DBUtils学习

>DBUtils
DBUtils是java编程中的数据库操作实用工具,小巧简单实用。 轻量级框架。
DBUtils封装了对JDBC的操作,简化了JDBC操作。可以少写代码。
1.对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
2.对于数据表的写操作,也变得很简单(只需写sql语句).。
3.可以使用数据源,使用JNDI,数据库连接池等技术来优化性能--重用已经构建好的数据库连接对象。

DBUtils的三个核心对象
QueryRunner类
ResultSetHandler接口
DBUtils类

使用步骤:
创建QueryRunner对象
使用query方法执行select语句
使用ResultSetHandler封装结果集
使用DbUtils类释放资源   几乎用不上

1、QueryRunner类
  QueryRunner中提供对sql语句操作的API。
主要有三个方法:
  query() 用于执行select 
  update() 用于执行insert update delete
  batch() 批处理
构造函数:
new QueryRunner(); 它的事务可以手动控制。
也就是说此对象调用的方法(如:query、update、batrch)参数中要传入自行创建的Connection对象。
new QueryRunner(DataSource ds); 它的事务是自动控制的。一个sql一个事务。
此对象调用的方法(如:query、update、batrch)参数中无需传入自行创建Connection对象,而使用连接池中的Connection对象。

public class TestCURD {
    @Test  //插入一条记录
    public void TestInsert() throws SQLException {
        //创建一个queryRunner对象   C3P0Util.getDataSource()将事务的控制权给它
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        //执行sql语句
        qr.update("insert into users (name,password,email,birthday) values (?,?,?,?)","payn10","809566095","809566095@qq.com",new Date());
    }
    
    @Test   //修改一条记录
    public void TestUpdate() throws SQLException {
        //创建一个queryRunner对象   C3P0Util.getDataSource()将事务的控制权给它
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        //执行sql语句
        qr.update("update users set name=?,password=? where id=? ","jay","777777",4);
    }
    
    @Test   //修改一条记录
    public void TestDelete() throws SQLException {
        //创建一个queryRunner对象   
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        //执行sql语句
        qr.update("delete from users where id=?",4);
    }
    
    @Test   //批处理  只能执行相同的sql语句
    public void TestBatch() throws SQLException {
        //创建一个queryRunner对象 
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        
        Object[][] params = new Object[10][];  //高维代表执行的次数
        for (int i = 0; i < params.length; i++) {
            params[i] = new Object[] {"payn10"+i,"123","123@163.com",new Date()};
        }
        qr.batch("insert into users (name,password,email,birthday) values (?,?,?,?)", params);
    }
}
View Code

上述案例中可以将:QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());提取出来公共使用。

2、ResultSetHandler接口
  用于定义select操作后,怎样封装结果集。
ResultSetHandler是一个接口,可以是能够用框架自己的内部类来实现。我们自己实现的话,比较麻烦,如下。

@Test  //
    public void testSelect() throws SQLException {
        //创建一个QueryRunner
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); //传进一个数据源
        List<User> list = qr.query("select * from users", new ResultSetHandler<List<User>>(){
            @Override
            public List<User> handle(ResultSet rs) throws SQLException {
                List<User> list = new ArrayList<User>();
                while(rs.next()) {
                    User u = new User();
                    u.setId(rs.getInt(1));
                    u.setName(rs.getString(2));
                    u.setPassword(rs.getString(3));
                    u.setEmail(rs.getString(4));
                    u.setBirthday(rs.getDate(5));
                    list.add(u);
                }
                return list;
            }
        });
        for (User user : list) {
            System.out.println(user.toString());
        }
    }
View Code

使用封装好的实现的BeanListHandler实现类:

public void testSelect2() throws SQLException{
        //创建一个QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        //执行查询语句,并返回结果
        List<User> list = qr.query("select * from users where id=? and username=?", new BeanListHandler<User>(User.class),8,"jerry");
        
        for (User user : list) {
            System.out.println(user);
        }
    }
View Code

ResultSetHandler接口共有9个实现类。
用来封装结果集的:
ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[]。

Object[] arr = qr.query("select * from users where name=? and password=?", new ArrayHandler(),"payn","123");

ArrayListHandler:适合取多条记录。把每条记录的每列值封装到一个数组中Object[](一个Object[]代表一行数据),把数组封装到一个List

