dbutils---原理以及使用

Posted xjs1874704478

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dbutils---原理以及使用相关的知识,希望对你有一定的参考价值。

 

  原始的操作(增删改)数据库,得到连接后,需要写sql模板,以及设置模板中的参数,其余步骤都相同。

  原始的操作(查单个,以及查所有)数据库,也是得到连接后,写sql模板,以及设置模板中的参数,然后会返回结果集,其余步骤都一样。

1.dbutils原理

自己仿写的工具类(部分代码)==可以实现增删改和查

使用的是c3p0数据库连接池得到的数据库池对象datasource===其实现方法看上篇中的数据库连接池

package com.xjs.dbutils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;
/**
 * 自己写的一个工具类
 * @author hp
 *
 * @param <T>
 */
public class QR<T> {
    private DataSource datasource;

    public QR() {
        
    }
    public QR(DataSource datasource) {
        this.datasource = datasource;
    }
    /**
     * 做insert、update、delete
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql,Object...params){
        Connection con=null;
        PreparedStatement pstmt=null;
        try {
            //1.通过连接池得到连接对象
            con=datasource.getConnection();
            //2.使用sql创建pstmt
            pstmt=con.prepareStatement(sql);
            //3.给sql模板中的参数赋值
            initParams(pstmt, params);
                return pstmt.executeUpdate();
            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{//关闭
            try {
                if(pstmt!=null) pstmt.close();
                if(con!=null) con.close();
            } catch (SQLException e2) {
                // TODO: handle exception
            }
        }        //执行sql,返回的是影响的行数

    }
    
    //给sql模板中的参数赋值---数组
    private void initParams(PreparedStatement pstmt,Object... params) 
            throws SQLException{
        
        for(int i=0;i<params.length;i++){
            pstmt.setObject(i+1,params[i] );
        }
    }
    //传一个sql模板,一个接口(把结果集封装成JavaBean),SQL模板中的参数
    public T query(String sql,RsHandler<T> rh,Object... params){
        Connection con=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        try {
            //1.通过连接池得到连接对象
            con=datasource.getConnection();
            //2.使用sql创建pstmt
            pstmt=con.prepareStatement(sql);
            //3.给sql模板中的参数赋值
            initParams(pstmt, params);
            //4.执行
            rs=pstmt.executeQuery();
            
            //5.返回  结果集--->对象
            return rh.handle(rs);
            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{//关闭
            try {
                if(pstmt!=null) pstmt.close();
                if(con!=null) con.close();
            } catch (SQLException e2) {
                // TODO: handle exception
            }
        }    
    }

}
//接口---把结果集给这个接口的这个方法---变成一个对象
//把结果集转换成需要的类型!---谁调用方法,谁提供其实现
interface RsHandler<T>{
    public T handle(ResultSet rs) throws SQLException;
}

测试:

package com.xjs.dbutils;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import com.xjs.jdbc.JdbcUtils;

public class Demo2 {
    @Test
    public void fun1(){
        Stu s=new Stu(1,"zhangSan",23,"男");
        addStu(s);
    }
    
    public void addStu(Stu stu){
        //1.创建对象时给出连接池
        QR qr=new QR(JdbcUtils.getDataSource());
        //2.给出sql模板
        String sql="insert into stu values(?,?,?,?)";
        //3.给出模板中的参数
        Object[] params={stu.getId(),stu.getName(),stu.getAge(),stu.getSex()};
        //4.调用增删改
        qr.update(sql, params);
    }
    
    @Test
    public void fun2(){
        Stu s=load(1);
        System.out.println(s);
    }
    
    public Stu load(int id){
        QR qr=new QR(JdbcUtils.getDataSource());
        String sql="select * from stu where id=?";
        Object[] params={id};
        
        //内部类
        RsHandler<Stu> rh=new RsHandler<Stu>() {
            
            @Override
            public Stu handle(ResultSet rs) throws SQLException {
                if(!rs.next()) return null;
                Stu stu=new Stu();
                stu.setId(rs.getInt("id"));
                stu.setName(rs.getString("name"));
                stu.setAge(rs.getInt("age"));
                stu.setSex(rs.getString("sex"));
                return stu;
            }
        };
        
        return (Stu)qr.query(sql, rh, params);
        
    }
}

2.dbutlis工具类的使用

使用该工具类需要导包:commons-dbutils-1.4.jar

QueryRunner核心类:

  update方法:

    * int update(String sql, Object...  params) --->可执行增、删、改语句

    * int update(Connection con, String sql, Object... params)--->需要调用者提供Connection,这说明本方法不再管理Connection了。支持事务!

  query方法:

    * T  query(String sql, ResultSetHandler rsh, Object... params) --->可执行查询

      >它会先得到ResultSet结果集,然后调用rsh的handle()把rs转换成需要的类型!

    * T query(Connection con, String sql, ResultSetHandler rsh, Object... params),支持事务

  ResultSetHandler接口:

    *BeanHandler(单行)--->其接口的实现类,它的构造器需要一个Class类型的参数,用来把一行结果转换成指定类型的JavaBean对象。

    *BeanListHandler(多行)--->构造器需要一个Class类型的参数,用来把一行结果集转换成一个JavaBean,那么多行就是转换成List对象,一堆JavaBean。

    *MapHandler(单行)--->把一行结果集转换Map对象。

      >一行记录:

        id  name  age  sex

        1  金泰妍  31  女

      >一个Map:

        {id:1, name:金泰妍, age:31, sex:女}

    *MapListHandler(多行)--->把一行记录转换成一个Map,多行记录就是多个Map,即List<Map>!

    *ScalarHandler(单行单列)--->通常用于select count(*) from 表名 语句!结果集是单行单列的!它返回一个Object。

测试1:

package com.xjs.dbutils;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.junit.Test;

import com.xjs.jdbc.JdbcUtils;

public class Demo3 {

    @Test
    public void fun1() throws SQLException{
        QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
        String sql="insert into stu values(?,?,?,?)";
        Object[] params={0,"金泰妍",31,"女"};
        qr.update(sql,params);
    }
    
    @Test
    public void fun2() throws SQLException{
        //1.创建QueryRunner,需要提供数据库连接池对象
        QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
        //2.给出SQL模板
        String sql="select * from stu where id=?";
        //3.给出参数
        Object[] params={0};
        /*
         * 4.执行query()方法,需要给出结果集处理器,即ResultSetHandler的实现类对象
         * 我们给的是BeanHandler,它实现了ResultSetHandler接口
         * 它需要一个类型,然后它会把rs中的数据封装到指定类型的JavaBean对象中,然后返回JavaBean对象。
         */
        Stu s=qr.query(sql, new BeanHandler<Stu>(Stu.class), params);//要求数据库的列名必须和类的属性名一致(保证映射)
        System.out.println(s);
    }
}

