• 【JDBCUtils ---DbUtils工具】


    Java + MySQL 学习

    QueryRunner增强–JdbcUtils事务处理–多线程并发安全


    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


    一、QueryRunner使用

    QueryRunner是DbUtils包下的一个增强JDBC,简化了JDBC中的数据操作,以及数据与对象之间的转化。

    涉及到事务时创建QueryRunner对象时,不需要传入参数,但需要在方法里传入和其他层同一个Connection对象。

    不涉及到事务时,创建QueryRunner对象,需要提供一个DateSource对象,QueryRunner内部从连接池获得连接

    常用的几种方法:

    1. query(Connection conn, String sql, Object[] params, ResultSetHandler rsh):执行选择查询,在查询中,对象阵列的值被用来作为查询的置换参数。

    2. query(String sql, Object[] params, ResultSetHandler rsh):方法本身不提供数据库连接,执行选择查询,在查询中,对象阵列的值被用来作为查询的置换参数。

    3. query(Connection conn, String sql, ResultSetHandler rsh):执行无需参数的选择查询。

    4. update(Connection conn, String sql, Object[] params):被用来执行插入、更新或删除(DML)操作。


    update()方法:

    1.int update(String sql,Object…params)–>可执行增、删、改语句

    2.int update(Connection conn,String sql,Object…params)–>同样支持增、删、改操作,但是方法不管理Connection了,支持事务。

    @Test
     public  void insert(){
         try {
         
            QueryRunner qr=new QueryRunner(C3p0Utils.getDateSource());
            String sql="update bank set blance=blance+? where name=?";
            Object[] o={200,"李四"};
            qr.update(sql, o);
          
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
     }
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    query()方法:

    1.T query(String sql,ResultSetHandler rsh,Object…params)–>可执行查询

    2.T query(Connection conn,String sql,ResultSetHandler rsh,Object…params)–>可执行查询,支持事务

    update方法和query方法参数里面有一处不同,里面增加了一个ResultSetHandler接口,作用是为了把从数据库中查询出来的数据转化成对象

    ResultSetHandler接口

    其中ResultSetHandler接口(org.apache.commons.dbutils.ResultSethandler)执行处理一个结果集对象,将数据转变并处理为任何一种形式,供其他应用使用。实现类如下:

    ArrayHandler:把结果集中的第一行数据转成对象数组。

    ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。

    BeanHandler: 将结果集中的第一行数据封装到一个对应的JavaBean实例中。

    BeanListHandler: 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。

    MapHandler: 将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。

    MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List

    ColumnListHandler:将结果集中某一列的数据存放到List中。

    KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List),再把这些map再存到一个map里,其key为指定的列。

    ScalarHandler: 将结果集第一行的某一列放到某个对象中。


    @Test
     public  void query(){
         try {
            QueryRunner qr=new QueryRunner(C3p0Utils.getDateSource());
            String sql="select * from bank";
            Bank b=qr.query(sql, new BeanHandler(Bank.class));
            System.out.println(b);
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    二、JdbcUtils自写工具类增加事务处理。

    在项目框架搭建过程中,涉及到三个层面,数据层、业务层、网络层,这是在MVC模式基础上进一步的业务分离。Dao层是对数据库进行操作的,这里不涉及到任何的业务处理,所以事务不该出现在这里,Service层是进行业务处理的,事务应该在这里出现,事务的开始和结束都得依靠Connection对象,所以需要Connection对象,但是Connection只应该出现在Dao层中,不应该在Service中出现,所以要进行封装,在这里为了线程安全,使用ThreadLocal对象,并且业务逻辑进行判断,使通过一个事务中只使用同一个Connection对象。

    import java.sql.Connection;
    import java.sql.SQLException;
    
    import javax.sql.DataSource;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    /**
     * @author WangXinwei
     *从C3P0连接池获取连接
     *getDateSource返回连接池对象
     */
    public class C3p0Utils {
     private static ComboPooledDataSource dataSource=new ComboPooledDataSource();
     //为了并发安全,使用ThreadLocal对象
     private static ThreadLocal<Connection>  tl=new ThreadLocal<Connection>();
     /**
      * 
      * @return
      * @throws SQLException
      * 返回连接,首先判断线程是否含有连接,如果没有,则新建连接
      */
     public static Connection getConnection() throws SQLException{
         Connection con=tl.get();
         if(con!=null) return con;
         return dataSource.getConnection();
     }
     /**
      * 开启事务
     * @throws SQLException 
      */
     public static void beginTransaction() throws SQLException{
         Connection con=tl.get();
         if(con!=null) throw new RuntimeException("已经开启了事务");
         con=getConnection();
         con.setAutoCommit(false);
         tl.set(con);
     }
     /**
     * @throws SQLException 
      *提交事务
      */
    public static void commitTransaction() throws SQLException{
        Connection con=tl.get();
         if(con==null) throw new RuntimeException("没有事务");
         con.commit();
         con.close();
         tl.remove();
     }
    /**
     * @throws SQLException 
     * 回滚事务
     */
    public static void rollbackTransaction() throws SQLException{
        Connection con=tl.get();
         if(con==null) throw new RuntimeException("没有事务");
         con.rollback();
         con.close();
         tl.remove();
    }
    /**
     * 
     * @param connection
     * @throws SQLException
     * 判断是否能够关闭连接,如果不属于事务那么就关闭。
     */
     public static void releaseConnection(Connection connection) throws SQLException{
         Connection con=tl.get();
         if(con==null) connection.close();
         if(con!=connection) connection.close();
     }
     /**
      * 
      * @return
      * 返回连接池对象
      */
     public static DataSource getDateSource(){
       return dataSource;
     
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    三、QueryRunner增强

      @Test
     public  void queryBank(){
         try {
            QueryRunner qr=new QueryRunner();
            String sql="select * from bank";
            Connection con=C3p0Utils.getConnection();
            Bank b=qr.query(con,sql, new BeanHandler(Bank.class));
            C3p0Utils.releaseConnection(con);
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    自己提供连接与判断是否可以关闭连接,导致代码臃肿,可以把这下方法哦QueryRunner中实现,写一个QueryRunner的继承类

    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.List;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.ResultSetHandler;
    
    public class BasicQueryRunner extends QueryRunner {
    
        @Override
        public int[] batch(String sql, Object[][] params) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            int[] result=super.batch(con,sql, params);
            C3p0Utils.releaseConnection(con);
            return result;
        }
    
        @Override
        public int execute(String sql, Object... params) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            int result=super.execute(con,sql, params);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public <T> List<T> execute(String sql, ResultSetHandler<T> rsh,
                Object... params) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            List<T> result=super.execute(con,sql, rsh, params);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public <T> T insert(String sql, ResultSetHandler<T> rsh, Object... params)
                throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            T result=super.insert(con,sql, rsh, params);
            C3p0Utils.releaseConnection(con);
            return result;
    
        }
    
        @Override
        public <T> T insert(String sql, ResultSetHandler<T> rsh)
                throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            T result=super.insert(con,sql, rsh);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public <T> T insertBatch(String sql, ResultSetHandler<T> rsh,
                Object[][] params) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            T result=super.insertBatch(con,sql, rsh, params);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
                throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            T result=super.query(con,sql, rsh, params);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            T result= super.query(con,sql, rsh);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public int update(String sql, Object... params) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            int result= super.update(con,sql, params);
            C3p0Utils.releaseConnection(con);
            return result;
        
        }
    
        @Override
        public int update(String sql, Object param) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            int result= super.update(con,sql, param);
            C3p0Utils.releaseConnection(con);
            return result;
            
        }
    
        @Override
        public int update(String sql) throws SQLException {
            // TODO Auto-generated method stub
            Connection con=C3p0Utils.getConnection();
            int result=super.update(con,sql);
            C3p0Utils.releaseConnection(con);
            return result;  
      
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    总结

    提示:这里对文章进行总结:

    例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 相关阅读:
    第十一章《Java实战常用类》第5节:UUID类
    Shell(2)数值运算与判断
    CTF取证技术实战,图片、文件、流等相关内容的取证技术
    接口测试 —— requests 的基本了解
    【自用】C++ 知识点总结Ⅱ:异常、IO流、类型转化、C++11新特新、STL、设计模式...(待更新)
    华为云云耀云服务器L实例评测|netdata的部署与应用
    【技术分享】SLA(服务等级协议)原理与配置
    DM8:生成DM AWR报告
    数据库可视化工具分享 (DBeaver)
    如何使用Java创建数据透视表并导出为PDF
  • 原文地址:https://blog.csdn.net/sakura22123/article/details/126596343