ColumnListHandler:取某一列的数据。封装到List中。
KeyedHandler/keyedHandler(int columnIndex):
取多条记录,每一条记录封装到一个Map中(即列名和列值),再把这个Map封装到另外一个Map中,key为指定的字段值(系统指定?)。
MapHandler:适合取1条记录。把当前记录的列名和列值放到一个Map中。
MapListHandler:适合取多条记录。把每条记录封装到一个Map中,再把Map封装到List
ScalarHandler:适合取单行单列数据.
BeanHandler:查询到的行封装成的单个对象。
BeanListHandler:返回泛型类型集合对象。

public class TestResultSetHandler {
    @Test//ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[]
    public void tese1() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        Object[] arr  = qr.query("select * from users", new ArrayHandler());
        
        for (Object o : arr) {
            System.out.println(o);
        }
    }
    
    @Test//ArrayListHandler:适合取多条记录。把每条记录的每列值封装到一个数组中Object[],把数组封装到一个List中
    public void tese2() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        List<Object[]> query = qr.query("select * from users", new ArrayListHandler());
        
        for (Object[] os : query) {
            for (Object o : os) {
                System.out.println(o);
            }
            System.out.println("--------------");
        }
    }
    
    @Test //ColumnListHandler:取某一列的数据。封装到List中。
    public void tese3() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        List<Object> list = qr.query("select username,password from users", new ColumnListHandler(1));
        
        for (Object o : list) {
            System.out.println(o);
        }
    }
    
    @Test //KeyedHandler:取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另外一个Map中,key为指定的字段值。
    public void tese4() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        //大Map的key是表中的某列数据,小Map中的key是表的列名,所以大Map的key是Object类型,小Map的key是String类型
        Map<Object,Map<String,Object>> map = qr.query("select * from users", new KeyedHandler(1));
        
        for (Map.Entry<Object, Map<String,Object>> m : map.entrySet()) {
            System.out.println(m.getKey());//大Map中key值就是id列的值
            for (Map.Entry<String, Object> mm : m.getValue().entrySet()) {
                System.out.println(mm.getKey()+"\t"+mm.getValue());//取出小Map中的列名和列值
            }
            System.out.println("---------------------");
        }
        
    }
    
    
    @Test//MapHandler:适合取1条记录。把当前记录的列名和列值放到一个Map中
    public void tese5() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        Map<String,Object> map = qr.query("select * from users where id=?", new MapHandler(),20);
        
        for (Map.Entry<String, Object> m : map.entrySet()) {
            System.out.println(m.getKey()+"\t"+m.getValue());
        }
        
    }
    
    
    @Test//MapListHandler:适合取多条记录。把每条记录封装到一个Map中,再把Map封装到List中
    public void tese6() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        List<Map<String,Object>> list = qr.query("select * from users", new MapListHandler());
        
        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> m : map.entrySet()) {
                System.out.println(m.getKey()+"\t"+m.getValue());
            }
            System.out.println("---------------");
        }
    }
    
    @Test //ScalarHandler:适合取单行单列数据
    public void tese7() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        Object o = qr.query("select count(*) from users", new ScalarHandler(1));
        System.out.println(o.getClass().getName());
    }
    
    @Test //BeanHandler:适合取单行单列数据
    public void tese8() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        User user = qr.query("select * from users where id=?", new BeanHandler<User>(User.class),1);
        System.out.println(user);
    }
    
    
    @Test //BeanListHandler 
    public void tese9() throws SQLException{
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        List<User> list = qr.query("select * from users where id=?", new BeanListHandler<User>(User.class),1);
        
        System.out.println(list.size());
    }
}
View Code

3、DBUtils类==>几乎用不上
  一个工具类,定义了关闭资源与事务处理的方法。

4、DBUtils控制事务的开发

5、ThreadLocal
java.lang
类 ThreadLocal<T>
该类提供了线程局部变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。

public class ThreadLocal{
private Map<Runnable,Object> container = new HashMap<Runnable,Object>();
public void set(Object value){
container.put(Thread.currentThread(),value);//用当前线程作为key
}
public Object get(){
return container.get(Thread.currentThread());
}
public void remove(){
container.remove(Thread.currentThread());
}
}
View Code

总结:调用该类的get方法,永远返回当前线程放入的数据。线程局部变量。


posted @ 2018-12-05 22:18  payn  阅读(163)  评论(0)    收藏  举报