Java之JDBC之Druid及Apache—DBUtils

文章目录

      • 1、JDBC之Druid(德鲁伊)
        • 1.1、 应用实例
        • 1.2、将 JDBCUtils 工具类改成 Druid(德鲁伊)实现
      • 2、Apache—DBUtils
        • 2.1、先分析一个问题
        • 2.2、基本介绍
        • 2.3、应用实例
        • 2.4、表和 JavaBean 的类型映射关系

1、JDBC之Druid(德鲁伊)

1.1、 应用实例

使用代码实现Druid(德鲁伊)数据库连接池

Druid_.java

package jdbc.datasource;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;

/**
 * druid 的使用
 */
@SuppressWarnings({"all"})
public class Druid_ {
    @Test
    public void testDruid() throws Exception {
        // 1. 加入 Druid jar 包
        // 2. 加入 配置文件 druid.properties, 将该文件拷贝项目的 src 目录
        // 3. 创建 Properties 对象, 读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\druid.properties"));
        // 4. 创建一个指定参数的数据库连接池, Druid 连接
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500000; i++) {
            Connection connection = dataSource.getConnection();
            // System.out.println(connection.getClass());  // class com.alibaba.druid.pool.DruidPooledConnection
            // System.out.println("连接成功!");
            connection.close();
        }
        long end = System.currentTimeMillis();
        // druid 连接池 操作 500000 耗时=561
        System.out.println("druid 连接池 操作 500000 耗时=" + (end - start));
    }
}

druid.properties

#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user_db?rewriteBatchedStatements=true
username=root
password=root
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000

1.2、将 JDBCUtils 工具类改成 Druid(德鲁伊)实现

通过德鲁伊数据库连接池获取连接对象

JDBCUtilsByDruid.java

package jdbc.datasource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 基于 druid 数据库连接池的工具类
 */
@SuppressWarnings({"all"})
public class JDBCUtilsByDruid {
    private static DataSource ds;

    // 在静态代码块完成 ds 初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 编写 getConnection 方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    // 关闭连接, 再次强调: 在数据库连接池技术中, close 不是真的断掉连接
    // 而是把使用的 Connection 对象放回连接池
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }

            if (statement != null) {
                statement.close();
            }

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

JDBCUtilsByDruid_USE.java

package jdbc.datasource;

import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;

@SuppressWarnings({"all"})
public class JDBCUtilsByDruid_USE {
    public static void main(String[] args) {
        System.out.println(new JDBCUtilsByDruid_USE().testSelectToArrayList());
    }

    @Test
    public void testSelect() {
        System.out.println("使用 druid 方式完成");
        // 1. 得到连接
        Connection connection = null;
        // 2. 组织一个 sql
        String sql = "select * from actor where id >= ?";
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        // 3. 创建 PreparedStatement 对象
        try {
            connection = JDBCUtilsByDruid.getConnection();
            System.out.println(connection.getClass());  // 运行类型 com.alibaba.druid.pool.DruidPooledConnection
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);//给?号赋值
            // 执行, 得到结果集
            set = preparedStatement.executeQuery();
            // 遍历该结果集
            while (set.next()) {
                int id = set.getInt("id");
                String name = set.getString("name");  // getName()
                String sex = set.getString("sex");  // getSex()
                Date borndate = set.getDate("borndate");
                String phone = set.getString("phone");
                System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            JDBCUtilsByDruid.close(set, preparedStatement, connection);
        }
    }

    // 使用土方法来解决 ResultSet =封装=> Arraylist
    @Test
    public ArrayList<Actor> testSelectToArrayList() {
        System.out.println("使用 druid 方式完成");
        // 1. 得到连接
        Connection connection = null;
        // 2. 组织一个 sql
        String sql = "select * from actor where id >= ?";
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        ArrayList<Actor> list = new ArrayList<>();  // 创建 ArrayList 对象,存放 actor 对象
        // 3. 创建 PreparedStatement 对象
        try {
            connection = JDBCUtilsByDruid.getConnection();
            System.out.println(connection.getClass());  // 运行类型 com.alibaba.druid.pool.DruidPooledConnection
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);  // 给?号赋值
            //执行, 得到结果集
            set = preparedStatement.executeQuery();
            // 遍历该结果集
            while (set.next()) {
                int id = set.getInt("id");
                String name = set.getString("name");//getName()
                String sex = set.getString("sex");//getSex()
                Date borndate = set.getDate("borndate");
                String phone = set.getString("phone");
                // 把得到的 resultset 的记录, 封装到 Actor 对象, 放入到 list 集合
                list.add(new Actor(id, name, sex, borndate, phone));
            }
            System.out.println("list 集合数据=" + list);
            for (Actor actor : list) {
                System.out.println("id=" + actor.getId() + "\t" + actor.getName());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            JDBCUtilsByDruid.close(set, preparedStatement, connection);
        }
        // 因为 ArrayList 和 connection 没有任何关联,所以该集合可以复用.
        return list;
    }
}

