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); } }
上述案例中可以将: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()); } }
使用封装好的实现的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); } }
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()); } }
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()); } }
总结:调用该类的get方法,永远返回当前线程放入的数据。线程局部变量。