Commons - dbutils

Posted WWWYC

tags:

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

 

时间:2016-12-4 18:06

 

——基本类

自己写的JDBC小工具:

public class JDBCUtils {
    // 使用的是配置文件的默认配置,即必须给出c3p0-config.xml配置文件
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
 
    /*
     * 使用连接池返回一个连接对象
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
 
    /*
     * 返回连接池对象
     */
    public static DataSource getDataSource() {
        return dataSource;
    }
}


——JavaBean

package jdbcutils;
 
public class Stu {
    private int sid;
    private String sname;
    private int age;
    private String gender;
 
    public Stu(int sid, String sname, int age, String gender) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.age = age;
        this.gender = gender;
    }
 
    public Stu() {
        super();
    }
 
    @Override
    public String toString() {
        return "Stu [sid=" + sid + ", sname=" + sname + ", age=" + age + ", gender=" + gender + "]";
    }
 
    public int getSid() {
        return sid;
    }
 
    public void setSid(int sid) {
        this.sid = sid;
    }
 
    public String getSname() {
        return sname;
    }
 
    public void setSname(String sname) {
        this.sname = sname;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public String getGender() {
        return gender;
    }
 
    public void setGender(String gender) {
        this.gender = gender;
    }
}
 




——使用commons - dbutils简化JDBC的代码


简化前:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
 
import org.junit.Test;
 
/**
 * 使用commons-dbutils简化JDBC的代码
 */
public class Demo1 {
    @Test
    public void addStu(Stu stu) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "insert into t_stu values(?,?,?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, stu.getSid());
            pstmt.setString(2, stu.getSname());
            pstmt.setInt(3, stu.getAge());
            pstmt.setString(4, stu.getGender());
        } catch (Exception e) {
            // 处理异常
        } finally {
            // 关闭连接
        }
    }
 
    @Test
    public void updateStu(Stu stu) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "update t_stu set sname = ?, age = ?, gender = ? where sid = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(4, stu.getSid());
            pstmt.setString(1, stu.getSname());
            pstmt.setInt(2, stu.getAge());
            pstmt.setString(3, stu.getGender());
        } catch (Exception e) {
            // 处理异常
        } finally {
            // 关闭连接
        }
    }
 
    @Test
    public void deleteStu(Stu stu) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "delete from t_stu where sid = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, stu.getSid());
        } catch (Exception e) {
            // 处理异常
        } finally {
            // 关闭连接
        }
    }
 
    public Stu load(int sid) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "select * from t_stu where sid = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, sid);
 
            rs = pstmt.executeQuery();
            /*
             * 需要把rs转换成JavaBean
             */
            if (rs.next()) {
                Stu stu = new Stu();
                stu.setSid(rs.getInt("sid"));
                stu.setSname(rs.getString("sname"));
                stu.setAge(rs.getInt("age"));
                stu.setGender(rs.getString("gender"));
 
                return stu;
            }
        } catch (Exception e) {
            // 处理异常
        } finally {
            // 关闭连接
        }
        return null;
    }
}
 

===============================================================================

简化后:

/*
 * 用来将结果集转化成需要的类型
 * 将结果集封装成一个对应的Bean并返回该Bean 
 */
interface Rshandle<T> {
    public T handle(ResultSet rs) throws SQLException;
}


------------------------------------------------------------------------------------------------------------------------------

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
import javax.sql.DataSource;
 
public class QR<T> {
    /*
     * 因为无法确定连接类型,所以使用DataSource接口来接收传入的连接对象
     */
    private DataSource dataSource = null;
 
    public QR() {
        super();
    }
 
    public QR(DataSource dataSource) {
        super();
        /*
         * 接收传入的连接对象
         */
        this.dataSource = dataSource;
    }
 
