文章目录

  • 1 介绍JDBC、数据库驱动
    • 1.1 JDBC
    • 1.2 数据库驱动
  • 2 使用JDBC
    • 2.1 JDBC下载地址
      • 方式一:maven坐标下载
      • 方式二:mysql官网方式下载
    • 2.2 导入数据库驱动
      • 方式一:maven坐标
      • 方式二:创建lib导入
    • 2.3 数据库数据
      • 1 创建数据库
      • 2 创建表
      • 3 插入数据
    • 2.4 代码实现
  • 3 JDBC中对象解释
    • 3.1 DriverManager类
    • 3.2 url
    • 3.3 Connection类
    • 3.4 Statement类
      • 1 CRUD操作-Create
      • 2 CRUD操作-Delete
      • 3 CRUD操作-Update
      • 4 CRUD操作-Read
    • 3.5 ResultSet类
      • 1 获取结果
      • 2 遍历
    • 3.6 释放资源
    • 3.7 工具类封装
    • 3.8 配置jdbc_mysql.properties文件
  • 4 CRUD练习
    • 4.1 添加(Create)
    • 4.2 查询(Read)
    • 4.3 更新(Update)
    • 4.4 删除(Delete)
  • 5 SQL注入问题
    • 5.1 产生原因
    • 5.2 PreparedStatement类
      • 1 快速入门
    • 5.3 CRUD练习
      • 1 添加(Create)
      • 2 查询(Read)
      • 3 更改(Update)
      • 4 删除(Delete)
  • 6 JDBC操作事务
    • 6.1 ACID原则
    • 6.2 持久性的问题
    • 6.3 流程介绍
    • 6.4 事务快速入门
      • 1 数据库表
      • 2 java代码
  • 7 数据库连接池
    • 7.1 介绍
      • 1 问题
      • 2 解决
      • 3 池化技术
    • 7.2 C3p0数据库连接池
      • 1 导入maven坐标
      • 2 创建c3p0-config.xml配置文件
      • 3 工具类
    • 7.3 Druid(德鲁伊)数据库连接池
      • 1 导入maven坐标
      • 2 创建druid.properties配置文件
      • 3 工具类
    • 7.4 工具类封装


学习视频来自于:秦疆(遇见狂神说)Bilibili地址
他的自学网站:kuangstudy

世界上只有少数人能够最终达到自己的理想


1 介绍JDBC、数据库驱动

1.1 JDBC

JDBC全称:java database connectivity,简称jdbc, 翻译就是 Java 数据库连接。

Java提供操作数据库的规范(接口),将规范给各大数据库厂商。

1.2 数据库驱动

各大数据库厂商实现规范(接口),广大Java程序员学习规范,就可以使用对应的数据库,只需要掌握JDBC既可操作数据库,不需要掌握和理解各大数据库厂商的具体实现

2 使用JDBC

2.1 JDBC下载地址

方式一:maven坐标下载

maven仓库

方式二:mysql官网方式下载

mysql官网下载地址

进入后在
👇
选择操作系统(Select Operating System:)
👇
下拉框中选择
👇
与平台无关(Platform lndependent)
👇
选择.zip格式下载

点击下载,甲骨文官网会提示登录或注册账号,点击下面不注册,开始下载。

下载后,解压mysql-connector-j-8.0.32.zip文件,进入解压后的文件mysql-connector-j-8.0.32,找到mysql-connector-j-8.0.32.jar包,复制到项目中资源目录即可

2.2 导入数据库驱动

方式一:maven坐标

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.20</version>
</dependency>

方式二:创建lib导入

在项目下新建lib文件夹,将数据库驱动放入,鼠标右键点击选择添加为库(Add as Library…)

2.3 数据库数据

1 创建数据库

-- 创建库
CREATE DATABASE IF NOT EXISTS `jdbc_Study` CHARACTER SET utf8;

-- 使用库
USE `jdbc_Study`;

2 创建表

-- 创建表
CREATE TABLE IF NOT EXISTS `users`(
	`id` INT PRIMARY KEY,
	`name` VARCHAR(40),
	`password` VARCHAR(40),
	`email` VARCHAR(60),
	`birthday` DATE
);

3 插入数据

