Jdbc-dbutils

这里写自定义目录标题

  • 1 简介
  • 2 常用类
  • 3 依赖
  • 4 DBUtils
  • 4.1 Dbutils三个核心功能介绍
  • 4.2 QueryRunner
  • 5 小结

1 简介

DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。简要来说就是配合数据库连接池简化对数据库的操作代码,数据库连接池简化了连接操作,而DBUtils简化了增删改查操作,底层由DbUtils工具实现,我们只需要关注用法和了解实现逻辑即可。

2 常用类

DBUtils工具
为了更加简单地使用JDBC,Apache组织提供了一个工具类库commons-dbutils,它是操作数据库地一个组件,实现一个对JDBC的简单封装,可以在不影响性能的情况下极大地简化JDBC地编码工作量。

API介绍
commons-dbutils的核心是两个类org.apache.commons.DbUtils、org.apache.commons.dbutils.QueryRunner和一个接口org.apache.commons.dbutils.ResultSetHealer。

DBUtils类
DBUtils类主要为如关闭连接、装载JDBC驱动程序之类的常规工作提供方法,它提供的方法都是静态方法。
1、close()方法
在DBUtils类中,提供了三个重载的close()方法,这些方法都是用来关闭数据连接,并且在关闭连接时,首先会检查参数是否为NULL,如果不是,该方法就会关闭Connection、Statement、ResultSet这三个对象。
2、closeQuietly(Connection conn,Statement stmt,ResultSet rs)方法
该方法用于关闭Connection、Statement和ResultSet对象。与close()方法相比,closeQuietly()方法不仅能Connection、Statement和ResultSet对象为NULL的情况下避免关闭,还能隐藏一些在程序中抛出的SQL异常。
3、commitAndCloseQuietly(Connection conn)方法
commitAndCloseQuietly()方法用来提交连接,然后关闭连接,并且在关闭连接时不抛出异常。
4、loadDriver(java.lang.String driverClassName)方法
loadDriver()方法用于装载并注册JDBC驱动程序,如果成功就返回true。使用该方法时,不需要捕捉ClassNotFoundException异常。

QueryRunner类
QueryRunner类简化了执行SQL语句的代码,它与ResultSetHandler组合在一起就能完成大部分的数据库操作,大大减少编码量。
QueryRunner类提供了两个构造方法,一个是默认的构造方法,一个是需要javax.sql.DataSource作为参数的构造方法。因此在不用为一个方法提供一个数据库连接的情况下,提供给构造器的DataSource就可以用来获得连接。但是,在使用JDBC操作数据库时,需要使用Connection对象对事务进行操作,QueryRunner类提供了不同的方法。

1、query(Connection conn,String sql,ResultSetHandler rsh,Object[] params)方法
该方法用于执行查询操作,其中,参数params表示一个对象数组,该数组中每个元素的值都被用来作为查询语句的置换参数。需要注意的是,该方法会自动处理PreparedStatement和ResultSet的创建和关闭。
值得一提的是,QueryRunner中还有一个方法是query(Connection conn,String sql,Object[] params,ResultSetHandler rsh)该方法与上述方法唯一不同的地方就是参数的位置。但是可变参数必须位于最后一项,所以此方法已过期。
2、query(String sql,ResultSetHandler rsh,Object[] params)方法
该方法用于执行查询操作,与第一个方法相比,它不需要将Connection对象传递给方法,它可以从提供给构造方法的数据源DataSource或使用的setDataSource()方法中获得连接。
3、query(Connection conn,String sql,ResultSetHandler rsh)方法
该方法用于执行一个不需要置换参数的查询结果。
4、update(Connection conn,String sql,Object[] params)方法
该方法用于执行插入、更新或者删除操作,其中,参数params表示SQL语句中的置换参数。
5、update(Connection conn,String sql)方法
该方法用于执行插入、更新或者删除操作,它不需要置换参数。

