JDBC11 - 封装BaseDao

高级应用层封装 BaseDao

基本每个数据表都应该有一个对应的 DAO 接口及其实现类,发现对所有表的操作(增、删、改、查)代码重复度很高,所以可以抽取公共代码,给这些 DAO 的实现类可以抽取一个公共的父类,称为 BaseDao

CRUD分为 DQL 和 非DQL,因此只需封装两个方法

封装 非DQL 返回值固定为int 比较简单

    /**
     * 封装简化非DQL语句 -- 返回值固定为int
     * @param sql    带占位符的SQL语句结构
     * @param params 占位符的值作为可变参数传入
     * @return
     */

    public int executeUpdate(String sql, Object... params) throws Exception {
        //获取连接
        Connection connection = JDBCUtilsV2.getConnection();

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //可变参可以作为数组使用
        for (int i = 1; i <= params.length; i++) {
            preparedStatement.setObject(i,params[i-1]);
        }

        int rows = preparedStatement.executeUpdate();

        preparedStatement.close();

        //是否回收连接要考虑是否为事务操作
        //如果开启事务了 不要管连接 --> 交给业务层处理
        //如果没有开启事务,正常回收连接
        if (connection.getAutoCommit()) {
            //true 没有开启
            JDBCUtilsV2.freeConnection();
        }

        return rows;
    }

封装 DQL

  • DQL语句封装方法 -> 返回值是什么类型的?
    • List list -> 实体类集合 -> 泛型
  • 并不是List map没有数据校验机制,且不支持反射操作
    • DQL -> List -> 一行 -> Map -> List
  • 数据库数据 -> java的实体类
    • table User
    • id id
    • account account
    • password password
    • nickname nickname
  • 表中一行 -> java类的一个对象 -> 多行 -> List<Java实体类>
    • 1.泛型 具体类型通过参数传入
    • 2.使用反射机制,实现属性赋值
  • public List executeQuery(Class clazz, String sql, Object...params);
/**
     * 将查询结果封装到一个实体集合
     * @param clazz  要接值的实体类集合的模板对象
     * @param sql    查询语句,要求列名或别名等于实体类的属性名   u_id as uId => uId
     * @param params 占位符的值,要和?位置对应传递
     * @return       查询的实体类集合
     * @param <T>    声明结果的类型
     * @throws Exception
     */
    public <T> List<T> executeQuery(Class<T> clazz, String sql, Object... params) throws Exception{

        Connection connection = JDBCUtilsV2.getConnection();

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        if (params != null && params.length != 0) {
            for (int i = 1; i < params.length; i++) {
                preparedStatement.setObject(i, params[i - 1]);
            }
        }

        ResultSet resultSet = preparedStatement.executeQuery();


        List<T> list = new ArrayList<>();

        //自动遍历列
        //获取列的信息对象
        //TODO metaData对象 装的当前结果集中列的信息对象(可以获取列的数量、列的名称)
        ResultSetMetaData metaData = resultSet.getMetaData();
        //知道列数后,就可以通过下标水平遍历列
        int columnCount = metaData.getColumnCount();

        while (resultSet.next()) {

            //一行数据 对应一个 T类型的对象
            //通过反射实例化对象 -- 调用类的无参构造函数实例化对象
            T t = clazz.newInstance();

            for (int i = 1; i <= columnCount; i++) {
                //对象的属性值
                Object value = resultSet.getObject(i);
                //对象的属性名
                String propertyName = metaData.getColumnLabel(i);

                //反射 给对象属性值赋值
                Field field = clazz.getDeclaredField(propertyName);
                field.setAccessible(true); //属性可以设置,打破private的修饰限制

                //参数1 要赋值的对象  参数2 具体的属性值
                field.set(t, value);

            }


            list.add(t);
        }

        //关闭资源
        resultSet.close();
        preparedStatement.close();

        if (connection.getAutoCommit()) {
            //true 没有开启事务,可以直接关闭
            JDBCUtilsV2.freeConnection();
        }

        return list;
    }

封装之后使用

public class PSCRUDPart extends BaseDao {

    @Test
    public void testInsert() throws Exception {

        String sql = "insert into t_user(account,password,nickname) values(?,?,?);";

        int rows = executeUpdate(sql, "test", "123123", "test");

        System.out.println("影响行数 = " + rows);

    }
    
    @Test
    public void testUpdate() throws Exception {

        String sql = "update t_user set nickname =? where id =?;";

        int rows = executeUpdate(sql, "new_name", "1");
        
        System.out.println("影响行数 = " + rows);

    }

    @Test
    public void testDelete() throws ClassNotFoundException, SQLException {


        String sql = "delete from t_user where id = ?;";

        int rows = executeUpdate(sql, "2");
        
        System.out.println("影响行数 = " + rows);
    }
}
posted @   LaViez  阅读(69)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示