JDBC(7)—DAO

  1. 介绍:
    DAO(Data Access Object):数据访问对象

    • 1.what:访问数据信息的类,包含了对数据的CRUD(create read、update、delete),而不包含业务相关的信息。
      2.why:实现功能模块化,更有利于代码的维护和升级。
    • 3.how:使用JDBC编写DAO可能会包含的方法。
    • public void update(String sql, Object … objects)
    • public T get(Class clazz, String sql, Object … objects)
    • public List getForList(Class calzz, String sql, Object … objects)
    • public E getForValue(String sql, Object … objects)

    • 版本:1.0,之后还会对DAO进行修改,这只是一个非常简单的介绍。

2.实例:

DAO层代码
public class DAO1_7 {

    /**
     * 1.更新操作,insert、update、delete操作都包含在其中。
     * @param sql
     * @param objects
     */
    public void update(String sql, Object ...objects){
        Connection conn = null;
        PreparedStatement preparedstatement = null;
        try {
            conn = TestTools.getConnection();
            preparedstatement = conn.prepareStatement(sql);
            for(int i = 0; i < objects.length; i++){
                preparedstatement.setObject(i + 1, objects[i]);
            }
            preparedstatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            TestTools.release(preparedstatement, conn);
        }
    }
    /**
     * 2.查询一条记录,返回对应的对象。
     * @param clazz
     * @param sql
     * @param objects:占位符从1开始
     * @return
     */
    public <T> T get(Class<T> clazz,String sql,Object ...objects){
        T entity = null;
        Connection conn = null;
        PreparedStatement preparedstatement = null;
        ResultSet rs = null;
        ResultSetMetaData rsmd = null;
        try {
            //1.获取Connection
            conn = TestTools.getConnection();
            //2.获取PreparedStatement
            preparedstatement = conn.prepareStatement(sql);
            //3.填充占位符
            for(int i = 0; i < objects.length; i++){
                preparedstatement.setObject(i + 1, objects[i]);
            }
            //4.进行查询,获取ResultSet对象
            rs = preparedstatement.executeQuery();
            //5.若ResultSet中有数据,准备一个Map<String,Object>:键:存放列的别名,值:存放列的值
            if(rs.next()){
                Map<String,Object> values = new HashMap<String,Object>();   
                //6.得到ResultSetMetaData对象。
                rsmd = rs.getMetaData();
                //7.处理ResultSet,把指针向下移动一个单位。(在判断是否有数据是已经移动,此处不在需要)

                //8.ResultSetMetaData对象中得到结果集中有多少列
                int columnCount = rsmd.getColumnCount();
                //9.由ResultSetMetaData得到每一列的值,再由ResultSet得到具体每一列的值
                for(int i = 0; i < columnCount; i++){
                    String columnLabel = rsmd.getColumnLabel(i + 1);
                    Object columnValue = rs.getObject(i + 1);
                    //10.填充Map对象
                    values.put(columnLabel, columnValue);
                }
                //11.使用反射创建Class对应的对象
                entity = clazz.newInstance();
                //12.遍历Map对象,使用反射遍历填充对象的属性值,Map:key为属性名,value为属性值
                for(Map.Entry<String, Object> entry : values.entrySet()){
                    String propertyName = entry.getKey();
                    Object value = entry.getValue();

                    TestTools.setFieldValue(entity, propertyName, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            TestTools.release(rs, preparedstatement, conn);
        }
        return entity;
    }
    /**
     * 3.查询多条记录,返回对应的对象的集合。
     * @param calzz
     * @param sql
     * @param objects
     * @return
     */
    public <T> List<T> getForList(Class<T> calzz,String sql,Object ... args){
        List<T> list = new ArrayList<>();//用于返回多个对象
        Connection conn = null;
        PreparedStatement preparedstatement = null;
        ResultSet rs = null;
        try {
            //1.获取Connection连接
            conn = TestTools.getConnection();
            //2.获取PreparedStatement对象
            preparedstatement = conn.prepareStatement(sql);
            //3.填充占位符
            for(int i = 0; i < args.length; i++){
                preparedstatement.setObject(i + 1, args[i]);
            }
            //4.进行查询,获取ResultSet对象
            rs = preparedstatement.executeQuery();
            //5.若ResultSet中有数据,准备一个List<Map<String,Object>>:
            //键:存放列的别名,值:存放列的值,其中一个Map对象对应一条记录,values用于存放
            List<Map<String, Object>> values = new ArrayList<>();
            Map<String, Object> map = null;
            //6.得到ResultSetMetaData对象。
            ResultSetMetaData rsmd = preparedstatement.getMetaData();
            //7.处理ResultSet,使用while()循环。(在判断是否有数据是已经移动,此处不在需要)
            while(rs.next()){
                map = new HashMap<>();
                //8.把每个列别名和列值取出来,存到Map对象中
                for(int i = 0; i < rsmd.getColumnCount(); i++){
                    String columnName = rsmd.getColumnLabel(i + 1);
                    Object columnValue = rs.getObject(i + 1);

                    map.put(columnName, columnValue);
                }
                //9.再把Map对象存到List中
                values.add(map);

            }
            //12.判断List是否为空集合,若不空则便利List得到一个个Map对象,
            //再把Map对象转化成Class参数对应的Object对象
            T bean = null;
            if(values.size() > 0){
                for(Map<String, Object> m : values){
                    bean = calzz.newInstance();
                    for(Map.Entry<String, Object> entry : m.entrySet()){
                        String propertyName = entry.getKey();
                        Object propertyValue = entry.getValue();
                        //为类成员变量赋值。
                        TestTools.setFieldValue(bean, propertyName, propertyValue);
                    }
                    //13.把Object对象放入到list中
                    list.add(bean);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            TestTools.release(rs, preparedstatement, conn);
        }

        return list;
    }
    /**
     * 4_1.功能:查询多条记录,返回对应的对象的集合。对以上3.方法进行的拆分。
     *与上一致,其中对ResultSet对象之后的代码进行优化,包括每次循环都都要获取列别名进行优化修改。
     * @param calzz
     * @param sql
     * @param objects
     * @return
     */
    public <T> List<T> getForLists(Class<T> calzz,String sql,Object ... args){
        List<T> list = new ArrayList<>();//用于接收返回的多个对象
        Connection conn = null;
        PreparedStatement preparedstatement = null;
        ResultSet rs = null;
        try {
            //1.得到结果集
            conn = TestTools.getConnection();
            preparedstatement = conn.prepareStatement(sql);
            for(int i = 0; i < args.length; i++){
                preparedstatement.setObject(i + 1, args[i]);
            }
            rs = preparedstatement.executeQuery();
            //-----------------修改
            //2.处理结果集,得到Map的List,其中一个Map对象就是一条记录,Map中Key表示列别名,Value表示列值
            List<Map<String, Object>> values = handleResultSetToMapList(rs);
            //3.把Map的list转为Clazz对应的list,其中Map的Key表示Class的成员属性,Value表示成员属性的值
            list = transfterMapListToBeanList(calzz, values);

        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            TestTools.release(rs, preparedstatement, conn);
        }
        return list;
    }

    /**
     * 4_2.处理结果集,获取Map的List,其中一条Map对象对应一条记录。
     * @param rs
     * @return
     * @throws SQLException
     */
    private List<Map<String, Object>> handleResultSetToMapList(ResultSet rs)
            throws SQLException {
        List<Map<String, Object>> values = new ArrayList<>();
        Map<String, Object> map = null;
        //---------------此处被修改。6.得到ResultSetMetaData对象。
        List<String> columnLabels = getColumnLabels(rs);
        while(rs.next()){
            map = new HashMap<>();
            //---------------此处被修改。8.把每个列别名和列值取出来,存到Map对象中
            for(String columnName : columnLabels){
                Object columnValue = rs.getObject(columnName);
                map.put(columnName, columnValue);
            }
            values.add(map);
        }
        return values;
    }
    /**
     * 4_3获取结果集所有的列别名,存到集合中,再返回集合。
     * @param rs
     * @return
     */
    private List<String> getColumnLabels(ResultSet rs){
        List<String> labels = new ArrayList<>();
        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            for(int i = 0; i < rsmd.getColumnCount(); i++){
                labels.add(rsmd.getColumnLabel(i + 1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return labels;
    }
    /**
     * 4_4.
     * @param calzz
     * @param values
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private <T> List<T> transfterMapListToBeanList(Class<T> calzz,
            List<Map<String, Object>> values) throws InstantiationException,
            IllegalAccessException {
        List<T> result = new ArrayList<>();
        T bean = null;
        if(values.size() > 0){
            for(Map<String, Object> m : values){
                bean = calzz.newInstance();
                for(Map.Entry<String, Object> entry : m.entrySet()){
                    String propertyName = entry.getKey();
                    Object propertyValue = entry.getValue();
                    //为类成员变量赋值。
                    TestTools.setFieldValue(bean, propertyName, propertyValue);
                }
                //13.把Object对象放入到list中
                result.add(bean);
            }
        }
        return result;
    }
    /**
     * 返回某条记录的某一个字段的值或一个统计的值(一共有多少条记录等。),即:确定的某一行的某个字段的值,或者计算的值
     * @param sql
     * @param objects
     * @return
     */
    public <E> E getForValue(String sql, Object ... objects){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.得到结果集:该结果集应该只有一行,且只有一列
            conn = TestTools.getConnection();
            ps = conn.prepareStatement(sql);
            for(int i = 0; i < objects.length; i++){
                ps.setObject(i + 1, objects[i]);
            }
            rs = ps.executeQuery();
            if(rs.next()){
                //2.取得结果
                return (E) rs.getObject(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            TestTools.release(rs, ps, conn);
        }
        return null;
    }
}
测试dao层代码
public class DAOTest_1_7 {

    DAO1_7 dao = new DAO1_7();
    //测试:DAO——update(String sql, Object ...objects)方法。
    @Test
    public void testUpdate() {
        String sql = "insert into customers(name,age,birth,address) " +
                "value(?,?,?,?)";
        dao.update(sql, "刘飒","20",new Date(new java.util.Date().getTime()),"河南省");
    }

    //测试:DAO——get(Class<T> clazz,String sql,Object ...objects)方法。
    @Test
    public void testGet() {
        String sql = "select * from customers where id = ?";
        Customers customers = dao.get(Customers.class, sql, 12);
        System.out.println(customers);
    }

    //测试:DAO——getForList(Class<T> calzz,String sql,Object ... args)方法。
    @Test
    public void testGetForList() {
        String sql = "select FlowID ,Type , IDCard , ExamCard " +
    ", StudentName , Location , Grade  from examStudent";
        List<Student> student = dao.getForLists(Student.class, sql);
        for(int i = 0; i < student.size(); i++){
            System.out.println(student.get(i));
        }
    }

    //测试:DAO——getForValue(String sql, Object ... objects)
    @Test
    public void testGetForValue(){
        String sql = "select examCard from examstudent where FlowID = ?";
        String examCard = dao.getForValue(sql, 33);
        if(examCard == null){
            System.out.println("查无信息!");
        }else{
            System.out.println(examCard);
        }
        sql = "select Count(*) from examstudent";
        Object count = dao.getForValue(sql);
        System.out.println("共有:"+count+"行");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值