ResultSetHandler接口
ResultSetHandler接口用于处理ResultSet结果集,它可以将结果集中的数据转为不同的形式。根据结果集中数据类型的不同,ResultSetHandler提供了不同的实现类。
1)AbstractKeyedHandler:该类为抽象类,能够把结果集里面的数据转换为用Map存储。
2)AbstractListHandler:该类为抽象类,能够把结果集里面的数据转化为用List存储。
3)ArrayHandler:把结果集中的第一行数据转成对象数组。
4)ArrayListHandler:把结果集中的每一行数据转成一个对象数组,再将数组存放到List中。
5)BaseResultSetHandler:把结果集转化为其他对象的扩展。
6)BeanHandler:将结果集中的第一行数据存放到一个对应的javaBean实例中。
7)BeanListHandler:把结果集中的每一行数据存放到一个对应的javaBean实例中,再将JavaBean实例存放到List中。
8)BeanMapHandler:把结果集中的每一行数据存放到一个对应的javaBean实例中,再根据指定的key把每个JavaBean再存放到一个Map里。
9)ColumnListHandler:将结果集中的某一列的数据存放到List中
10)KeyedHandler:把结果集中的每一行数据封装到一个Map中,再根据指定的key把每个JavaBean再存放到一个Map里。
11)MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value是对应的值。
12)MapListHandler:把结果集中的每一行数据封装到一个Map中,再存放到List中。
13)ScalarHandler:将结果集中某一条记录的其中一列的数据存储成Object对象。
另外,在ResultSetHandler接口中,提供了一个单独的方法handle(java.sql.ResultSet rs),如果上述实现类没有提供想要的功能,可以通过自定义一个实现ResultSetHandler接口的类,然后通过重写handle()方法,实现结果集的处理。

3 依赖

        
            commons-dbutils
            commons-dbutils
            1.7
        
        
            org.testng
            testng
            7.3.0
        
        
            mysql
            mysql-connector-java
            5.1.49
        
        
            com.alibaba
            druid
            1.2.10
        

工具

public class Dbutils {

    private DruidDataSource dataSource;

    @BeforeMethod
    public void testBefore() throws IOException, ClassNotFoundException, SQLException {
        /*Properties pros=new Properties();
        //properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("/jdbc.properties"));
        pros.load(Dbutils.class.getResourceAsStream("/jdbc.properties"));
        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        String url = pros.getProperty("url");
        String driverClass = pros.getProperty("driverClass");
        Class.forName(driverClass);
        Connection con = DriverManager.getConnection(url,user,password)*/

        Properties properties=new Properties();
        properties.load(Dbutils.class.getResourceAsStream("/jdbc.properties"));
        dataSource = new DruidDataSource();
        dataSource.configFromPropety(properties);
    }

    @Test
    public void test() throws SQLException {
        DruidPooledConnection dpc =  dataSource.getConnection();
        PreparedStatement preparedStatement=dpc.prepareStatement("show tables");
        ResultSet resultSet=preparedStatement.executeQuery();
        while(resultSet.next()) {
            System.out.println(resultSet.getString(1));
        }
    }
}

配置文件

druid.name=myDruid
druid.url=jdbc:mysql://localhost:3306/dc?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
druid.driverClassName=com.mysql.jdbc.Driver
druid.username=root
druid.password=root

4 DBUtils

DbUtils:连接数据库对象----jdbc辅助方法的集合类,线程安全

4.1 Dbutils三个核心功能介绍

QueryRunner 中提供对sql语句操作的API.
ResultSetHandler 接口,用于定义select操作后,怎样封装结果集.
DbUtils 类,它就是一个工具类,定义了关闭资源与事务处理的方法

4.2 QueryRunner

跳转到目录
提供数据源: 使用传过来的数据源的连接对象

构造方法
QueryRunner(DataSource) : 创建核心类,并提供数据源,内部自己维护Connection
普通方法