    /*
     * 更新操作 接收SQL模板和参数列表
     */
    public int update(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            // 通过连接池得到连接
            conn = dataSource.getConnection();
 
            // 使用SQL创建pstmt
            pstmt = conn.prepareStatement(sql);
 
            /*
             * 给参数赋值
             */
            initParams(pstmt, params);
 
            // 执行SQL,并返回受影响行数
            return pstmt.executeUpdate();
        } catch (Exception e) {
            // 处理异常
            throw new RuntimeException(e);
        } finally {
            // 关闭连接
        }
    }
 
    /*
     * 使用传入的SQL语句和参数,最终得到一个结果集,然后调用结果集的handle()方法,handle()方法谁调用谁传入
     */
    public T query(String sql, Rshandle<T> rh, Object... params) {
 
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            // 通过连接池得到连接
            conn = dataSource.getConnection();
 
            // 使用SQL创建pstmt
            pstmt = conn.prepareStatement(sql);
 
            // 给参数赋值
            initParams(pstmt, params);
 
            // 执行SQL
            rs = pstmt.executeQuery();
            // 将结果集传入指定的handle()方法中
            return rh.handle(rs);
        } catch (Exception e) {
            // 处理异常
            throw new RuntimeException(e);
        } finally {
            // 关闭连接
        }
    }
 
    // 用来给参数赋值
    private void initParams(PreparedStatement pstmt, Object... params) throws Exception {
        for (int i = 0; i < params.length; i++) {
            // 因为不知道参数的类型,所以使用Object接收参数
            pstmt.setObject(i + 1, params[i]);
        }
    }
}


------------------------------------------------------------------------------------------------------------------------------


进行调用:


import java.sql.ResultSet;
import java.sql.SQLException;
 
import org.junit.Test;
 
public class Demo2 {
    @Test
    public void fun1() {
        // Stu s = new Stu(1001, "张三", 99, "male");
        // int result = addStu(s);
        // System.out.println("受影响行数:" + result);
 
        Stu stu = load(1001);
        System.out.println(stu);
    }
 
    public int addStu(Stu stu) {
        // 创建对象时给出连接池
        QR qr = new QR(JDBCUtils.getDataSource());
        // 给出SQL模板
        String sql = "insert into t_stu values(?,?,?,?)";
        // 给出参数
        Object[] params = { stu.getSid(), stu.getSname(), stu.getAge(), stu.getGender() };
        // 调用update方法,执行增删改
        return qr.update(sql, params);
    }
 
    public Stu load(int sid) {
        // 创建QR对象,并给出连接池
        QR<Stu> qr = new QR<Stu>(JDBCUtils.getDataSource());
        // 创建SQL模板
        String sql = "select * from t_stu where sid = ?";
        // 给出参数
        Object[] params = { sid };
        // 使用RsHandle接口创建内部类
        Rshandle<Stu> rh = new Rshandle<Stu>() {
            // 重写handle()方法
            public Stu handle(ResultSet rs) throws SQLException {
                // 传入的rs集合如果是空,返回null
                if (!rs.next()) {
                    return null;
                }
                // 如果不是null,组合对象并返回
                Stu stu = new Stu();
                stu.setSid(rs.getInt("sid"));
                stu.setSname(rs.getString("sname"));
                stu.setAge(rs.getInt("age"));
                stu.setGender(rs.getString("gender"));
                return stu;
            }
        };
 
        /*
         * 将SQL模板,内部类对象rh,参数列表传给查询方法query() 返回查询后得到的对象
         */
        return qr.query(sql, rh, params);
    }
}



------------------------------------------------------------------------------------------------------------------------------

commons-dbutils中的方法:

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.junit.Test;
 
public class Demo3 {
    @Test
    public void fun() throws Exception {
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "insert into t_stu values (?,?,?,?)";
 
        Object[] params = { 1002, "李四", 88, "female" };
        int result = qr.update(sql, params);
        System.out.println("受影响行数:" + result);
    }
 
    @Test
    public void fun2() throws Exception {
        // 创建QueryRunner对象,并提供数据库连接池对象
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        // 给出SQL模板
        String sql = "select * from t_stu where sid = ?";
        // 给出参数
        Object[] params = { 1002 };
        // ResultSetHandler rsh = new ResultSetHandler(){
 
        // @Override
        // public Stu handle(ResultSet rs) throws SQLException {
        // if(!rs.next()){
        // return null;
        //
        // }
        // return null;
        // }
 
        // }
 
        // 执行query()方法,并给出结果集处理器,即ResultSetHandler接口的实现类
        // 我们给出的是BeanHandler,它实现了ResultSetHandler接口
        // 它需要一个类型,然后它会把结果集中的数据封装到指定类型的JavaBean对象中,然后返回JavaBean
        Stu stu = qr.query(sql, new BeanHandler<Stu>(Stu.class), params);
        System.out.println(stu);
    }
}



