美文网首页
反射实现 daoImpl

反射实现 daoImpl

作者: flyHunter雄 | 来源:发表于2017-04-21 12:52 被阅读0次

    代码实现:

    /**
    * 根据主键查询数据。
    * 要求实体类型的属性名称和数据库表的字段名称完全一致。
    * 要求实体类型的类名于数据库的表名有直接关系
    * 表名 : tb_类名
    * @param clazz : 要查询的数据的java类型。 直接可以代表数据          库中的表名和字段名。
    * @param id : 要查询的数据的主键。 主键数据为id字段。
    */
      @Override
      public Object getObjectById(Class clazz, Serializable id) {
    // 要执行的查询语句
    String sql = "";
    Connection conn = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    // 查询结果
    Object result = null;
    try{
        Class.forName("oracle.jdbc.driver.OracleDriver");
        conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "test", "test");
        
        conn.setAutoCommit(false);
        
        sql = createGetObjectByIdSQL(clazz);
        System.out.println("sql : " + sql);
        pstm = conn.prepareStatement(sql);
        pstm.setObject(1, id);
        rs = pstm.executeQuery();
        // 处理结果集。
        if(rs.next()){
        // 缺少字段和对象属性的映射
            // Object columnValue = rs.getObject("字段名");
            Method[] methods = clazz.getMethods();
            // 检索方法中的set方法。 将查询的字段值,注入到对象中。
            result = clazz.newInstance();
            for(Method method : methods){
            String methodName = method.getName();
            if(methodName.startsWith("set") && methodName.length() > 3){
                // 获取字段名称
                String columnName = methodName.substring(3);
                // 获取方法的参数表, 判断参数类型。 决定调用什么方法获取字段数据。
                // 如: 参数类型是Integer, 调用getInt方法。
                Object columnValue = null;
                Class[] parameterTypes = method.getParameterTypes();
                if(parameterTypes.length == 1){
                Class type = parameterTypes[0];
                if(type == Integer.class){
                    columnValue = rs.getInt(columnName);
                }else if(type == String.class){
                    columnValue = rs.getString(columnName);
                }else if(type == Double.class){
                    columnValue = rs.getDouble(columnName);
                }else if(type == int.class){
                    columnValue = rs.getInt(columnName);
                }
            }
            // 根据字段名称获取字段数据
            // 将查询结果保存在对象result的属性中。
            method.invoke(result, columnValue);
            }
            }
        }
        conn.commit();
    }catch(Exception e){
        e.printStackTrace();
                      如果出现异常回滚
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
    }finally{
            //关闭资源
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
            // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(pstm != null){
            try {
                pstm.close();
            } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    return result;
    }
    

    反射拼接 sql 字符串

    private String createGetObjectByIdSQL(Class clazz){
      // 缺少SQL语法
      StringBuilder builder = new StringBuilder("select ");
      // 拼接字段名, 字段名就是类型的属性名
      // 获取所有方法。 循环方法的数组。 查询已get/set命名的方法。
      Method[] methods = clazz.getMethods();
      String[] columnNames = new String[methods.length];
      for(int i = 0; i < methods.length; i++){
        String methodName = methods[i].getName();
        
        if(methodName.startsWith("get") && methodName.length() > 3 && !methodName.equals("getClass")){
                // 当前方法是需要分析的方法。 将方法名称前缀get去除,其余部分为字段名
                String columnName = methodName.substring(3);
                columnNames[i] = columnName;
                builder.append(columnName);
                builder.append(",");
          }
        }
      // 上述的SQL语法末尾多一个逗号
    builder.deleteCharAt(builder.length() - 1);
      // 拼接表名, 表名是tb_类名
      String className = clazz.getName();
      // 截取类的名称。 className : package.name.ClassName
      className = className.substring(className.lastIndexOf(".")+1);
      builder.append(" from tb_"+className);
      // 拼接条件。 条件是主键查询
      builder.append(" where id = ? ");
      return builder.toString();
      }

    相关文章

      网友评论

          本文标题:反射实现 daoImpl

          本文链接:https://www.haomeiwen.com/subject/hardzttx.html