Apache-DBUtils实现CRUD操作

1. Apache-DBUtils简介

  • commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。
  • API介绍:
    (1)org.apache.commons.dbutils.QueryRunner
    (2)org.apache.commons.dbutils.ResultSetHandler
    (3)工具类:org.apache.commons.dbutils.DbUtils
image.png

2. 主要API的使用

DbUtils

  • DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。主要方法如下:
    (1)public static void close(…) throws java.sql.SQLException: DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。
    (2)public static void closeQuietly(…): 这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。
    (3)public static void commitAndClose(Connection conn)throws SQLException: 用来提交连接的事务,然后关闭连接
    (4)public static void commitAndCloseQuietly(Connection conn): 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。
    (5)public static void rollback(Connection conn)throws SQLException:允许conn为null,因为方法内部做了判断
    (6)public static void rollbackAndClose(Connection conn)throws SQLException
    (7)rollbackAndCloseQuietly(Connection)
    (8)public static boolean loadDriver(java.lang.String driverClassName):这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。

QueryRunner类

  • 该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
  • QueryRunner类提供了两个构造器:
    (1)默认的构造器
    (2)需要一个 javax.sql.DataSource 来作参数的构造器
  • QueryRunner类的主要方法:
    更新
    (1)public int update(Connection conn, String sql, Object... params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
    (2)......
    插入
    (1)public T insert(Connection conn,String sql,ResultSetHandler rsh, Object... params) throws SQLException:只支持INSERT语句,其中 rsh - The handler used to create the result object from the ResultSet of auto-generated keys. 返回值: An object generated by the handler.即自动生成的键值
    (2)....
    批处理
    (1)public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException: INSERT, UPDATE, or DELETE语句
    (2)public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException:只支持INSERT语句
    (3).....
    查询
    (1)public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
    (2)......

ResultSetHandler接口及实现类

  • 该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
  • ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)。
  • 接口的主要实现类:
    (1)ArrayHandler:把结果集中的第一行数据转成对象数组。
    (2)ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
    (3)BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
    (4)BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
    (5)ColumnListHandler:将结果集中某一列的数据存放到List中。
    (6)KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
    (7)MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
    (8)MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
    (9)ScalarHandler:查询单个值对象

代码示例(使用QueryRunner实现增删改查以及查询特殊值的操作)

package com.lty5.dbutils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
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;

import com.lty2.bean.Customer;
import com.lty4.util.JDBCUtils;

    /**
     * commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,封装了针对于数据库的增、删、改、查操作
     */
public class QueryRunnerTest {
    
    // 测试插入
    @Test
    public void testInsert() {
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            
            conn = JDBCUtils.getConnection3();
            String sql = "insert into customers(name , email , birth)values(?,?,?)";
            int insertCount = runner.update(conn, sql, "蔡徐坤", "[email protected]", "1997-05-08");
            System.out.println("添加了"  + insertCount + "条记录");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
                
            JDBCUtils.closeResource(conn, null);
        }
    
    }
    
    
    // 测试查询
    /*
     * BeanHandler : 是ResultSetHandler接口的实现类,用于封装表中的一条记录
     */
    @Test
    public void testQuery1() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            String sql = "select id , name , email , birth from customers where id = ?";
            BeanHandler handler = new BeanHandler<>(Customer.class);
            Customer customer = runner.query(conn, sql, handler, 31);
            System.out.println(customer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            JDBCUtils.closeResource(conn, null);
        }
    }
    
    /*
     * BeanListHandler : 是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合
     */
    @Test
    public void testQuery2() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            String sql = "select id , name , email , birth from customers where id < ?";
            BeanListHandler handler = new BeanListHandler<>(Customer.class);
            List list = runner.query(conn, sql, handler, 31);
            list.forEach(System.out::println);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
                
            JDBCUtils.closeResource(conn, null);
        }
    }
    
    /*
     * MapHandler : 是ResultSetHandler接口的实现类,对应表中的一条记录(通过键 值 的形式)
     *     --- 将字段及相应字段的值作为map中的键和值(key 和 value)
     */
    @Test
    public void testQuery3() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            String sql = "select id , name , email , birth from customers where id = ?";
            MapHandler handler = new MapHandler();
            Map map = runner.query(conn, sql, handler, 31);
            System.out.println(map);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            JDBCUtils.closeResource(conn, null);
        }
    }
    
    
    /*
     * MapListHandler : 是ResultSetHandler接口的实现类,对应表中的多条记录(通过键 值 的形式)
     *     --- 将字段及相应字段的值作为map中的键和值(key 和 value),将这些map添加到List中
     */
    @Test
    public void testQuery4() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            String sql = "select id , name , email , birth from customers where id < ?";
            MapListHandler handler = new MapListHandler();
            List> list = runner.query(conn, sql, handler, 31);
            list.forEach(System.out::println);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            JDBCUtils.closeResource(conn, null);
        }
    }
    
    
    /*
     * ScalarHandler : 用于查询特殊值
     */
    @Test
    public void testQuery5() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            
            String sql = "select count(*) from customers";
            
            ScalarHandler handler = new ScalarHandler();
            
            Long count = (Long) runner.query(conn, sql, handler);
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            JDBCUtils.closeResource(conn, null);
        }
    }
    
    
    @Test
    public void testQuery6() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            
            String sql = "select max(birth) from customers";
            
            ScalarHandler handler = new ScalarHandler();
            
            Date maxBirth = (Date) runner.query(conn, sql, handler);
            System.out.println(maxBirth);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            JDBCUtils.closeResource(conn, null);
        }
    }
    
}