Actor.java

package jdbc.datasource;

import java.util.Date;


public class Actor {  // Javabean, POJO, Domain对象

    private Integer id;
    private String name;
    private String sex;
    private Date borndate;
    private String phone;

    public Actor() {  // 一定要给一个无参构造器[反射需要]
    }

    public Actor(Integer id, String name, String sex, Date borndate, String phone) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.borndate = borndate;
        this.phone = phone;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBorndate() {
        return borndate;
    }

    public void setBorndate(Date borndate) {
        this.borndate = borndate;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "\nActor{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", borndate=" + borndate +
                ", phone='" + phone + '\'' +
                '}';
    }
}

2、Apache—DBUtils

2.1、先分析一个问题

  1. 关闭connection 后,resultSet 结果集无法使用
  2. resultSet 不利于数据的管理

示意图
Java之JDBC之Druid及Apache—DBUtils_第1张图片

// 使用土方法来解决 ResultSet =封装=> Arraylist
@Test
public ArrayList<Actor> testSelectToArrayList() {
    System.out.println("使用 druid 方式完成");
    // 1. 得到连接
    Connection connection = null;
    // 2. 组织一个 sql
    String sql = "select * from actor where id >= ?";
    PreparedStatement preparedStatement = null;
    ResultSet set = null;
    ArrayList<Actor> list = new ArrayList<>();  // 创建 ArrayList 对象,存放 actor 对象
    // 3. 创建 PreparedStatement 对象
    try {
        connection = JDBCUtilsByDruid.getConnection();
        System.out.println(connection.getClass());  // 运行类型 com.alibaba.druid.pool.DruidPooledConnection
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, 1);  // 给?号赋值
        //执行, 得到结果集
        set = preparedStatement.executeQuery();
        // 遍历该结果集
        while (set.next()) {
            int id = set.getInt("id");
            String name = set.getString("name");//getName()
            String sex = set.getString("sex");//getSex()
            Date borndate = set.getDate("borndate");
            String phone = set.getString("phone");
            // 把得到的 resultset 的记录, 封装到 Actor 对象, 放入到 list 集合
            list.add(new Actor(id, name, sex, borndate, phone));
        }
        System.out.println("list 集合数据=" + list);
        for (Actor actor : list) {
            System.out.println("id=" + actor.getId() + "\t" + actor.getName());
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        JDBCUtilsByDruid.close(set, preparedStatement, connection);
    }
    // 因为 ArrayList 和 connection 没有任何关联,所以该集合可以复用.
    return list;
}

2.2、基本介绍

Java之JDBC之Druid及Apache—DBUtils_第2张图片

2.3、应用实例

Java之JDBC之Druid及Apache—DBUtils_第3张图片
DBUtils_USE.java

package jdbc.datasource;

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.ScalarHandler;
import org.junit.jupiter.api.Test;

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