1 update(String sql , Object ... params): 执行DML语句 用于执行增删改语句
2 query(String sql , ResultSetHandler , Object ... params) : 执行DQL语句,并将查询结果封装到对象中。用于执行查询语句
不提供数据源: 需要自己提供连接对象
3.batch():用于执行批处理

构造方法
QueryRunner() : 创建核心类,没有提供数据源,在进行具体操作时,需要手动提供Connection
普通方法
update(Connection conn , String sql , Object … params) : 使用提供的Connection,完成
DML语句
query(Connection conn , String sql , ResultSetHandler , Object … params) : 使用提供的Connection,执行DQL语句,并将查询结果封装到对象中。
QueryRunner实现添加、更新、删除操作
跳转到目录

update(String sql, Object… params) : 用来完成表数据的增加、删除、更新操作
queryRunner.update(sql):针对增加、删除、修改
queryRunner.query(sql,rsh):针对查询

 @Test
    public void insert() throws Exception {
        // 获取一个用来执行SQL语句对象
        QueryRunner qr = new QueryRunner(dataSource);
        String sql = "INSERT INTO stu(name, score) VALUES(?, ?)";
        Object[] params = {"百岁山", "50"};
        int count = qr.update(sql, params);
        System.out.println("执行成功:=" + count);
    }
    