——dbutils结果集处理器介绍

commons-dbutils.jar包

QueryRunner类:

    update方法:
        *   int  update(String sql, Object[] params)
            可执行增删改语句。

        *   int  update(Connection conn, String sql, Object ... params)
            需要调用者提供Connection,这说明本方法不再管理Connection了。
            这个方法的好处是可以使用同一Connection对象,用于处理事务,因为同一事务必须保证Connection是唯一的。而update(String sql, Object ... params)方法就无法保证事务的安全性,因为该方法是通过连接池来获取连接的。
            即支持事务。 

    query方法:
        *   T  query(String sql, ResultSetHandler rsh, Object ... params)
            可执行查询。
            它会先得到ResultSet,然后调用rsh的handle()方法并将rs结果集转换为需要的类型。

        *   T  query(Connection conn, String sql, ResultSetHandler<T> rsh, Object ... params)
            道理同:update(Connection conn, String sql, Object ... params)

ResultSetHandler接口:
    BeanHandler
        处理单行结果集。
        是一个实现类,构造器需要一个Class类型的参数,用来把一行结果集转换成指定类型的JavaBean对象。

    BeanListHandler
        处理多行结果集。
        是一个实现类,构造器也需要一个Class类型的参数,用来把一行结果集转换成一个JavaBean对象,然后把多个JavaBean对象保存到List集合中。

    MapHandler
        处理单行结果集。
        是一个实现类,无参构造,把一行结果集转换成Map对象。
            >   id         1001
            >   age      22
            >   name   张三
            >   gender 男
        
    MapListHandler
        处理多行记录。
        是一个实现类,无参构造,把一行记录转换成一个Map对象,多行就是多个Map对象,然后将Map对象保存到List中。

    ScalarHandler
        单行单列时使用。
        通常用于:select count(*) from table语句,即结果集是单行单列的,它返回一个Object。


——结果集处理器具体操作

import java.util.List;
import java.util.Map;
 
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
 
public class Result2 {
    /*
     * BeanListHandler的应用,它是多行结果集处理器 每行记录对应一个Student对象
     */
    @Test
    public void fun() throws Exception {
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from t_stu";
        List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));
        System.out.println(list);
    }
 
    /*
     * MapHandler的应用,它是单行处理器,把一行转换成一个Map对象
     */
    @Test
    public void fun2() throws Exception {
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from t_stu where sid = ?";
        Object[] params = { 2 };
 
        Map<String, Object> map = qr.query(sql, new MapHandler(), params);
        System.out.println(map);
    }
 
    /*
     * MapListHandler的应用,它是多行处理器,把每行都转换成一个Map,即List<Map>
     */
    @Test
    public void fun3() throws Exception {
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from t_stu";
        List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
        System.out.println(mapList);
    }
 
    /*
     * ScalarHandler的应用,返回单行单列的数据
     */
    @Test
    public void fun4() throws Exception {
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select count(*) from t_stu";
        Object obj = qr.query(sql, new ScalarHandler());
        System.out.println(obj);
        // 打印Object的类型
        System.out.println(obj.getClass().getName());
 
        /*
         * 在JDBC5.1之前,query返回的是Integer类型,在Oracle中返回的是BigInteger类型
         * 而在JDBC5.1之后,mysql返回的是Long类型,这三个类有一个共同的父类:Number
         * 所以可以使用Number来接收,然后根据需求转换即可。
         */
        Number number = (Number) qr.query(sql, new ScalarHandler());
        int i = number.intValue();
        long l = number.longValue();
        System.out.println(i);
        System.out.println(l);
    }
}

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

commons-lang3

commons-beanutils的jar包导入了出错。Java 一直报下图错误

commons字符串工具类——commons-lang3

Commons-Collections漏洞

commons dbcp.jar有什么用

Commons Lang 介绍