dbutils API学习

dbutils API介绍

1.简介

​ dbutils就是JDBC操作的类库,是对JDBC操作的封装,提供一些简易的API来操作数据库,提供了数据库增删改查等通用的JDBC实现。

2.org.apache.commons.dbutils.handlers包

​ 这个包里面的类是对ResultSetHandler接口的实现类,主要是用来处理ResultSet(结果集)的转换,将结果集转成Object[],List< Object[] >,List< T >,Map< K,V >等的数据结构。这些实现类会在做数据库查询操作时使用,主要有以下类:

  • AbstractListHandler  将ResultSet转为List的抽象类
  • ArrayHandler   将ResultSet转为一个Object[]的ResultSetHandler实现类
  • ArrayListHandler   将ResultSet转换为List< Object[] >的ResultSetHandler实现类
  • BeanHandler   将ResultSet行转换为一个JavaBean的ResultSetHandler实现类
  • BeanListHandler   将ResultSet转换为List< T >的ResultSetHandler实现类
  • ColumnListHandler  将ResultSet的一个列转换为List< Object >的ResultSetHandler实现类
  • KeyedHandler   将ResultSet转换为Map< K,V>的ResultSetHandler实现类
  • MapHandler   将ResultSet的首行转换为一个Map的ResultSetHandler实现类
  • MapListHandler   将ResultSet转换为List< K,V>的ResultSetHandler实现类
  • ScalarHandler   将ResultSet的一个列到一个对象。

3.org.apache.commons.dbutils.QueryRunner

​ 它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,是用来执行SQL语句的工具类。主要的方法如下。

QueryRunner的无参构造函数和有参构造函数:

  1. 用QueryRunner无参构造函数创建的对象,手动提交事务。
  2. 用QueryRunner有参构造函数创建的对象,自动提交事务。

QueryRunner中一共有6种方法:

  • execute(执行SQL语句)
  • batch(批量处理语句)
  • insert(执行INSERT语句)
  • insertBatch(批量处理INSERT语句)
  • query(SQL中 SELECT 语句)
  • update(SQL中 INSERT, UPDATE, 或 DELETE 语句)

比较常用就是query和update

3.1 query

query要用到org.apache.commons.dbutils.handlers包下的实现类,这类提供了ResultSet(结果集)的转换。

ArrayHandler例子:

这个是放回一个Object[]对象,一个Object[]对应一行数据,如:{1,“zs”}

public static void testArrayHandler() throws SQLException{
	//自己写的DataSourceUtil.getDataSourceWithC3P0(),返回datasource
    //QueryRunner执行工具
	QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
    //返回第一个数据(ResultSet转成Object[]),一个Object[]对应表查询的一行数据
	Object[] student = runner.query("select id,name from student where id>?", new ArrayHandler(),1);
	System.out.println(student[0]+"\t"+student[1]);
}

ArrayListHandler例子

这个是放回一个List<Object[]>对象,如:[ {1,“zs”},{2,“李”} ]

public static void testArrayHandler() throws SQLException{
	//自己写的DataSourceUtil.getDataSourceWithC3P0(),返回datasource
    //QueryRunner执行工具
	QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
    //ResultSet转成list<Object[]>,查询多行操作
	List<Object[]> student = runner.query("select id,name from student", new ArrayHandler());
	System.out.println(student[0]+"\t"+student[1]);
}

MapHandler例子

这个是放回一个Map<K,V>对象,{ID=1,name=“ZS”}

 public void testMapHandler() throws SQLException{         
     QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
     String sql = "select * from users";
     //做出map
     Map<String,Object> map = qr.query(sql, new MapHandler());
     for(Map.Entry<String, Object> me : map.entrySet())
     {
         System.out.println(me.getKey() + "=" + me.getValue());
     }
}

MapListHandler例子

List<Map<K,V>>,如[{ID=1,name=“ZS”},{ID=2,name=“ls”}]