@Test
 public static void insert(){
        QueryRunner qr = new QueryRunner();
        String sql = "insert into student values(112,'张三',19)";
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            int count = qr.update(conn,sql);
            System.out.println(count);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void update() throws Exception {
        QueryRunner qr = new QueryRunner(dataSource);
        String sql = "UPDATE stu SET name=?,score=? WHERE id=?";
        Object[] params = {"芒果99", "99", 6};
        int count = qr.update(sql, params);
        System.out.println(count);
    }

@Test
   public static void update(){
        QueryRunner qr = new QueryRunner();
        String sql = "update student set sage= sage+10 where sno = 110";
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            int count = qr.update(conn,sql);
            System.out.println(count);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
、
   @Test
    public void delete() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql = "DELETE from stu WHERE id = ?";
        Object[] params = {6};
        int r = queryRunner.update(sql, params);
        System.out.println(r);
    }
@Test
  public static void delete(){
        QueryRunner qr = new QueryRunner();
        String sql = "delete from student where sno = 112";
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            int count = qr.update(conn,sql);
            System.out.println(count);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

QueryRunner实现查询操作
跳转到目录

query(String sql, ResultSetHandler rsh, Object… params) 用来完成表数据的查询操作
参数:
String sql: sql语句,参数用?替代
ResultSetHandler<T> rsh: 结果集处理器,接口,必然传递实现类对象
Object … params: 可变参数,传递参数列表,数组.
作用: 给sql中?进行赋值.
ResultSetHandler结果集
跳转到目录

BeanHandler:将结果集中第一条记录封装到一个指定的JavaBean中。
BeanListHandler:将结果集中每一条记录封装到指定的JavaBean中,将这些JavaBean在封装到List集合中
ScalarHandler:它是用于单数据。例如select count(*) from表操作。
ColumnListHandler:将结果集中指定的列的值,封装到一个List集合中
JavaBean
跳转到目录
JavaBean就是一个类,在开发中常用于封装数据,。具有如下特性.

需要实现接口:java.io.Serializable ,通常实现接口这步骤省略了,不会影响程序。
提供私有字段:private 类型 字段名;
提供getter/setter方法:
提供无参构造
BeanHandler
跳转到目录

查询数据表结果集处理其中一种方式:
BeanHandler处理方式 将数据表的结果集第一行数据,封装成JavaBean类的对象
构造方法: BeanHandler(Class<T> type) 传递一个Class类型对象,将结果封装到哪个类的对象

 @Test
    public void testQueryBeanHandler() throws Exception{
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql = "SELECT * FROM stu WHERE id = ?";
        Object[] params = {5};
        // 查询并封装
        Stu pro = queryRunner.query(sql, new BeanHandler<>(Stu.class), params);
        System.out.println(pro);
    }

BeanListHandler
跳转到目录

查询数据表结果集处理其中一种方式:
BeanListHandler处理方式 将数据表的每一行数据,封装成JavaBean类对象 ,多行数据了,多个JavaBean对象,存储List集合.

   @Test
   public void testQueryBeanListHandler() throws Exception{
       QueryRunner queryRunner = new QueryRunner(DBCPUtil.getDataSource());
       String sql = "SELECT * FROM product";
       Object[] params = {};
       List pros = queryRunner.query(sql, new BeanListHandler(Product.class), params);
       for (Product pro : pros) {
           System.out.println(pro);
       }
   }

ScalarHander
跳转到目录

作用: 把查询结果的某一列,存储到List集合对象
构造方法:
public ScalarHandler(): 获取查询结果的第一行的第一列
public ScalarHandler(int index): 获取查询结果的第一行的第index列
public ScalarHandler(String ColumnName): 获取查询结果的第一行的ColumnName列

    @Test
    public void testQueryScalarHandler() throws Exception{
        QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
        String sql = "SELECT * FROM product WHERE pid = ?";
        Object[] params = {2};
        // 表示查询第二行的第二列
        Object o = queryRunner.query(sql, new ScalarHandler(2), params);
        System.out.println(o);
    }

ColumnListHandler
跳转到目录

获取数据库某一列的值, 通常用于汇总; 常用于 聚合函数

作用: 把查询结果的某一列,存储到List集合对象.用于 聚合函数
构造方法:
public ColumnListHandler(): 把第一列的内容存储到List集合中
public ColumnListHandler(int index): 把指定编号列的内容存储到List集合中
public ColumnListHandler(String ColumnName): 把指定列名对应列的内容存储到List集合中

    @Test
    public void testQueryColumnListHandler() throws Exception{
        QueryRunner queryRunner = new QueryRunner(C3P0Util.getDataSource());
        String sql = "SELECT * FROM product";
        // List list = queryRunner.query(sql, new ColumnListHandler());// 默认查询第一列
        // List list = queryRunner.query(sql, new ColumnListHandler(2)); // 查询关系表指定的第二列
        List list = queryRunner.query(sql, new ColumnListHandler("pname"));
        for (Object o : list) {
            System.out.println(o);
        }
    }
 
  

2.ResultSetHandler接口
1.ArrayHandler:将查询结果的第一行数据,保存到Object数组中

    public static void arrayHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student";

        try {
            Connection conn = JDBCUtils.getConnection();
            Object[] query = qr.query(conn, sql, new ArrayHandler());
            for(Object obj : query)
                System.out.print(obj);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

2.arrayListHandler: 将查询的结果,每一行先封装到Object数组中,然后将数据存入List集合

    public static void arrayListHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student";
        try {
            Connection conn = JDBCUtils.getConnection();
            List query = qr.query(conn, sql, new ArrayListHandler());
            for(Object[] objs : query){
                for (Object obj : objs){
                    System.out.print(obj+"  ");
                }
                System.out.println();
                DbUtils.closeQuietly(conn);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

3.BeanHandler: 将查询结果的第一行数据,封装到student对象

    public static void BeanHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student";
        try {
            Connection conn = JDBCUtils.getConnection();
            Student query = qr.query(conn, sql, new BeanHandler(Student.class));
            System.out.println(query);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

4.BeanLIstHandler: 将查询结果的每一行封装到student对象,然后再存入List集合

    public static void BeanListHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student";
        try {
            Connection conn = JDBCUtils.getConnection();
            List query = qr.query(conn, sql, new BeanListHandler(Student.class));
            for (Student student : query){
                System.out.println(student+"  ");
            }
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

5.ColumnListHandler:将查询结果的指定列的数据封装到List集合中

    public static void ColumnListHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student";
        try {
            Connection conn = JDBCUtils.getConnection();
            List sno = qr.query(conn, sql, new ColumnListHandler<>("sno"));
            for (Object obj : sno)
                System.out.println(obj);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 
  

6.ScalarHanlder:将结果集第一行的某一列放到某个对象中

    public static void ScalarHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select count(*) from student";
        try {
            Connection conn = JDBCUtils.getConnection();
            long query = qr.query(conn, sql, new ScalarHandler());
            System.out.println(query);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

7.MapHandler:将结果集中的第一行数据封装到一个Map

    public static void MapHandler(){
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student where sno = ?";
        try {
            Connection conn = JDBCUtils.getConnection();
            Map query = qr.query(conn, sql, new MapHandler(), 110);
            System.out.println(query);
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

8.MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List

    public static void MapListHandler() {
        QueryRunner qr = new QueryRunner();
        String sql = "select * from student where sno = ?";
        try {
            Connection conn = JDBCUtils.getConnection();
            List> query = qr.query(conn, sql, new MapListHandler(),110);
            for (Map map : query) {
                System.out.println(map);
            }
            DbUtils.closeQuietly(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

KeyedHandler:将结果集中的每一行数据都封装到一个Map里(List),再把这些map再存到一个map
public static void KeyedHandler(){
QueryRunner queryRunner = new QueryRunner();
String sql = “select * from student”;
Map>map = null;
try {
Connection conn = JDBCUtils.getConnection();
map = queryRunner.query(conn,sql,new KeyedHandler(“sname”));
for(Map.Entry> entry : map.entrySet()){
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
DbUtils.closeQuietly(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}

DBUtils类
它提供关于关闭资源以及事务rollback,commit操作。里面的方法都是静态的。

5 小结

跳转到目录
DBUtils工具

作用:简化JDBC的操作
DBUtils常用类与方法

QueryRunner 用来执行SQL语句对象

update(Connection conn, String sql, Object… params) 插入表记录、更新表记录、删除表记录
query(Connection conn, String sql, ResultSetHandler handler, Object… params) 查询表记录
ResultSetHandler 处理结果集的对象

BeanHandler:将结果集中第一条记录封装到一个指定的javaBean中。
BeanListHandler:将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
ScalarHandler:它是用于单数据。例如select count(*) from 表操作。
ColumnListHandler:将结果集中指定的列的字段值,封装到一个List集合中

public class Dbutils {

    private static DruidDataSource dataSource;

    @BeforeMethod
    public void testBefore() throws IOException, ClassNotFoundException, SQLException {
        Properties properties=new Properties();
        properties.load(Dbutils.class.getResourceAsStream("/jdbc.properties"));
        dataSource = new DruidDataSource();
        dataSource.configFromPropety(properties);
    }

    @AllArgsConstructor
    private static class InitRunnable implements Runnable {
        private CountDownLatch countDownLatch;
        @SneakyThrows
        @Override
        public void run() {
            System.out.println(new Date());
            Dbutils.insert();
            countDownLatch.countDown();
        }
    }

    @Test
    public void curent() throws InterruptedException {
        CountDownLatch countDownLatch=new CountDownLatch(1000);
        List workers = Stream
                .generate(() -> new Thread(new InitRunnable(countDownLatch)))
                .limit(1000)
                .collect(toList());
        workers.forEach(Thread::start);
        countDownLatch.await();
    }

    public static void insert() throws Exception {
        // 获取一个用来执行SQL语句对象
        QueryRunner qr = new QueryRunner(dataSource);
        String sql = "INSERT INTO stu(name, score) VALUES(?, ?)";
        Object[] params = {"百岁山", "50"};
        int count = qr.update(sql, params);
    }
}

你可能感兴趣的:(java,java,apache,数据库)