测试2:

    /*
     * 使用BeanListHandler,返回的是一个List<Map>
     */
    @Test
    public void fun3() throws SQLException{
        QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
        String sql="select * from stu";
        //直接封装成对象的集合
        List<Stu> list = qr.query(sql, new BeanListHandler<Stu>(Stu.class));
        
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }
    /*
     * 使用MapHandler的应用,它是单行处理器,把一行记录转换成一个Map对象
     */
    @Test
    public void fun4() throws SQLException{
        QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
        String sql="select * from stu where id=?";
        Object[] params={0};
        Map map= qr.query(sql, new MapHandler(),params);
        System.out.println(map);
    }
    /*
     * 使用MapListHandler,它是多行处理器,把每行都转换成一个Map,即List<Map>
     */
    @Test
    public void fun5() throws SQLException{
        QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
        String sql="select * from stu";
        List<Map<String, Object>> list = qr.query(sql, new MapListHandler());
        
        System.out.println(list);
    }
    /*
     * 使用ScalarHandler
     */
    @Test
    public void fun6() throws SQLException{
        QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
        String sql="select count(*) from stu";
        //返回值类型在不同的地方是不同的,有Integer、Long、BigInteger
        Object obj= qr.query(sql, new ScalarHandler());
        System.out.println(obj);//2--->行
    }

 

以上是关于dbutils---原理以及使用的主要内容,如果未能解决你的问题,请参考以下文章

二级域名原理以及程序代码

数据库基础_JDBC[5]_Dbutil以及一个简单的数据库存储过程

DBUtil

DBUtils框架的使用(上)

DBUtil以及对static的理解

DBUtils与BeanUtils以及Gson工具类