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

    依旧是项目内的需求: 基于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类 进行了修正,以便后面的逻辑更加方便使用。
     
  • 相关阅读:
    3(翻译)如何在cocos2d里面使用动画和spritesheet
    Objectivec2.0 每种数据类型定义属性的方法
    cocos2d 入门必备4个基本概念
    如何在Mac上搭建自己的服务器——Nginx
    JN_0001:在微信朋友圈分享时长大于10s的视频
    JN_0002:Win10禁止U盘拷贝文件的方法
    abstract class 和 interface区别
    ref和out
    .Net配置错误页
    Unity3d 物体沿着正七边形轨迹移动
  • 原文地址:https://www.cnblogs.com/justtodo/p/11990759.html
Copyright © 2011-2022 走看看