zoukankan      html  css  js  c++  java
  • Commons dbutils、pool、dbcp以及JDBC事务

    1.dbutils包:

    提供执行sql语句的功能,简化过程

    (1)执行添加、删除语句

        public static void add() throws SQLException {
            QueryRunner qr = new QueryRunner();//实例化
            Connection conn = DButil.getConn();//获取数据库连接
            String sql = "insert into userscount(uname,upwd) values(?,?)";
            Object[] obj = {"god","123456"};
            int pow = qr.update(conn, sql,obj);//传入链接对象,sql语句,obj对象,obj数组内的两个值对应两个预留字符
            conn.close();
            if(pow>0) {
                System.out.println("添加成功!");
            }else {
                System.out.println("添加失败!");
            }
        }
    public static void delete() throws SQLException {
            QueryRunner qr = new QueryRunner();
            Connection conn = DButil.getConn();
            String sql = "delete from userscount where uid=?";
            int pow = qr.update(conn,sql,1);//可以直接传入多个参数来对应预留字符
            conn.close();
            if(pow>0) {
                System.out.println("删除成功!");
            }else {
                System.out.println("删除失败!");
            }
    }

    增删改都调用update()方法。

    (2)查询

    查询调用query()方法,最常用的是将查询的结果存入javabean对象中,然后把多个结果存入集合中

    public static void findBeanList() throws SQLException {
            QueryRunner qr = new QueryRunner();
            Connection conn = DButil.getConn();
            String sql = "select * from userscount";
            List<UserBean> list = qr.query(conn, sql,new BeanListHandler<UserBean>(UserBean.class));
            //查询到的每条记录存入对象中,对象存入list中
            for(UserBean b:list) {
                System.out.println(b.getUid()+"::"+b.getUname()+"::"+b.getUpwd());
            }
            conn.close();
    }

    其他的查询方法:

    public static void find() throws SQLException {
            QueryRunner qr = new QueryRunner();
            Connection conn = DButil.getConn();
            String sql = "select * from userscount";
            Object[] obj = qr.query(conn,sql, new ArrayHandler());//查询到的第一条记录存入集合
            for(Object o:obj) {
                System.out.println(o);
            }
            conn.close();
    }
    public static void findList() throws SQLException {
            QueryRunner qr = new QueryRunner();
            Connection conn = DButil.getConn();
            String sql = "select * from userscount";
            List<Object[]> list = qr.query(conn,sql, new ArrayListHandler());//查询到的每条记录记录存入Object数组然后放入Arraylist中
            for(Object[] o:list) {
                for(Object obj:o) {
                    System.out.println(obj);
                }
            }
            conn.close();
    }
    public static void findBean() throws SQLException {
            QueryRunner qr = new QueryRunner();
            Connection conn = DButil.getConn();
            String sql = "select * from userscount";
            UserBean ub = qr.query(conn, sql,new BeanHandler<UserBean>(UserBean.class));//查询到的第一条记录存入对象中
            conn.close();
    }
    public static void findScalar() throws SQLException {
            QueryRunner qr = new QueryRunner();
            Connection conn = DButil.getConn();
            String sql = "select count(*) from userscount group by uname";
            long count = qr.query(conn, sql,new ScalarHandler<Long>());//查找指定数据
            System.out.println(count);
            conn.close();
    }

    2.连接池(pool、dbcp)

    提供DataSource接口(java中提供的连接池)的实现类BasicDataSource,连接数据库并返回一个连接池对象

    public class ConnPool {
        public static DataSource getDataSource() {
            try(InputStream in = ConnPool.class.getClassLoader().getResourceAsStream("DButil.properties");){
                Properties pro = new Properties();
                pro.load(in);
                String driver = pro.getProperty("driver");
                String url = pro.getProperty("url");
                String user = pro.getProperty("user");
                String password = pro.getProperty("password");
                BasicDataSource dataSource = new BasicDataSource();
                dataSource.setDriverClassName(driver);
                dataSource.setUrl(url);
                dataSource.setUsername(user);
                dataSource.setPassword(password);
                return dataSource;
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("连接数据库失败!"+e);
            }
        }
    }

    如何使用连接池:

    将连接池对象传入QueryRunner的构造方法中

    public static void findMap() throws SQLException {
            QueryRunner qr = new QueryRunner(ConnPool.getDataSource());//将连接池对象传入
            String sql = "select * from userscount";
            Map<String, Object> map = qr.query(sql,new MapHandler());//key是字段名,value是数据
            Set<Entry<String,Object>> entry = map.entrySet();
            for(Entry<String,Object> e:entry) {
                System.out.println(e.getKey()+":"+e.getValue());
            }
    }

     3.JDBC事务

    一般情况下,sql语句在excute后会自动将数据提交到数据库,而使用手动事务后,数据会暂存在事务日志中,可以防止多条语句执行时,其中一条语句执行失败而其他语句成功执行的情况,同时可以回滚数据取消操作。

    public class Demo {
    
        public static void main(String[] args){
            try {
                Connection conn = DButil.getConn();
                String sql1 = "insert into userscount(uname,upwd) values(?,?)";
                String sql2 = "insert into userscoun(uname,upwd) values(?,?)";//故意写错,表名少个t
                //关闭自动提交事务
                conn.setAutoCommit(false);
                PreparedStatement ps1 = conn.prepareStatement(sql1); 
                ps1.setString(1, "admin");
                ps1.setString(2, "123456");
                ps1.executeUpdate();
                PreparedStatement ps2 = conn.prepareStatement(sql2); 
                ps2.setString(1, "user1");
                ps2.setString(2, "123456");
                ps2.executeUpdate();
                // 手动提交事务
                conn.commit();
                //conn.rollback();回滚数据
                //上面两条数据都没有被加入数据库
                DButil.close(ps1, conn);
            } catch (Exception e) {
                System.out.println("添加数据失败!");
            }
        }
    }

     需要注意的是,手动事务能成功的前提是执行sql语句的statement来自于同一个Connection,一般DAO层的方法是在Service层执行的,所以在Service层的方法中,每个方法内的DAO层方法要使用同一个Connection,将其作为参数传入DAO层的方法:

    public void method(){
        Connection conn =DButil.getConn();
        conn.setAutoCommit(false);
        方法(conn,其他参数) ;
        方法(conn,其他参数);
        .
        .
        .
        .
        conn.commit();
    
    }

     利用ThreadLocal改进上述方法:

    DButil内改动

    private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
    
      //获取连接
        public static Connection getCurrentConn() throws SQLException {
            Connection conn = tl.get();
            if(conn==null) {
                tl.set(getConn());
            }
            return conn;
        }
        //开启手动事务
        public static void startManul() throws SQLException {
            Connection conn = getCurrentConn();
            conn.setAutoCommit(false);
        }
        //回滚
        public static void manulRollback() throws SQLException {
            Connection conn = getCurrentConn();
            conn.rollback();
        }
        //手动提交
        public static void manulCommit() throws SQLException {
            Connection conn = getCurrentConn();
            conn.commit();
        }

    DAO层方法:

    public void method(){
        Connection conn =DButil.getCurrentConn();
        业务逻辑....
    
    }

    Service层改动:

    public void method(){
        DButil.startManul();
        方法(参数) ;
        方法(参数);
        .
        .
        .
        .
        DButil.manulCommit();
    
    }finally{
        manulRollback();
    }
  • 相关阅读:
    笔记35 跨重定向请求传递数
    判断邮箱的正则表达式
    按钮
    async await 的用法
    笔记34 Spring MVC的高级技术——处理multipart形式的数据
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Unique Binary Search Trees,Unique Binary Search Trees II
    Validate Binary Search Tree
    Populating Next Right Pointers in Each Node,Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/whwjava/p/9035534.html
Copyright © 2011-2022 走看看