@SuppressWarnings({"all"})
public class DBUtils_USE {
    // 使用apache-DBUtils 工具类 + druid 完成对表的crud操作
    @Test
    public void testQueryMany() throws SQLException {  // 返回结果是多行的情况
        // 1. 得到 连接 (druid)
        Connection connection = JDBCUtilsByDruid.getConnection();
        // 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
        // 3. 创建 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        // 4. 就可以执行相关的方法, 返回ArrayList 结果集
        // String sql = "select * from actor where id >= ?";
        // 注意: sql 语句也可以查询部分列
        String sql = "select id, name from actor where id >= ?";
        // 解读
        // (1) query 方法就是执行sql 语句, 得到resultset ---封装到 --> ArrayList 集合中
        // (2) 返回集合
        // (3) connection: 连接
        // (4) sql : 执行的sql语句
        // (5) new BeanListHandler<>(Actor.class): 在将resultset -> Actor 对象 -> 封装到 ArrayList
        //    底层使用反射机制 去获取Actor 类的属性,然后进行封装
        // (6) 1 就是给 sql 语句中的? 赋值,可以有多个值,因为是可变参数Object... params
        // (7) 底层得到的resultset ,会在query 关闭, 关闭PreparedStatment
        /**
         * 分析 queryRunner.query方法:
         * public  T query(Connection conn, String sql, ResultSetHandler rsh, Object... params) throws SQLException {
         *         PreparedStatement stmt = null;//定义PreparedStatement
         *         ResultSet rs = null;//接收返回的 ResultSet
         *         Object result = null;//返回ArrayList
         *
         *         try {
         *             stmt = this.prepareStatement(conn, sql);//创建PreparedStatement
         *             this.fillStatement(stmt, params);//对sql 进行 ? 赋值
         *             rs = this.wrap(stmt.executeQuery());//执行sql,返回resultset
         *             result = rsh.handle(rs);//返回的resultset --> arrayList[result] [使用到反射,对传入class对象处理]
         *         } catch (SQLException var33) {
         *             this.rethrow(var33, sql, params);
         *         } finally {
         *             try {
         *                 this.close(rs);//关闭resultset
         *             } finally {
         *                 this.close((Statement)stmt);//关闭preparedstatement对象
         *             }
         *         }
         *
         *         return result;
         *     }
         */
        List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
        System.out.println("输出集合的信息");
        for (Actor actor : list) {
            System.out.print(actor);
        }

        //释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }

    // apache-dbutils + druid 完成 返回的结果是单行记录(单个对象)
    @Test
    public void testQuerySingle() throws SQLException {
        // 1. 得到 连接 (druid)
        Connection connection = JDBCUtilsByDruid.getConnection();
        // 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
        // 3. 创建 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        // 4. 就可以执行相关的方法, 返回单个对象
        String sql = "select * from actor where id = ?";
        // 解读
        // 因为我们返回的单行记录<--->单个对象, 使用的Hander 是 BeanHandler
        Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 1);
        System.out.println(actor);

        // 释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }

    // apache-dbutils + druid 完成查询结果是单行单列-返回的就是object
    @Test
    public void testScalar() throws SQLException {
        // 1. 得到 连接 (druid)
        Connection connection = JDBCUtilsByDruid.getConnection();
        // 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
        // 3. 创建 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        // 4. 就可以执行相关的方法,返回单行单列 , 返回的就是Object
        String sql = "select name from actor where id = ?";
        // 解读: 因为返回的是一个对象, 使用的handler 就是 ScalarHandler
        Object obj = queryRunner.query(connection, sql, new ScalarHandler(), 2);
        System.out.println(obj);

        // 释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }

    // apache-dbutils + druid 完成 dml (update, insert ,delete)
    @Test
    public void testDML() throws SQLException {
        // 1. 得到 连接 (druid)
        Connection connection = JDBCUtilsByDruid.getConnection();
        // 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
        // 3. 创建 QueryRunner
        QueryRunner queryRunner = new QueryRunner();

        // 4. 这里组织sql 完成 update, insert delete
        // String sql = "update actor set name = ? where id = ?";
        // String sql = "insert into actor values(null, ?, ?, ?, ?)";
        String sql = "delete from actor where id = ?";

        // 解读
        // (1) 执行dml 操作是 queryRunner.update()
        // (2) 返回的值是受影响的行数 (affected: 受影响)
        // int affectedRow = queryRunner.update(connection, sql, "林青霞", "女", "1966-10-10", "116");
        int affectedRow = queryRunner.update(connection, sql, 1);
        System.out.println(affectedRow > 0 ? "执行成功" : "执行没有影响到表");

        // 释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }
}

2.4、表和 JavaBean 的类型映射关系

Java之JDBC之Druid及Apache—DBUtils_第4张图片

你可能感兴趣的:(java,java,apache,sql)