• 项目实战,通过类对象,反射类属性等信息。通过数据库连接信息,获取所有的对象以及结果


    依旧是项目内的需求: 基于mysql进行的操作,因为要作为通用产品模型,对接不同地市,就是没有确定的mapper可用。所以采用jdbc去封装。

    场景一:

    条件:已经根据IDEA的database插件,利用POJO生成对应的实体类。

    需求:获取所有表内容 (select * ),list输出。

      

    public static final String ENTRY_PATH = "com.ucap.exchange.dataexchange.entity";
        public static List<ComplexResults> getData(Connection conn) {
    
        //获取实体类包路径 String packageName
    = ENTRY_PATH;
        // Set
    <String> classNames = getClassName(packageName, false); List<ComplexResults> resultList = new ArrayList(); for (String className : classNames) { String tableName = className.substring(className.lastIndexOf(".") + 1); String sql = "select * from " + tableName ; try { Class tableNameClass = Class.forName(className); List fserd = queryToObj(tableNameClass, conn, sql); for (Object obj : fserd) { ComplexResults complexResults = new ComplexResults(null, tableName, System.currentTimeMillis(), ExchangeConstants.INSERT, obj, null); resultList.add(complexResults); } } catch (Exception e) { e.printStackTrace(); } } return resultList; }
    /**
    * @param <T> 封装对象的泛型
    * @param clazz 实体类对象
    * @param sql sql语句
    * @return list
    */
    public static <T> List<T> queryToObj(Class<T> clazz, Connection conn, String sql) {
    try {
    // 1. 获取结果集
    PreparedStatement ps = conn.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();

    // 2. 将查询的结果和字段名称获取 获取所有的字段
    ResultSetMetaData metaData = rs.getMetaData();

    // 用来保存对象的
    ArrayList<T> cols = new ArrayList<>();
    while (rs.next()) {
    // 创建对象
    T obj = clazz.newInstance();
    for (int i = 1; i <= metaData.getColumnCount(); i++) {
    // 通过反射获取对应的字段
    Field filed = clazz.getDeclaredField(metaData.getColumnLabel(i).toLowerCase());
    filed.setAccessible(true);
    Object value = rs.getObject(metaData.getColumnLabel(i));
    filed.set(obj, value);
    }
    cols.add(obj);
    }
    return cols;
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }
    
    
    /**
    * 获取某包下所有类
    *
    * @param packageName 包名
    * @param isRecursion 是否遍历子包
    * @return 类的完整名称
    */
    public static Set<String> getClassName(String packageName, boolean isRecursion) {
    Set<String> classNames = null;
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    String packagePath = packageName.replace(".", "/");

    URL url = loader.getResource(packagePath);
    if (url != null) {
    String protocol = url.getProtocol();
    if (protocol.equals("file")) {
    classNames = getClassNameFromDir(url.getPath(), packageName, isRecursion);
    } else if (protocol.equals("jar")) {
    JarFile jarFile = null;
    try {
    jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
    } catch (Exception e) {
    e.printStackTrace();
    }

    if (jarFile != null) {
    getClassNameFromJar(jarFile.entries(), packageName, isRecursion);
    }
    }
    } else {
    /*从所有的jar包中查找包名*/
    classNames = getClassNameFromJars(((URLClassLoader) loader).getURLs(), packageName, isRecursion);
    }

    return classNames;
    }
     
    ComplexResults 是我封装的一个结果集对象,显式写一个构造方法,new对象时,生成实例用的。
    queryToObj 方法,根据sql查询结果集获取结果 getMetaData(),再通过反射获取对应的字段 key,利用sql结果集 Set.getObject(key),获取值,把结果进行封装返回。
    getClassName 方法,根据包路径获取包下对应实体对象放入set集合。

    场景二:优化版。(去掉了实体类的绑定)

    条件:已有数据库连接,动态扫描表结构。无实体类。

    需求:获取所有表内容 (select * ),list输出。

      public static final String EXCLUDE_TABLE = "sys_datachange_log";
      public static List<ComplexResults> getData(Connection conn) throws SQLException {
    
            DatabaseMetaData dbmd = conn.getMetaData();
    //        获取所有表
          
          //获取数据库实例 String catalog = conn.getCatalog(); List<String> stringList = new ArrayList<>();
          //获取所有的表对象 ResultSet tableRet
    = dbmd.getTables(catalog, null, null, new String[]{"TABLE"}); while (tableRet.next()) { stringList.add(tableRet.getString("TABLE_NAME")); } List<ComplexResults> resultList = new ArrayList(); for (String m_TableName : stringList) { if (!EXCLUDE_TABLE.equals(m_TableName)) { String columnName; String columnType_Sql; String columnType_Java;
              //获取表内的列,属性等信息 ResultSet colRet
    = dbmd.getColumns(catalog, "%", m_TableName, "%"); Map sqlResultsMap = new HashMap(); while (colRet.next()) { columnName = colRet.getString("COLUMN_NAME"); columnType_Sql = colRet.getString("TYPE_NAME"); sqlResultsMap.put(columnName,columnType_Sql); } String sql = "select * from " + m_TableName; List<Entity> entityList = SqlExecutor.query(conn, sql, new EntityListHandler()); for (Entity entity : entityList) { ComplexResults complexResults = new ComplexResults(null, m_TableName, System.currentTimeMillis(), ExchangeConstants.INSERT, entity, sqlResultsMap); resultList.add(complexResults); } } } return resultList; }
    EXCLUDE_TABLE 此表是一个日志表,不需要获取内容。
    合理的利用了java.sql包下的 一些方法。
    再写第二个实现的时候,我对结果集对象 ComplexResults类 进行了修正,以便后面的逻辑更加方便使用。
     
  • 相关阅读:
    设置数据库某字段为当前时间
    HashMap源码解析(只为吊打面试官)
    SRAM 静态内存芯片 IS62WV51216 的使用 STM32F407ZGT6
    手机ARM种类,STM32中的ARM核又是什么东东?
    运算放大器 常用经典电路 计算书
    SMT 生产线设备 (PCBA)
    横机 电控设计
    ISO26262 标准
    质量管理体系(16949)的五大工具
    IATF16949和TS16949有什么不同?
  • 原文地址:https://www.cnblogs.com/justtodo/p/11990759.html
Copyright © 2020-2023  润新知