zoukankan      html  css  js  c++  java
  • 通过对DAO层的封装减少数据库操作的代码量

       在学框架之前,写项目时总是要花大量的时间去写数据库操作层代码,这样会大大降低我们的效率,为了解决这个问题,我花了两天时间利用反射机制和泛型将DAO层进行了封装,这样我们只需要写sql语句,不需要再写繁琐的数据库操作语句,增强代码的复用性,让我们把主要精力放在业务逻辑上。

      以下就是我写的代码(我是用连接池操作,普通的jdbc操作和连接池道理相同,主要思想是将结果集设置到对象的属性中)

     1     /**
     2      * 预处理通用查询对象集合
     3      *
     4      * @param cla 操作类型
     5      * @param params 预处理参数
     6      * @param sql 要执行的sql语句
     7      * @return 返回的对象集合
     8      * @throws SQLException 抛出异常
     9      */
    10     @SuppressWarnings("deprecation")
    11     public static <T> List<T> commonPreparedQueryList(final Class<T> cla,Object params[],String sql) throws SQLException{
    12                //获得连接池(这里使用的是阿里巴巴开源的jar包)
    13         QueryRunner qr = new QueryRunner(DBUtil.getDruid());
    14         /*
    15          * 声明一个List存放返回对象
    16          */    
    17                 List<T> tList = new ArrayList<T>(); 
    18                 /*
    19                  * 执行查询操作并返回对应集合,传入sql和预处理参数并进行结果集处理(这里要实现handle方法)
    20                  */
    21                 tList = qr.query(sql, params,new ResultSetHandler<List<T>>(){
    22 
    23                 public List<T> handle(ResultSet rs) throws SQLException {
    24                     /*
    25                      * 这里要用到ResultSetMetaData来获取数据库表的字段名和数量
    26                      */
    27                     ResultSetMetaData ms = rs.getMetaData();
    2              T t = null;//声明一个泛型,此处类型和传入一致
    29                     List<T> list = new ArrayList<T>();
    30                     /*
    31                      * 通过循环获得表中所有的字段名,并通过反射的方式把字段名内容
    32                      * 设置到我们要查询的集合中,并将结果返回
    33                      * 注意:这里需要用到循环的嵌套,我们需要先循环表中所有数据,
    34                      * 然后再循环表的所有字段名
    35                      */
    36                     while(rs.next()){
    37                         try {
    38                             t = cla.newInstance();//创建一个实例化对象
    39                             //获得所有字段名,并将其转换为驼峰式命名规则  eg:guest_id转化为guestId
    40                             for(int i = 0; i <ms.getColumnCount(); i++){
    41                                 String columnName = ms.getColumnName(i+1);//获得字段名
    42                                 /*
    43                                  * 以下操作是将下划线形式转化为驼峰式的实现
    44                                  * 现将字段名以下划线分割到字符串数组中,将第一个数组元素复制到StringBuffer中
    45                                  * 然后将后面的数组元素第一个首字母转化为大写形式,最后将他们拼接到一起,将所得结果转化为字符串
    46                                  */
    47                                 String[] strName = columnName.split("_");
    48                                 StringBuffer sb = new StringBuffer(strName[0]);
    49                                 for(int i1 = 1;i1<strName.length;i1++){
    50                                     strName[i1] = strName[i1].substring(0, 1).toUpperCase().concat(strName[i1].substring(1));
    51                                     sb.append(strName[i1]);
    52                                 }
    53                                 String property = sb.toString();
    54                                 /*
    55                                  * 获得对象的所有属性,并将结果集中的内容通过反射赋值到对象的属性中
    56                                  */
    57                                 Field field = cla.getDeclaredField(property);
    58                                 field.setAccessible(true);
    59                                 field.set(t, rs.getObject(columnName));
    60                             }
    61                         } catch (InstantiationException e) {
    62                             e.printStackTrace();
    63                         } catch (IllegalAccessException e) {
    64                             e.printStackTrace();
    65                         } catch (NoSuchFieldException e) {
    66                             e.printStackTrace();
    67                         } catch (SecurityException e) {
    68                             e.printStackTrace();
    69                         }
    70                         //将对象添加到List中
    71                         list.add(t);
    72                     }
    73                     //循环结束后返回对象集合
    74                     return list;
    75                 }
    76                 
    77             });
    78         return tList;
    79     }

    测试代码:

    1 public void Test() throws SQLException{
    2         List<Book> bookList = new LinkedList<Book>();
    3         Object params[] = new Object[]{"%三%"};
    4         String sql = "select * from book where book_name like ? ";
    5         bookList = CommonDao.commonPreparedQueryList(Book.class,params ,sql);
    6         System.out.println(bookList);
    7     }

    一共两条数据

    查询一条数据(这个和查询集合的区别只有集合需要循环结果集,而这个只需要用if语句判断一下即可,其余代码完全相同):

     1 /**
     2      * 通用预处理查询对象
     3      *
     4      * @param cla
     5      * @param params
     6      * @param sql
     7      * @return 对象
     8      * @throws SQLException
     9      * @throws InstantiationException
    10      * @throws IllegalAccessException
    11      */
    12     @SuppressWarnings("deprecation")
    13     public static <T> T commonPreparedQuery(final Class<T> cla,Object params[],String sql) throws SQLException, InstantiationException, IllegalAccessException{
    14         QueryRunner qr = new QueryRunner(DBUtil.getDruid());
    15             T m = cla.newInstance();
    16             m = qr.query(sql,params ,new ResultSetHandler<T>(){
    17 
    18             public T handle(ResultSet rs) throws SQLException {
    19                 ResultSetMetaData rm = rs.getMetaData();
    20                 T t = null;
    21                 try {
    22                     if(rs.next()){             //这里用if,是与查询集合代码的唯一区别
    23                         t = cla.newInstance();
    24                         for(int i = 0; i<rm.getColumnCount(); i++){
    25                             String columnName = rm.getColumnName(i+1);
    26                             String str[] = columnName.split("_");
    27                             StringBuffer sb = new StringBuffer(str[0]);
    28                             for(int j = 1; j<str.length; j++){
    29                                 str[j] = str[j].substring(0, 1).toUpperCase().concat(str[j].substring(1));
    30                                 sb.append(str[j]);
    31                             }
    32                             String property = sb.toString();
    33                             Field field = cla.getDeclaredField(property);
    34                             field.setAccessible(true);
    35                             field.set(t, rs.getObject(columnName));
    36                         }
    37                     }else{
    38                         System.out.println("sql语句错误或对象不存在");
    39                     }
    40                 } catch (InstantiationException e) {
    41                     e.printStackTrace();
    42                 } catch (IllegalAccessException e) {
    43                     e.printStackTrace();
    44                 } catch (SecurityException e) {
    45                     e.printStackTrace();
    46                 } catch (NoSuchFieldException e) {
    47                     e.printStackTrace();
    48                 }
    49                 return t;
    50             }
    51             
    52         });
    53     return m;
    54 }

    测试:

        public void Test() throws SQLException, InstantiationException, IllegalAccessException{
            Book book = new Book();
            Object params[] = new Object[]{10001};
            String sql = "select * from book where book_id = ? ";
            book = CommonDao.commonPreparedQuery(Book.class, params, sql);
            System.out.println(book);
        }

    还有普通查询操作(不通过预处理)

    这种方式和预处理查询的唯一区别只是不需要传递参数params,其余和上面代码完全一致

     1 /**
     2      * 通用类查询集合
     3      *
     4      * @param cla
     5      * @param sql
     6      * @return 
     7      * @throws SQLException
     8      */
     9     public static <T> List<T> commonQueryList(final Class<T> cla,String sql) throws SQLException{
    10         QueryRunner qr = new QueryRunner(DBUtil.getDruid());
    11                 List<T> tList = new ArrayList<T>(); 
    12                 tList = qr.query(sql, new ResultSetHandler<List<T>>(){
    13 
    14                 public List<T> handle(ResultSet rs) throws SQLException {
    15                     ResultSetMetaData ms = rs.getMetaData();
    16                     T t = null;
    17                     List<T> list = new ArrayList<T>();
    18                     while(rs.next()){
    19                         try {
    20                             t = cla.newInstance();
    21                             for(int i = 0; i <ms.getColumnCount(); i++){
    22                                 String columnName = ms.getColumnName(i+1);
    23                                 String[] strName = columnName.split("_");
    24                                 StringBuffer sb = new StringBuffer(strName[0]);
    25                                 for(int i1 = 1;i1<strName.length;i1++){
    26                                     strName[i1] = strName[i1].substring(0, 1).toUpperCase().concat(strName[i1].substring(1));
    27                                     sb.append(strName[i1]);
    28                                 } 
    29                                 String property = sb.toString();
    30                                 Field field = cla.getDeclaredField(property);
    31                                 field.setAccessible(true);
    32                                 field.set(t, rs.getObject(columnName));
    33                             }
    34                         } catch (InstantiationException e) {
    35                             e.printStackTrace();
    36                         } catch (IllegalAccessException e) {
    37                             e.printStackTrace();
    38                         } catch (NoSuchFieldException e) {
    39                             e.printStackTrace();
    40                         } catch (SecurityException e) {
    41                             e.printStackTrace();
    42                         }
    43                         list.add(t);
    44                     }
    45                     return list;
    46                 }
    47                 
    48             });
    49         return tList;
    50     }

    测试:

    public void Test() throws SQLException{
            List<Book> bookList = new LinkedList<Book>();
            String sql = "select * from book ";
            bookList = CommonDao.commonQueryList(Book.class,sql);
            System.out.println(bookList);
        }

    同样有两条数据

    查询一个对象:

     1 /**
     2      * 查询一个数据库类操作
     3      *
     4      * @param cla
     5      * @param sql
     6      * @return 一个数据库类对象
     7      * @throws SQLException
     8      * @throws InstantiationException
     9      * @throws IllegalAccessException
    10      */
    11     public static <T> T commonQuery(final Class<T> cla,String sql) throws SQLException, InstantiationException, IllegalAccessException{
    12             QueryRunner qr = new QueryRunner(DBUtil.getDruid());
    13                 T m = cla.newInstance();
    14                 m = qr.query(sql, new ResultSetHandler<T>(){
    15 
    16                 public T handle(ResultSet rs) throws SQLException {
    17                     ResultSetMetaData rm = rs.getMetaData();
    18                     T t = null;
    19                     try {
    20                         if(rs.next()){
    21                             t = cla.newInstance();
    22                             for(int i = 0; i<rm.getColumnCount(); i++){
    23                                 String columnName = rm.getColumnName(i+1);
    24                                 String str[] = columnName.split("_");
    25                                 StringBuffer sb = new StringBuffer(str[0]);
    26                                 for(int j = 1; j<str.length; j++){
    27                                     str[j] = str[j].substring(0, 1).toUpperCase().concat(str[j].substring(1));
    28                                     sb.append(str[j]);
    29                                 }
    30                                 String property = sb.toString();
    31                                 Field field = cla.getDeclaredField(property);
    32                                 field.setAccessible(true);
    33                                 field.set(t, rs.getObject(columnName));
    34                             }
    35                         }else{
    36                             System.out.println("sql语句错误或对象不存在");
    37                         }
    38                     } catch (InstantiationException e) {
    39                         e.printStackTrace();
    40                     } catch (IllegalAccessException e) {
    41                         e.printStackTrace();
    42                     } catch (SecurityException e) {
    43                         e.printStackTrace();
    44                     } catch (NoSuchFieldException e) {
    45                         e.printStackTrace();
    46                     }
    47                     return t;
    48                 }
    49                 
    50             });
    51         return m;
    52     }

    测试:

    @Test
        public void Test() throws SQLException, InstantiationException, IllegalAccessException{
            Book book = new Book();
            String sql = "select * from book where book_id = 10002";
            book = CommonDao.commonQuery(Book.class,sql);
            System.out.println(book);
        }

    接下来是增删改操作,这个操作比较简单,不需要用到泛型和反射,只需要传入sql语句即可:

    1 public static boolean updateSql(String sql) throws SQLException{
    2         boolean flag = false;
    3         QueryRunner qr = new QueryRunner(DBUtil.getDruid());
    //执行修改操作
    4 if(qr.update(sql)>0) 5 flag = true; 6 return flag; 7 }

    还有预处理形式

    1 public static boolean updatePreparedSql(String sql,Object params[]) throws SQLException{
    2         boolean flag = false;
    3         QueryRunner qr = new QueryRunner(DBUtil.getDruid());
    4         if(qr.update(sql,params)>0)
    5             flag = true;
    6         return flag;
    7     }

    还有批量处理形式

    /**
         * 通过预处理解决批量增删改操作
         *
         * @param sql
         * @param params params[rows][cols],rows代表sql语句执行次数,cols表示替换占位符的参数个数
         * @return boolean
         * @throws SQLException
         */
        public static boolean batchProcessing(String sql,Object params[][]) throws SQLException{
            boolean flag = false;
            QueryRunner qr = new QueryRunner(DBUtil.getDruid());
            if(qr.batch(sql, params).length == params.length)
                flag = true;
            return flag;
        }
  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/Shevo/p/7785537.html
Copyright © 2011-2022 走看看