-- 插入数据
INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`) VALUES
(1,'马钰',123456,'mayu@sina','1123-01-04'),
(2,'丘处机',123456,'qiuchuji@sina','1148-05-04'),
(3,'谭处端',123456,'tanchuduan@sina','1123-03-01'),
(4,'王处一',123456,'wangchuyi@sina','1142-10-04'),
(5,'郝大通',123456,'haodatong@sina','1140-01-24'),
(6,'刘处玄',123456,'liuchuxuan@sina','1147-10-04'),
(7,'孙不二',123456,'sunbuer@sina','1119-10-04');

2.4 代码实现

// 1 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");

// 2 用户信息
String url = "jdbc:mysql://localhost:3306/jdbc_Study?userUnicode=true&characterEncoding=utf8&useSSl=true&serverTimezone=GMT%2B8";
String username = "root"; // 写自己数据库用户
String password = "root"; // 写自己数据库密码

// 3 连接数据库,获取connection对象,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);

// SQL语句
String sql = "select * from users";

// 4 获取执行sql对象
Statement statement = connection.createStatement();

// 5 使用执行sql对象去执行sql,有结果集就返回结果集
ResultSet resultSet = statement.executeQuery(sql);

// 遍历结果集(查询有结果集,增删改没有结果集)
while (resultSet.next()) {
    System.out.println(
            resultSet.getInt(1) + " " +
            resultSet.getString(2) + " " +
            resultSet.getString(3) + " " +
            resultSet.getString(4) + " " +
            resultSet.getString(5));
}

// 6 释放连接
if (resultSet != null) {
   resultSet.close();
}
if (statement != null) {
   statement.close();
}
if (connection != null) {
   connection.close();
}

3 JDBC中对象解释

3.1 DriverManager类

管理数据库中的所有驱动程序

// java.sql.DriverManager.registerDriver(new Driver());
Class.forName(driver);// 固定写法,通过反射初始化类,静态代码块执行以上代码

// 建立连接,获取代表数据库的Connection对象
Connection connection = DriverManager.getConnection(url, username, password);

3.2 url

数据库连接

// jdbc:mysql 协议
// localhost:3306 主机地址:端口号
// jdbc_Study 数据库名称
// userUnicode=true 使用Unicode编码,支持中文
// characterEncoding=utf8 字符集编码
// useSSl=true 使用安全链接
// serverTimezone=GMT%2B8 时区,写法不唯一(Asia/Shanghai)
String url = "jdbc:mysql://localhost:3306/jdbc_Study?userUnicode=true&characterEncoding=utf8&useSSl=true&serverTimezone=GMT%2B8";

3.3 Connection类

数据库操作对象

// Connection代表数据库,可以获取或更改与数据库有关的信息
// 事务关闭自动提交
connection.setAutoCommit(false);
// 事务提交
connection.commit();
// 事务回滚
connection.rollback();

3.4 Statement类

jdbc中的statement对象用于向数据库发送sql语句想完成对数据库的增删改查只需要通过这个对象向数据库发送增删改查语句即可

Statement 对象的executeUpdate()方法,用于向数据库发送增、删、改的sql语句,executeUpdate执行完,将返回一个成功执行的条数。

Statement 对象的executeQuery()方法,用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。

// 获取执行sql对象
Statement statement = connection.createStatement();
// 执行sql语句
statement.execute(sql);
// 执行查询
statement.executeQuery(sql);
// 执行增、删、改
statement.executeUpdate(sql);
// 批处理
statement.executeBatch();

1 CRUD操作-Create

Statement statement = connection.createStatement();
String sql = "insert into users (...) values (...)";
int num =  statement.executeUpdate(sql);
if(num > 0){
 System.out.println("添加成功");
}

2 CRUD操作-Delete

Statement statement = connection.createStatement();
String sql = "delete from users where id = 1";
int num =  statement.executeUpdate(sql);
if(num > 0){
 System.out.println("删除成功");
}

3 CRUD操作-Update

Statement statement = connection.createStatement();
String sql = "update users set 列=值 where id = 1";
int num =  statement.executeUpdate(sql);
if(num > 0){
 System.out.println("更新成功");
}

4 CRUD操作-Read

Statement statement = connection.createStatement();
String sql = "select * from users";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
// 根据获取列的书库类型,分别调用rs的响应方法映射到java对象中
}

3.5 ResultSet类

结果集对象

1 获取结果

// 5.使用执行sql对象去执行sql,有结果集就返回结果集
ResultSet resultSet = statement.executeQuery(sql);
// 结果集对象,封装了我们全部的查询结果
resultSet.getObject(); // 在不知道列类型的情况下使用
// 知道类型就直接指定类型,更加准确
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();

2 遍历

resultSet.beforeFirst(); // 移动到最前面
resultSet.afterLast(); // 移动到最后面
resultSet.next(); // 移动到下一个
resultSet.previous(); // 移动到上一个
resultSet.absolute(row); // 移动到制定行

3.6 释放资源

使用对象中的close方法,关闭资源

// 必须有的步骤,资源不释放,非常影响程序性能
resultSet.close();
statement.close();
connection.close();

3.7 工具类封装

将重复的步骤封装,使用时便于调用

public class JDBCUtils {
    static String driver = null;
    static String url = null;
    static String username = null;
    static String password = null;

    static {
        try {
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc_mysql.properties");
            Properties properties = new Properties();
            properties.load(is);

            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            // 1.加载驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }

    // 关闭资源
    public static void close(Statement statement, Connection connection) {
        // 释放连接
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {
        // 释放连接
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close(statement, connection);
    }
}

3.8 配置jdbc_mysql.properties文件

可以设置多个配置文件以对应不同数据库

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc_Study?userUnicode=true&characterEncoding=utf8&useSSl=true&serverTimezone=GMT%2B8
username=root
password=root

4 CRUD练习

4.1 添加(Create)

// 添加方法
private static void Create() {
    // 提升作用于
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {
        // 通过工具类获取connection
        connection = JDBCUtils.getConnection();
        String sql = "insert into `users` (`id`,`name`,`password`,`email`,`birthday`) values (7,'孙不二',123456,'sunbuer@sina','1119-10-04')";
        // 获取执行sql对象
        statement = connection.createStatement();
        // 使用执行sql对象去执行sql,有结果集就返回结果集
        int num = statement.executeUpdate(sql);
        // 执行结果
        if (num > 0) {
            System.out.println("添加成功");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        JDBCUtils.close(resultSet, statement, connection);
    }
}

4.2 查询(Read)

private static void Read() {
    // 提升作用于
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {
        // 通过工具类获取connection
        connection = JDBCUtils.getConnection();
        String sql = "select * from users";
        // 获取执行sql对象
        statement = connection.createStatement();
        // 使用执行sql对象去执行sql,有结果集就返回结果集
        resultSet = statement.executeQuery(sql);
        // 遍历结果集
        while (resultSet.next()) {
            System.out.println(
                resultSet.getInt(1) + " " +
                resultSet.getString(2) + " " +
                resultSet.getString(3) + " " +
                resultSet.getString(4) + " " +
                resultSet.getString(5));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        JDBCUtils.close(resultSet, statement, connection);
    }
}

4.3 更新(Update)

// 更新方法
private static void Update() {
    // 提升作用于
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {
        // 通过工具类获取connection
        connection = JDBCUtils.getConnection();
        String sql = "update `users` set `password`=654321 where id = 1";
        // 获取执行sql对象
        statement = connection.createStatement();
        // 使用执行sql对象去执行sql,有结果集就返回结果集
        int num = statement.executeUpdate(sql);
        // 执行结果
        if (num > 0) {
            System.out.println("更新成功");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        JDBCUtils.close(resultSet, statement, connection);
    }
}

4.4 删除(Delete)

// 删除方法
private static void Delete() {
    // 提升作用于
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {
        // 通过工具类获取connection
        connection = JDBCUtils.getConnection();
        String sql = "delete from `users` where `id` = 7";
        // 获取执行sql对象
        statement = connection.createStatement();
        // 使用执行sql对象去执行sql,有结果集就返回结果集
        int num = statement.executeUpdate(sql);
        // 执行结果
        if (num > 0) {
            System.out.println("删除成功");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        JDBCUtils.close(resultSet, statement, connection);
    }
}

5 SQL注入问题

5.1 产生原因

通过操作输入修改后台SQL语句,达到代码功能变化的。

-- 登录SQL代码
SELECT * FROM `users` WHERE `email`='qiuchuji@sina' and `password`='123456';
// 登录java代码
public class Login {
    public static void main(String[] args) {
        // 页面获取用户名和密码
        String email = "sunbuer@sina";
        String password = "123456";
        // 调用登录方法
        LoginDemo(email, password);
    }

    public static void LoginDemo(String email, String password) {
        // 提升作用于
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            // 通过工具类获取connection
            connection = JDBCUtils.getConnection();
            // 在sql中拼接传入的用户名和密码
            String sql = "select * from `users` where `email` = '" + email + "'and `password` = '" + password + "'";
            // 获取执行sql对象
            statement = connection.createStatement();
            // 使用执行sql对象去执行sql,有结果集就返回结果集
            resultSet = statement.executeQuery(sql);
            // 打印登录账号信息
            while (resultSet.next()) {
                System.out.println(
                    resultSet.getInt(1) + " " +
                    resultSet.getString(2) + " " +
                    resultSet.getString(3) + " " +
                    resultSet.getString(4) + " " +
                    resultSet.getString(5));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            JDBCUtils.close(resultSet, statement, connection);
        }
    }
}

如果将登录的用户名那个和密码改成

// 页面获取用户名和密码
String email = "' OR '1=1";
String password = "' OR '1=1";

直接可以获取多个用户信息

-- 登录代码
SELECT * FROM `users` WHERE `email`='' OR '1=1' and `password`='' OR '1=1';

代码运行结果:查询到表所有信息

+----+--------+----------+---------------------+------------+
| id | name   | password | email               | birthday   |
+----+--------+----------+---------------------+------------+
|  1 | 马钰   | 123456   | mayu@sina       | 1123-01-04 |
|  2 | 丘处机 | 123456   | qiuchuji@sina   | 1148-05-04 |
|  3 | 谭处端 | 123456   | tanchuduan@sina | 1123-03-01 |
|  4 | 王处一 | 123456   | wangchuyi@sina  | 1142-10-04 |
|  5 | 郝大通 | 123456   | haodatong@sina  | 1140-01-24 |
|  6 | 刘处玄 | 123456   | liuchuxuan@sina | 1147-10-04 |
|  7 | 孙不二 | 123456   | sunbuer@sina    | 1119-10-04 |
+----+--------+----------+---------------------+------------+
7 rows in set (0.01 sec)

5.2 PreparedStatement类

java中PreparedStatement对象可以屏蔽SQL注入问题。

PreparedStatement继承Statement。

相当于在Statement上做扩展

1 快速入门

String sql = "INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?);";
// 获取执行sql对象,预编译
statement = connection.prepareStatement(sql);
// 插入?对应的值
statement.setInt(1, 7);
statement.setString(2, "孙不二");
statement.setString(3, "123456");
statement.setString(4, "sunbuer@sina");
// sql.Date和util.Date不一样
// new Date().getTime()获取一个时间戳
statement.setDate(5, new java.sql.Date(new Date().getTime()));
// 使用执行sql对象去执行sql,有结果集就返回结果集
int num = statement.executeUpdate();
if (num > 0) {
    System.out.println("添加成功");
}

5.3 CRUD练习

1 添加(Create)

String sql = "INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?);";
// 获取执行sql对象,预编译
statement = connection.prepareStatement(sql);
// 插入?对应的值
statement.setInt(1, 7);
statement.setString(2, "孙不二");
statement.setString(3, "123456");
statement.setString(4, "sunbuer@sina");
// sql.Date和util.Date不一样
// new Date().getTime()获取一个时间戳
statement.setDate(5, new java.sql.Date(new Date().getTime()));
// 使用执行sql对象去执行sql,有结果集就返回结果集
int num = statement.executeUpdate();
if (num > 0) {
    System.out.println("添加成功");
}

2 查询(Read)

String sql = "select * from users;";
// 获取执行sql对象
statement = connection.prepareStatement(sql);
// 使用执行sql对象去执行sql,有结果集就返回结果集
resultSet = statement.executeQuery();
// 遍历结果集
while (resultSet.next()) {
    System.out.println(
        resultSet.getInt(1) + " " +
        resultSet.getString(2) + " " +
        resultSet.getString(3) + " " +
        resultSet.getString(4) + " " +
        resultSet.getString(5));
}

3 更改(Update)

String sql = "UPDATE `users` set `birthday` = ? WHERE `id` = ?;";
// 获取执行sql对象,预编译
statement = connection.prepareStatement(sql);
// 插入?对应的值
statement.setDate(1, java.sql.Date.valueOf("1119-10-04"));
statement.setInt(2, 7);
// 使用执行sql对象去执行sql,有结果集就返回结果集
int num = statement.executeUpdate();
if (num > 0) {
    System.out.println("修改成功");
}

4 删除(Delete)

String sql = "DELETE FROM `users` WHERE `id` = ?;";
// 获取执行sql对象,预编译
statement = connection.prepareStatement(sql);
// 插入?对应的值
statement.setInt(1, 7);
// 使用执行sql对象去执行sql,有结果集就返回结果集
int num = statement.executeUpdate();
if (num > 0) {
    System.out.println("删除成功");
}

6 JDBC操作事务

6.1 ACID原则

要么都成功要么都失败

原子性:执行一组业务全部成功,或者全部失败。
一致性:执行前后数量变换一直。
隔离性:多个业务相互不干扰。
持久性:一旦提交不可逆,持久化到数据库。

6.2 持久性的问题

脏读:一个事务读取了另一个没有提交的事务。
虚读(幻读):在一个事务内,读取到了被人插入的数据,导致前后读出来的结果不一致。
不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了改变。

6.3 流程介绍

将事务自动提交关闭,开始写执行代码

connection.setAutoCommit(false); //false:关闭自动提交

程序执行正常,事务提交

connection.commit();

程序执行阶段出现异常,事务回滚

connection.rollback();

6.4 事务快速入门

1 数据库表

-- 表结构
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(40) DEFAULT NULL,
  `money` float DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- 数据
INSERT INTO `account` VALUES ('1', 'a', '1000');
INSERT INTO `account` VALUES ('2', 'b', '1000');
INSERT INTO `account` VALUES ('3', 'c', '1000');
INSERT INTO `account` VALUES ('4', 'd', '1000');

2 java代码

Connection connection = null;
PreparedStatement statement = null;
// 金额减少
String sql1 = "update `account` set `money` = `money` - ? where id = ?";
// 金额增加
String sql2 = "update `account` set `money` = `money` + ? where id = ?";
try {
	// 获取connection对象
    connection = JDBCUtils.getConnection();
    // 开启手动提交
    connection.setAutoCommit(false);
    // 执行金额较少
    statement = connection.prepareStatement(sql1);
    statement.setInt(1, 200);
    statement.setInt(2, 1);
    statement.executeUpdate();
    // 执行金额增加
    statement = connection.prepareStatement(sql2);
    statement.setInt(1, 200);
    statement.setInt(2, 2);
    int num = statement.executeUpdate();
    // 判断执行结果
    if (num > 0) {
        System.out.println("执行成功");
    }
    // 手动提交事务
    connection.commit();
} catch (SQLException e) {
    try {
    // 有异常事务回滚,如果不写也会隐式的自动回滚
        connection.rollback();
    } catch (SQLException ex) {
        ex.printStackTrace();
    }
    e.printStackTrace();
} finally {
	// 释放资源
    JDBCUtils.close(statement, connection);
}

7 数据库连接池

7.1 介绍

1 问题

每次创建数据库对象(Connection)需要花费一定的时间,当同一时间大量用户访问网站,创建过程非常耗时,页面加载慢,用户体验差。

2 解决

在启动服务器的时候,就创建一些Connection,并保存起来,每当有用户访问,就可以直接获取,不需要等待,如果自己写耗时费力,效果因人而异,不如直接使用市面上的成熟的连接池。

例如:DBCP-C3p0数据库连接池,Druid(德鲁伊)数据库连接池。

3 池化技术

准备一些预先的资源,有连接过来就直接使用。

编写连接池: 实现一个接口DataSource

7.2 C3p0数据库连接池

1 导入maven坐标

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.5</version>
</dependency>

2 创建c3p0-config.xml配置文件

文件名字改成别的c3p0会找不到资源文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_Study?userUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true&amp;serverTimezone=GMT%2B8
        </property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!-- 初始化时连接数,default: 10 -->
        <property name="initialPoolSize">10</property>
        <!--定义申请数据库连接池增量 -->
        <property name="acquireIncrement">2</property>
        <!-- 连接池中最大连接数,default: 100 -->
        <property name="maxPoolSize">40</property>
        <!-- 连接池中最小连接数,default: 10 -->
        <property name="minPoolSize">10</property>
    </default-config>

    <named-config name="mySource">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <!--        -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/user?userUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true&amp;serverTimezone=GMT%2B8
        </property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!--定义初始化容量 -->
        <property name="initialPoolSize">20</property>
        <!--定义申请数据库连接池增量 -->
        <property name="acquireIncrement">2</property>
        <!--定义数据库连接池最大容量 -->
        <property name="maxPoolSize">40</property>
        <!--定义数据库连接池最小容量(剩余量) -->
        <property name="minPoolSize">10</property>
    </named-config>
</c3p0-config>

3 工具类

// C3P0连接池(数据源)
public static ComboPooledDataSource dataSource = null;
// 类加载创建C3P0连接池对象
static {
    dataSource = new ComboPooledDataSource();
}
// 从连接池获取连接对象
public static Connection getConnection() throws SQLException {
    return dataSource.getConnection();
}
// 释放资源不变

7.3 Druid(德鲁伊)数据库连接池

1 导入maven坐标

<!-- https://mvnrepository/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
</dependency>

2 创建druid.properties配置文件

名字随便

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc_Study?userUnicode=true&characterEncoding=utf8&useSSl=true&serverTimezone=GMT%2B8
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000

3 工具类

// Druid连接池(数据源)
private static DataSource dataSource = null;

static {
    // druid连接池配置
    Properties properties = new Properties();
    InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
    try {
        properties.load(is);
        dataSource = DruidDataSourceFactory.createDataSource(properties);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

// 获取连接
public static Connection getConnection() throws SQLException {
    return dataSource.getConnection();
}

// 释放资源不变

7.4 工具类封装

public class BaseDao {
    private final static DataSource dataSource;

    // 静态代码块,类加载时就初始化
    static {
        try {
            // 通过类加载器读取对应的资源
            InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("mysql.properties");
            Properties pro = new Properties();
            pro.load(is);
            // 加载连接池
            dataSource = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取数据库连接
     *
     * @return Connection
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /**
     * 获取数据库连接池
     *
     * @return dataSource
     */
    public static DataSource getdataSource() {
        return dataSource;
    }

    /**
     * 增删改公共类
     *
     * @param sql
     * @param params
     * @param conn
     * @param stat
     * @return boolean
     * @throws SQLException
     */
    public static int execute(String sql, Object[] params, Connection conn, PreparedStatement stat) throws SQLException {
        stat = conn.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            stat.setObject(i + 1, params[i]);
        }
        return stat.executeUpdate();
    }

    /**
     * 查询公共类
     *
     * @param sql
     * @param params
     * @param conn
     * @param stat
     * @return ResultSet
     * @throws SQLException
     */
    public static ResultSet executeQuery(String sql, Object[] params, Connection conn, PreparedStatement stat) throws SQLException {
        stat = conn.prepareStatement(sql);
        if (params != null) {
            for (int i = 0; i < params.length; i++) {
                stat.setObject(i + 1, params[i]);
            }
        }
        return stat.executeQuery();
    }


    /**
     * 释放资源
     *
     * @param rs
     * @param stat
     * @param conn
     * @return boolean
     */
    public static boolean remove(ResultSet rs, Statement stat, Connection conn) {
        boolean flag = true;
        if (rs != null) {
            try {
                rs.close();
                rs = null;// GC回收
            } catch (SQLException e) {
                flag = false;
                throw new RuntimeException(e);
            }
        }
        if (stat != null) {
            try {
                stat.close();
                stat = null;// GC回收
            } catch (SQLException e) {
                flag = false;
                throw new RuntimeException(e);
            }
        }
        if (conn != null) {
            try {
                conn.close();
                conn = null;// GC回收
            } catch (SQLException e) {
                flag = false;
                throw new RuntimeException(e);
            }
        }
        return flag;
    }
}

更多推荐

数据库驱动和JDBC