一、commons-dbutils简介
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。
- org.apache.commons.dbutils (该包中的类主要帮助我们更便捷的操作JDBC)
- org.apache.commons.dbutils.handlers(该包中的类都是实现org.apache.commons.dbutils.ResultSetHandler接口的实现类)
- org.apache.commons.dbutils.wrappers(该包中的类主要是封装了对Sql结果集的操作)
二、QueryRunner类使用讲解
该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
QueryRunner类提供了两个构造方法:
- 默认的构造方法
- 需要一个 javax.sql.DataSource 来作参数的构造方法。
2.1、QueryRunner类的主要方法
public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException: 几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource) 或使用的setDataSource 方法中重新获得 Connection。
public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException : 执行一个不需要置换参数的查询操作。
public int update(Connection conn, String sql, Object[] params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
public int update(Connection conn, String sql) throws SQLException:用来执行一个不需要置换参数的更新操作。
2.2、使用QueryRunner类实现CRUD(增删查改)
以下使用SQLServer2008版数据库
package org.apache.commons.dbutils;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList;import javax.sql.DataSource;import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler;/*** 使用QueryRunner 类实现CRUD(create,read,update,delete)* @author Administrator**/ public class QueryRunnerTest {/*测试表create table stuInfo(stuNo int primary key identity (1,1),--学号stuName nvarchar(10) not null,--学生姓名stuSex nvarchar(2) not null,--学生性别stuAge int not null,--学生年龄stuSeat int not null,--学生座位stuAddress nvarchar(20) --学生住址)*/public static void main(String[] args) {QueryRunnerTest test = new QueryRunnerTest();test.add();test.delete();test.update();test.find();test.getAll();}private static Connection getConnection() {Connection conn = null;try {Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;Database=student", "sa", "sasa");} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(conn);return conn;}//添加方法public void add () {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "insert into stuInfo (stuName,stuSex,stuAge,stuSeat,stuAddress) values (?,?,?,?,?)";Object param[] = {"张良","男",20,11,"韩国"};int i;try {i = qr.update(conn, sql, param);System.out.println("添加成功:"+i);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//删除方法public void delete() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql ="delete from stuInfo where stuNo=?";try {int i = qr.update(conn, sql, 7);System.out.println("删除成功:"+i);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//修改方法public void update() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "update stuInfo set stuName=? where stuNo=?";Object params[] = {"胡歌",3};try {int i = qr.update(conn, sql, params);System.out.println("修改成功:"+i);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//查询方法public void find() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo where stuNo=?";Object params[] = {5};try {StuInfo stuInfo = (StuInfo)qr.query(conn, sql, new BeanHandler<StuInfo>(StuInfo.class), params);System.out.println("查询成功:"+stuInfo);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//查询所有public void getAll() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql ="select * from stuInfo";ArrayList<StuInfo> list;try {list = (ArrayList<StuInfo>) qr.query(conn, sql, new BeanListHandler<StuInfo>(StuInfo.class));for (StuInfo stuInfo : list) {System.out.println(stuInfo);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
三、ResultSetHandler接口使用讲解
该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。
ResultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)
3.1、ResultSetHandler接口的实现类
- ArrayHandler:把结果集中的第一行数据转成对象数组。
- ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
- ColumnListHandler:将结果集中某一列的数据存放到List中。
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
3.2、测试dbutils各种类型的处理器
JavaBean类
package org.apache.commons.dbutils;public class StuInfo {private String stuName;private String stuSex;private int stuAge;private int stuSeat;private String stuAddress;public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}public String getStuSex() {return stuSex;}public void setStuSex(String stuSex) {this.stuSex = stuSex;}public int getStuAge() {return stuAge;}public void setStuAge(int stuAge) {this.stuAge = stuAge;}public int getStuSeat() {return stuSeat;}public void setStuSeat(int stuSeat) {this.stuSeat = stuSeat;}public String getStuAddress() {return stuAddress;}public void setStuAddress(String stuAddress) {this.stuAddress = stuAddress;}//重写toString方法//当需要将一个对象输出到显示器时,通常要调用他的toString()方法,将对象的内容转换为字符串.java中的所有类默认都有一个toString()方法//默认情况下 System.out.println(对象名)或者System.out.println(对象名.toString())输出的是此对象的类名和此对象对应内存的首地址如果想自定义输出信息必须重写toString()方法@Overridepublic String toString() {// TODO Auto-generated method stubreturn ("姓名:"+stuName+"\n"+"年龄:"+stuAge+";"+"性别:"+stuSex+";"+"座位:"+stuSeat+";"+"地址:"+stuAddress);}}
各种结果集处理方法
package org.apache.commons.dbutils;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.Map;import org.apache.commons.dbutils.handlers.ArrayHandler; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.BeanMapHandler; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.apache.commons.dbutils.handlers.KeyedHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler;/*** Dbutils结果集实例* 单行数据处理:ScalarHandler ArrayHandler MapHandler BeanHandler* 多行数据处理:BeanListHandler AbstractkeyedHandler(KeyedHandler BeanMapHandler)* AbstractListHandler(ArrayListHandler MapListHandler ColumnListHandler)* 可供扩展的类:BaseResultSetHandler* @author Administrator**/ public class ResultSetHandlerTest {public static void main(String[] args) {// TODO Auto-generated method stubResultSetHandlerTest test = new ResultSetHandlerTest();//test.testColumnListHandler();test.testScalarHandler();test.testColumnListHandler();test.testArrayHandler();test.testArrayListHandler();test.testMapHandler();test.testMapListHandler();test.testKeyedHandler();test.testBeanHandler();test.testBeanListHandler();test.testBeanMapHandler();}private static Connection getConnection() {Connection conn = null;try {Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;Database=student", "sa", "sasa");} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(conn);return conn;}//ScalarHandler<T>用于获取结果集中第一行某列的数据并转换成T表示的实际对象。( 该类对结果集的处理直接在 handle 方法中进行,不涉及 dbutils 库的其他类)public void testScalarHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {//ScalarHandler的参数为空或null时,返回第一行第一列的数据int i = qr.query(conn, sql, new ScalarHandler<Integer>());System.out.println("Scalarhandler:"+i);//ScalarHandler的参数可以是列的索引(从1开始)或是列名String name = qr.query(conn, sql, new ScalarHandler<String>(2));System.out.println("学生姓名:"+name);String stuName = qr.query(conn, sql, new ScalarHandler<String>("stuName"));System.out.println("stuName:"+stuName);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//ColumnListHandler<T>:根据列索引或列名获取结果集中某列的所有数据,并添加到ArrayList中。可以看成ScalarHandler<T>的加强版public void testColumnListHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {List<String> list = (List) qr.query(conn, sql, new ColumnListHandler<String>("stuName"));//List<String> list = (List) qr.query(conn, sql, new ColumnListHandler<String>(2));for (String string : list) {System.out.println(string);}System.out.println(list);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} }//ArrayHandler:把结果集中的第一行数据转成对象数组(用于获取结果集中的第一行数据,并将其封装到数组中,一列值对应一个数组元素)public void testArrayHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {Object result[] = qr.query(conn, sql, new ArrayHandler());System.out.println("ArrayHandler:"+Arrays.asList(result));System.out.println("ArrayHandler:"+Arrays.toString(result));} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//ArrayListHandler:把结果集中的每一行数据都转成一个Object数组(处理过程等同于ArrayHandler),再将该数组添加到ArrayList中。//简单点,就是将每行数据经ArrayHandler处理后,添加到ArrayListhandler中public void testArrayListHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {List<Object[]> list = (List) qr.query(conn, sql, new ArrayListHandler());for (Object[] objects : list) {System.out.println(Arrays.asList(objects));System.out.println(Arrays.toString((Object[])objects));}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//KeyedHandler:用于获取所有结果集,将每行结果集转换为Map<String,Object>,并指定某列为Key。//可以简单认为是一个双层Map,相当于先对每行数据执行MapHandler,再为其指定Key添加到HashMap中.//KeyedHadler<K>中的<K>是指定的列值得类型public void testKeyedHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {//在这里,指定主键stuNo为结果Key//注意:也可指定其他列作为Key,如果选取的列值存在重复,则后面的会覆盖前面的,以保证HashMaP中Key值是唯一的 Map<Integer,Map> map = (Map)qr.query(conn, sql, new KeyedHandler("stuNo"));//Map<Integer,Map> map = (Map)qr.query(conn, sql, new KeyedHandler(1));for (Map.Entry<Integer, Map> element : map.entrySet()) {//entrySet()返回此映射中包含的映射关系的 Set 视图。int stuNo = element.getKey();Map<String,Object> innermap = element.getValue();for (Map.Entry<String, Object> innerelement : innermap.entrySet()) {String columnName = innerelement.getKey();Object value = innerelement.getValue();System.out.println(columnName+"="+value);System.out.println("-------------------");}}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//MapHandler:将结果集的第一行数据封装到一个Map里,Map中key是列名,value就是对应的值public void testMapHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {Map<String,Object> map = (Map)qr.query(conn, sql, new MapHandler());for (Map.Entry<String, Object> me : map.entrySet()) {System.out.println(me.getKey()+"="+me.getValue());}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//MapListHandler:将结果集每行数据转换为Map(处理结果等同于MapHandler),再将Map添加到ArrayList中public void testMapListHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {List<Map> list = (List)qr.query(conn, sql, new MapListHandler());for (Map<String,Object> map : list) {System.out.println((Map<String,Object>) map);/*for (Map.Entry<String, Object> me : map.entrySet()) {System.out.println(me.getKey()+"="+me.getValue());}*/}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//BeanHandler<T>:将结果集的第一行数据封装到对应的JavaBean实例中//注意:数据库中表中字段要和JavaBean中属性保持一致public void testBeanHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {StuInfo stuInfo = qr.query(conn, sql, new BeanHandler<StuInfo>(StuInfo.class));System.out.println("BeanHandler:"+stuInfo);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//BeanListHandler<T>:用于将结果集的每一行数据转换为JavaBean,再将这个JavaBean添加到ArrayList中,可以看成BeanHandler的高级版public void testBeanListHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {List<StuInfo> list = (List)qr.query(conn, sql, new BeanListHandler<StuInfo>(StuInfo.class));System.out.println("BeanListHandler:"+list);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//BeanMapHandler:用于获取所有结果集,将每行结果集转换为JavaBean作为value,并指定某列为Key,封装到HashMap中。//相当于,对每行数据做BeanHandler一样的处理后,再指定列值为key封装到HashMap中。public void testBeanMapHandler() {Connection conn = getConnection();QueryRunner qr = new QueryRunner();String sql = "select * from stuInfo";try {Map<Integer,StuInfo> map = qr.query(conn, sql, new BeanMapHandler<Integer,StuInfo>(StuInfo.class, 1));System.out.println("BeanMapHandler:"+map);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
四、DbUtils类使用讲解
DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。主要方法如下:
public static void close(…) throws java.sql.SQLException: DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。
public static void closeQuietly(…): 这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。
public static void commitAndCloseQuietly(Connection conn): 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。
public static boolean loadDriver(java.lang.String driverClassName):这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。