前言:

本文内容:使用IDEA连接数据库、JDBC操作事务、DBCP-C3P0连接池

推荐免费MySQL基础讲解视频:【狂神说Java】MySQL最新教程通俗易懂哔哩哔哩bilibili

MySQL笔记代码下载地址:

蓝奏云:下载地址 密码:joker

百度云:下载地址 提取码:agtc

使用IDEA连接数据库

连接步骤

164

163

162

修改数据库内容后一定要提交

161

编写SQL语句

160

JDBC操作事务

要么都成功,要么都失败

ACID原则

原子性:要么都完成,要么都不完成

一致性:总数不变

隔离性:多个进程互不干扰

持久性:一旦提交不可逆

隔离性的问题

脏读:一个事务读取了另一个没有提交的事务

不可重复读:在同一个事务内,重复读取表中的数据,表的数据发生改变

虚读:在一个事务内,读取到了别人插入的数据,导致前后读出结果不一致

例子

创建account表

1
2
3
4
5
6
7
8
9
10
-- 创建客户表
create table account(
`id` int primary key auto_increment,
`name` varchar(40),
`money` float
);

-- 测试数据
insert into account(`name`,`money`) values
('A',1000),('B',1000),('C',1000);

模拟事务进行转账

  1. 开启事务conn.setAutoCommit(false)
  2. 一组业务执行完毕,提交事务
  3. 可在catch语句中显示定义的回滚语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.jokerdig.lesson04;

import com.jokerdig.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @author Joker大雄
* @data 2022/3/23 - 12:29
**/
public class TestTransaction1 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
// 关闭数据库自动提交,自动开启事务
conn.setAutoCommit(false);
// 模拟A为B转账100
String sql1 = "update account set money=money-100 where name='A'";
ps=conn.prepareStatement(sql1);
ps.executeUpdate();
String sql2 = "update account set money=money+100 where name='B'";
ps=conn.prepareStatement(sql2);
ps.executeUpdate();
// 业务完毕 提交事务
conn.commit();
System.out.println("提交成功");
} catch (SQLException throwables) {
// 提交失败 就回滚数据
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}finally{
JDBCUtils.release(conn,ps,rs);
}
}
}

DBCP-C3P0连接池

数据库连接–执行完毕–释放

连接->释放 十分浪费资源

池化技术:准备一些预先的资源,过来就连接准备好的;

– 开启–业务员:等待–服务–关闭–

常用连接数若为10个

最小连接数:10个

最大连接数:15(业务最高承载上限)

等待超时:100ms

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

开源数据源实现

DBCP

C3P0

Druid:阿里巴巴

使用这些数据库连接池之后,在项目开法中就不需要编写连接数据库的代码。

DBCP

需要用到的jar包

commons-dbcp-版本号.jar

commons-pool-版本号.jar

commons-logging-版本号.jar

例子

dbcp.properties配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
driverClassName=com.mysql.cj.jdbc.Driver

url=jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&serverTimezone=UTC

username=root

password=123456

initialSize=10

maxActive=50

maxIdle=20

minIdle=5

maxWait=10000

connectionProperties=useUnicode=true;characterEncoding=UTF8

defaultAutoCommit=true

JDBCUtils_DBCP工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.jokerdig.utils;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
* @author Joker大雄
* @data 2022/3/23 - 13:20
**/
public class JDBCUtils_DBCP {

private static BasicDataSource dataS = null;

static{
try {
InputStream in = JDBCUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
Properties properties = new Properties();
properties.load(in);
// 创建数据源 工厂模式
dataS = BasicDataSourceFactory.createDataSource(properties);

} catch (Exception e) {
e.printStackTrace();
}
}

// 获取连接
public static Connection getConnection() throws SQLException {
return dataS.getConnection(); // 从数据源获取连接
}
// 释放资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
try {
if(resultSet!=null){
resultSet.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(statement!=null){
statement.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(connection!=null){
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}

测试查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.jokerdig.lesson05;

import com.jokerdig.utils.JDBCUtils_DBCP;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @author Joker大雄
* @data 2022/3/23 - 13:04
**/
public class TestDBCP {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils_DBCP.getConnection();
String sql = "select * from users where id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1,5);
rs = ps.executeQuery();
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+" name:"+rs.getString("name")+" password:"+rs.getString("password")+"\n");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
JDBCUtils_DBCP.release(conn,ps,rs);
}
}
}

C3P0

需要用到的jar包

c3p0-版本号.jar

mchange-commons-java-版本号.jar

例子

c3p0-config.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<named-config name="MySQL">
<!-- c3p0默认配置,下面还可以配置多个数据库 -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&amp;serverTimezone=UTC</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 初始化时获取连接数 -->
<property name="initialPoolSize">6</property>
<!-- 连接池中保留的最大连接数 -->
<property name="maxPoolSize">50</property>
<!-- 最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->
<property name="maxIdleTime">1000</property>
</named-config>
</c3p0-config>

JDBCUtils_C3P0工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.jokerdig.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.*;

/**
* @author Joker大雄
* @data 2022/3/21 - 13:17
**/
public class JDBCUtils_C3P0 {

private static DataSource dataS = null;

static{
try {
// 配置文件写法
dataS=new ComboPooledDataSource("MySQL");
// 代码也可一直接配置
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接
public static Connection getConnection() throws SQLException {
return dataS.getConnection();
}
// 释放资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
try {
if(resultSet!=null){
resultSet.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(statement!=null){
statement.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(connection!=null){
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}

测试查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.jokerdig.lesson05;

import com.jokerdig.utils.JDBCUtils_C3P0;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @author Joker大雄
* @data 2022/3/23 - 13:04
**/
public class TestC3P0 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils_C3P0.getConnection();
String sql = "select * from users where id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1,5);
rs = ps.executeQuery();
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+" name:"+rs.getString("name")+" password:"+rs.getString("password")+"\n");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
JDBCUtils_C3P0.release(conn,ps,rs);
}
}
}

结论

无论使用什么数据源,本质还是一样的,DataSource接口不会变;