2018年5月14日java

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();
}
复制代码

 

posted on 2018-06-11 10:56  jason111  阅读(93)  评论(0编辑  收藏  举报

导航