一、利用反射及JDBC元数据编写通用的查询方法

1.ResultSetMetaData

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

定义:描述ResultSet的元数据对象,即从中可以获取到结果集中有多少列、列名是什么。

获取 ResultSetMetaData 对象:

  调用 ResultSet 的 getMetaData() 方法

方法:

  int getColumnCount():SQL语句中包含的列数

  String getColumnLabel(int column):获取指定的列的别名,其中索引从1开始

2.通用的查询方法

    /**
     * 通用的查询方法:可以根据传入的SQL、Class对象返回SQL对应的对象
     * 
     * @param clazz:
     *            描述对象的类型
     * @param sql:
     *            SQL语句,可能带占位符
     * @param args:
     *            填充占位符的可变参数
     */
    public <T> T get(Class<T> clazz, String sql, Object... args) {
        T entity = null;

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            // 1.获得ResultSet对象
            conn = getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            rs = ps.executeQuery();

            // 2.得到ResultSetMetaData对象
            ResultSetMetaData rsmd = rs.getMetaData();

            // 3.创建一个Map<String, Object>对象,键:SQL查询的列的别名;值:列的值
            Map<String, Object> values = new HashMap<>();

            // 4.处理结果集,利用ResultSetMetaData填充3对应的Map对象
            if (rs.next()) {
                for (int i = 0; i < rsmd.getColumnCount(); i++) {
                    String columnLabel = rsmd.getColumnLabel(i + 1);
                    Object columnValue = rs.getObject(i + 1);

                    values.put(columnLabel, columnValue);
                }
            }

            // 5.若Map不为空集,利用反射创建 clazz 对应的对象
            if (values.size() > 0) {
                entity = clazz.newInstance();

                // 6.遍历Map对象,利用反射为Class对象的对应的属性赋值。
                for (Map.Entry<String, Object> entry : values.entrySet()) {
                    String fieldName = entry.getKey();
                    Object value = entry.getValue();
                    setFieldValue(entity, fieldName, value);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return entity;
    }
    /**
     * 利用反射给具体对象的属性赋值
     */
    public void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Class<? extends Object> clazz = obj.getClass();
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

使用该通用方法:

    /**
     * 使用通用的查询方法
     */
    public void testGet(){
        String sql = "select id, name, email, birth " 
                + "from customers where id = ?";
        Customer customer = get(Customer.class, sql, 5);
        System.out.println(customer);
    }

 二、DAO设计模式

1.定义:

  DAO即 Data Access Object ,访问数据信息的类,包含了对数据的CRUD(create, read, update, delete),而不包含任何业务相关的信息。

2.作用:

  实现功能的模块化,更有利于代码的保护和升级。

3.方法:

void update(String sql, Object ... args); //INSERT,UPDATE,DELETE操作都可以包含在其中

<T> T get(Class<T> calzz, String sql, Object ... args); //查询一条记录,返回对应的对象

<T> List<T> getForList(Class<T> clazz, String sql, Object ... args); //查询多条记录,返回对应的对象的集合

<E> E getForValue(String sql, Object ... args); //返回某条记录的某一个字段的值或者一个统计的值(一共有多少条记录等)

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