使用Druid数据库连接池技术获取数据库连接

package com.lty4.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCUtils {
    
    /**
     * 获取数据库的连接
     */
    public static Connection getConnection() throws Exception {
        // 1.读取配置文件中的4个基本信息 
        // ClassLoader.getSystemClassLoader() : 获取系统类加载器
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");

        Properties pros = new Properties();
        pros.load(is);
        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        String url = pros.getProperty("url");
        String driverClass = pros.getProperty("driverClass");

        // 2.加载驱动
        Class.forName(driverClass);

        // 3.获取连接
        Connection conn = DriverManager.getConnection(url, user, password);
        
        return conn;
    }
    
    
    /**
     * 使用C3P0的数据库连接池技术
     */
    // 数据库连接池只需提供一个即可   放在外面的好处? --- > 随着工具(当前)类的调用而被立即创建实例化对象,当存在同时多个调用时,该实例化对象始终是这一个,避免了调用一次创建一次实例化对象的过程
    private static ComboPooledDataSource cpds = new ComboPooledDataSource("hellc3p0"); // 创造c3p0数据库连接池
    
    public static Connection getConnection1() throws SQLException {
        
        Connection conn = cpds.getConnection();
        
        return conn;
    }
    
    /**
     * 使用DBCP数据库连接池技术来获取数据库连接
     */
    // 创建一个DBCP数据库连接池
    private static DataSource source;
    
    // 静态代码块随着类的加载而加载,只执行一次
    static {
        
        try {
            Properties pros = new Properties();
            
            // 方式一 :使用类的加载器获取系统类加载器
//      InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); // 默认识别src下
            
            // 方式二
            FileInputStream is = new FileInputStream(new File("src/dbcp.properties")); // 识别的是当前工程下
            
            pros.load(is);

            source = BasicDataSourceFactory.createDataSource(pros);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static Connection getConnection2() throws Exception {
        
        Connection conn = source.getConnection();
        
        return conn;
    }
    
    
    /**
     * 使用Druid数据库连接池技术
     */
    private static DataSource source1;
    static {
        try {
            Properties pros = new Properties();
            
            InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
            
            pros.load(is);
            
            source1 = DruidDataSourceFactory.createDataSource(pros);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection3() throws Exception {
        
        Connection conn = source1.getConnection();
        
        return conn;
    }
    
    
    /**
     * 关闭资源的操作
     */
    public static void closeResource(Connection conn , Statement ps) {
        try {
            if (conn != null)
                conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (ps != null)
                ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    // 关闭资源操作
    public static void closeResource(Connection conn , Statement ps , ResultSet rs) {
        try {
            if (conn != null)
                conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (ps != null)
                ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (rs != null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Customer实体类

package com.lty2.bean;

import java.sql.Date;

    /**
     * ORM编程思想 : Object Relational Mapping (对象关系映射)
     * 具体体现:  我们需要让一个数据表对应一个Java类
     *          表中的一条记录对应Java类的一个对象
     *          表中的一个字段对应Java类的一个属性
     */
public class Customer {
    
    private int id;
    private String name;
    private String email;
    private Date birth;
    
    
    
    public Customer() {
        super();
    }



    public Customer(int id, String name, String email, Date birth) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
        this.birth = birth;
    }



    public int getId() {
        return id;
    }



    public void setId(int id) {
        this.id = id;
    }



    public String getName() {
        return name;
    }



    public void setName(String name) {
        this.name = name;
    }



    public String getEmail() {
        return email;
    }



    public void setEmail(String email) {
        this.email = email;
    }



    public Date getBirth() {
        return birth;
    }



    public void setBirth(Date birth) {
        this.birth = birth;
    }



    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
    }
    
}

自定义ResultSetHandler的实现类完成指定操作(单个方法)

    /*
     *  自定义ResultSetHandler的实现类
     */
    @Test
    public void testQuery7() {
        
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtils.getConnection3();
            
            String sql = "select id , name , email , birth from customers where id = ?";
            
            ResultSetHandler handler = new ResultSetHandler() {//匿名实现类

                @Override
                public Customer handle(ResultSet rs) throws SQLException {
//                  System.out.println("handle");
                    
                    if(rs.next()) {
                        
                        int id = rs.getInt("id");
                        String name = rs.getString("name");
                        String email = rs.getString("email");
                        Date birth = rs.getDate("birth");
                        
                        Customer customer = new Customer(id, name , email, birth);
                        return customer;
                    }
                    
                    return null;
                }
                
                
            };
            Customer customer = runner.query(conn, sql, handler, 31);
            System.out.println(customer);
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            JDBCUtils.closeResource(conn, null);
        }
    }

使用DbUtils工具类实现关闭资源的操作(单个方法)

    // 使用dbutils.jar中提供的DbUtils工具类,实现资源的关闭
    public static void closeResource1(Connection conn , Statement ps , ResultSet rs) {
        
        // 方式一
//       try {
//          DbUtils.close(conn);
//      } catch (SQLException e) {
//          e.printStackTrace();
//      }
//       
//       try {
//          DbUtils.close(ps);
//      } catch (SQLException e) {
//          e.printStackTrace();
//      }
//       
//       try {
//          DbUtils.close(rs);
//      } catch (SQLException e) {
//          e.printStackTrace();
//      }
         
        // 方式二
         DbUtils.closeQuietly(conn);
         DbUtils.closeQuietly(ps);
         DbUtils.closeQuietly(rs);
    }

你可能感兴趣的:(Apache-DBUtils实现CRUD操作)