public void testMapListHandler() throws SQLException{
    QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
    String sql = "select * from users";

    List<Map<String,Object>> list = (List) qr.query(sql, new MapListHandler());
    for(Map<String,Object> map :list){
        for(Map.Entry<String, Object> me : map.entrySet())
            System.out.println(me.getKey() + "=" + me.getValue());
    }
}

KeyedHandler例子

Map<Integer,Map<String,Object>>,就是Map里面套map,如:{1={ID=1,name=“ZS”},2={ID=2,name=“ls”}}

public void testKeyedHandler() throws Exception{
	QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
	String sql = "select * from users";
 	//MAP里面套map
	Map<Integer,Map<String,Object>> map = qr.query(sql, new KeyedHandler("id"));
	for(Map.Entry<Integer, Map> me : map.entrySet()){
		int  id = me.getKey();
		Map<String,Object> innermap = me.getValue();
		for(Map.Entry<String, Object> innerme : innermap.entrySet()){
			String columnName = innerme.getKey();
			Object value = innerme.getValue();
			System.out.println(columnName + "=" + value);
	}
}
}
3.2 update

update会相对简单很多,用来执行数据库的DML操作,因为不涉及ResultSet,所以直接给SQL语句和变量值就可以了。

增操作

public void Insert() throws SQLException{         
    QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
    String sql = "insert into student(id,name) value(?,?)";        
    int count = qr.query(sql, new Object[]{"1","zs"});   
}

删操作

public void Delete() throws SQLException{         
    QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
    String sql = "delete from student where id = ?";        
    qr.query(sql, 1);   
}

改操作

public void Updata() throws SQLException{         
    QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());
    String sql = "updata from student set name = ? where id = ?";        
    qr.query(sql, new Object[]{"1","xiaoming"});   
}

4.事务手动提交

重复一下QueryRunner的构造函数,如果我们需要手动提交事务用无参构造。

QueryRunner的无参构造函数和有参构造函数:

  1. 用QueryRunner无参构造函数创建的对象,手动提交事务。
  2. 用QueryRunner有参构造函数创建的对象,自动提交事务。

自动提交事务将每个SQL语句都当成一个事务并进行提交,而有时候我们需要把多个SQL语句当成一个事务来处理,举个简单的也是最经典的例子:银行转账。

​ 如:A转钱给B,我们需要完成以下操作,A账户减去转账金额,B账户加上转账金额。这个过程涉及多个SQL操作(两个修改updata),如果我们使用自动提交(每个SQL一个事务),那么就可能发生以下情况,A账户减去转账金额,但当B账户加上转账金时额发生错误。出现A减钱了B没加钱。因为是自动提交,B加钱发生错误也只是B的事务回滚,不涉及A。如果我把这个过程涉及多个SQL操作放到一个事务里面,那么任何一边发生错误,事务都会回滚,因为事务的原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。每次手动提交都会将执行SQL语句放到同一个事务里面(运行多个SQL语句,然后提交,那么执行的SQL语句都放在一个事务里面)。

其中这里与JDBC的基础有关,可以看以下代码例子:

public void QueryRunnertest() throws SQLException{         
   	String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC";
    String user = "root" ;    
    String password = "root";
    //这里随便创建一个连接
    Connection conn= DriverManager.getConnection(url,user,password);
    //设置连接为手动提交
    conn.setAutoCommit(false);
    //因为用手动提交,所以需要无参构造,有参的会帮你自动提交的
    QueryRunner qr = new QueryRunner();
    //插入SQL
    String sql = "insert into student(id,name) value(?,?)";  
    try{
        //只需要把连接传给函数就行了
        int count1 = qr.query(conn,sql, new Object[]{"1","zs"});  
        int count2 = qr.query(conn,sql, new Object[]{"2","ls"});
        int count3 = qr.query(conn,sql, new Object[]{"3","ww"});
        //提交事务
        conn.commit();
    }catch(Exception e){
        //操作回滚
        conn.rollback();    //一旦其中一个操作出错都将回滚,使全部操作都不成功 (事务原子性)
    }
}

在这里例子里面,先获取连接,然后设置连接为手动提交,并创建QueryRunner工具类,并使用工具里面的函数通过传递连接,SQL语句,变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值