19JavaSE操作数据库总结

一、JDBC

JDBC有关的类:都在java.sql 和 javax.sql 包下.

1.数据准备

这里假设已经在数据库中新建立了mydb4数据库,并且也插入了一些数据,

 并且还需要导入一个jar包mysql-connector-java-5.1.17jar(可从官网下载)

2.JDBC 编程步骤

**步骤1:**装载驱动    DriverManager.registerDriver(new Driver());   

 tips:在装载驱动的时候推荐使用**Class.forName(“com.mysql.jdbc.Driver”);**

​ 一、查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
二、程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。**

**步骤2:建**立连接    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb4", "root", "111");

 步骤3:操作数据库
1
2
3
4
5
6
7
8
9
10
11
 Statement statement = conn.createStatement();

ResultSet rs = statement.executeQuery(sql);

while (rs.next()) {

 System.out.println(rs.getString("username"));

 System.out.println(rs.getString("email"));

}

步骤4:释放资源

1
2
3
4
5
rs.close();

statement.close();

conn.close();

3.一步到位的操作方式

(更加面向对象&&解决SQL注入问题):

将重复的内容 提取到JDBCUtils工具类中:

提供两种版本分别是硬编码和软编码

硬编码(信息写入到程序中):

JDBCUtils工具类

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
public class JDBCUtils {

private static final String driverClass = "com.mysql.jdbc.Driver";
// 当时本地默认3306 可以省略,也可写成 "jdbc:mysql://localhost:3306/mydb4?"
private static final String url = "jdbc:mysql:///mydb4?";
private static final String user = "root";
private static final String password = "111";

// 加载驱动
public static void loadDriver() {
// 1. 加载驱动
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("驱动加载失败!");
}
}

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

// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
release(conn, stmt);
}

public static void release(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}

测试类

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
@Test
public void test_query() {
// 1. 加载驱动
JDBCUtils.loadDriver();

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
// 2. 建立连接
conn = JDBCUtils.getConnection();
// 3. 操作数据
String sql = "select * from user;";
// 这里有可能引起sql注入问题,换成prepareStatement(sql)
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()) {
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(username + " = " + password);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}

软编码:从配置文件中读取(配置文件名字jdbc.properties)

1
2
3
4
5
6
7
#配置文件
#jdbc.properties
#mysql
driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///mydb4?
user=root
passwrod=111
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public class JDBCUtils {

// 属性
private static String driverClass;
private static String url;
private static String username;
private static String password;

// 请问 : 什么时候加载外部配置文件最合适 ???
// 特点1 : 随着类的加载而加载.
// 特点2 : 静态代码块只在类加载的被执行一次. 仅一次.
static {
Properties prop = new Properties();

try {
prop.load(new FileReader("jdbc.properties")); // 这里直接放在项目的目录下,具体要切合实际

// 如果程序执行到这里, 说明外部资源文件加载成功, 需要给我们的静态属性赋值
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");

// 直接执行加载驱动
loadDriver();

} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件资源加载失败!");
}
}

// 加载驱动
public static void loadDriver() {
try {
// 1. 加载驱动
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
// e.printStackTrace();
// 驱动加载失败!
throw new RuntimeException("驱动加载失败!");
}
}

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

// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
// 4. 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
// 将 rs 清空
rs = null;
}
// 直接调用
release(conn, stmt);
}
public static void release(Connection conn, Statement stmt) {
// 4. 释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}

测试类:

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
@Test
public void test_query() {

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "select * from user where username = ? and password = ?;";
// 预编译sql
stmt = conn.prepareStatement(sql);
// 设置sql语句的参数
stmt.setString(1, username);
stmt.setString(2, password);
// 执行sql语句
rs = stmt.executeQuery();
// 判断返回的结果
if (rs.next()) {
// 登录成功
int id = rs.getInt("id");
String u_name = rs.getString("username");
String u_pwd = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + u_name + " : " + u_pwd + " : " + email);

} catch (SQLException e) {
e.printStackTrace();
} finally {
// 3. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}

JDBCUtils中避免sql注入问题之后最终版总结:

PreparedStatement的CRUD
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    @Test
public void test_update() {
Connection conn = null;
PreparedStatement stmt = null;
try {
// 2. 建立连接
conn = JDBCUtils.getConnection();

// U 修改

// 3. 操作数据
String sql = "update user set username = ?, password = ?, email = ? where id = ?;";
stmt = conn.prepareStatement(sql);
// 设置参数
stmt.setString(1, "张三");
stmt.setString(2, "888");
stmt.setString(3, "zs@qiezi.cn");
stmt.setInt(4, 1);
// 执行
int affectedRowNum = stmt.executeUpdate();
System.out.println(affectedRowNum);

// 删除



// 2. 操作数据
String sql = "delete from user where id = ?;";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 4);
int affectedRowNum = stmt.executeUpdate();
System.out.println(affectedRowNum);



// 增加





// 2. 操作数据
String sql = "insert into user values(?,?,?,?);";
stmt = conn.prepareStatement(sql);
// 设置参数
stmt.setInt(1, 4);
stmt.setString(2, "赵六");
stmt.setString(3, "888");
stmt.setString(4, "zl@qiezi.cn");
int affectedRowNumber = stmt.executeUpdate();
System.out.println(affectedRowNumber);





// 查询





// 2. 操作数据
String sql = "select * from user where username = ? and password = ?;";
stmt = conn.prepareStatement(sql);
// 设置sql语句的参数
stmt.setString(1, username);
stmt.setString(2, password);
// 执行sql语句
rs = stmt.executeQuery();
// 判断返回的结果
if (rs.next()) {
// 登录成功
int id = rs.getInt("id");
String u_name = rs.getString("username");
String u_pwd = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + u_name + " : " + u_pwd + " : " + email);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}

二、JdbcTemplate

1.JdbcTemplate 介绍

JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。JdbcTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分

JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。

在JdbcTemplate中执行SQL语句的方法大致分为3类:

\1. execute:可以执行所有SQL语句,一般用于执行DDL语句。

\2. update:用于执行INSERT、UPDATE、DELETE等DML语句。

\3. queryXxx:用于DQL数据查询语句。

**新增加,新复习

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
DDL (数据定义语言)

数据定义语言 - Data Definition Language

用来定义数据库的对象,如数据表、视图、索引等

create drop alter truncate

DML (数据操纵语言)

数据处理语言 - Data Manipulation Language

在数据库表中更新,增加和删除记录

如 update, insert, delete 不包含查询



DCL (数据控制语言)

数据控制语言 – Data Control Language

指用于设置用户权限和控制事务语句

如grant,revoke,ifelsewhile,begin transaction



DQL (数据查询语言)(★★★★★)

数据查询语言 – Data Query Language

数据表记录的查询。

select

2.JDBCTemplate使用:

API介绍:

    1.org.springframework.jdbc.core.JdbcTemplate类方便执行SQL语句
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
public JdbcTemplate(DataSource dataSource)
创建JdbcTemplate对象,方便执行SQL语句


public void execute(final String sql)
execute可以执行所有SQL语句,因为没有返回值,一般用于执行DML语句。

public int update(final String sql)
用于执行`INSERT`、`UPDATE`、`DELETE`等DML语句。


public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):
传入参数, 执行查询语句,返回一个指定类型的数据。


public Map<String, Object> queryForMap(String sql, Object... args)
传入参数,执行查询语句,将一条记录放到一个Map中。


public List<Map<String, Object>> queryForList(String sql, Object... args)
传入参数,执行查询语句,返回一个List集合,List中存放的是Map类型的数据。


public <T> List<T> query(String sql, RowMapper<T> rowMapper)
执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。


public <T> List<T> query(String sql, RowMapper<T> rowMapper)
执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。


public class BeanPropertyRowMapper<T> implements RowMapper<T>
BeanPropertyRowMapper类实现了RowMapper接口

1.数据准备:

这里采用c3p0数据流连接池,集成到JDBCUtils 工具类中,需要将c3p0的配置文件放入到src目录下

 导入依赖的jar包

2.创建JdbcTemplate对象,传入c3p0连接池

3.调用 execute、update、queryXxx等方法

c3p0-config.xml 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,c3p0框架默认加载这段默认配置 -->
<default-config>
<!-- 配置JDBC 四个基本属性 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4?</property>
<property name="user">root</property>
<property name="password">111</property>
</default-config>
<!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
<named-config name="zidingyimingzi">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4?</property>
<property name="user">root</property>
<property name="password">111</property>
</named-config>
</c3p0-config>

JDBCUtils 工具类

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
public class JDBCUtils {

// 核心连接池类
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

public static DataSource getDataSource() {
return dataSource;
}

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

// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}

release(conn, stmt);
}

public static void release(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}

if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}

测试类(实现增改)

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
public class JDBCTemplateExecute {
public static void main(String[] args) {

// 查询语句



// 1. 创建表的SQL语句
String sql = "create table product (" +
"pid int primary key auto_increment," +
"pname varchar(20)," +
"price double" +
");";

// 2. 创建 jdbcTemplate 对象, 并将数据库连接池作为参数传入
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

// 3. 使用 jdbcTemplate 对象调用 execute 方法, 执行 sql 语句, 创建数据库表.
jdbcTemplate.execute(sql);



// 增加数据

// 2. 编写 sql 语句
String sql = "insert into product values(null, ?, ?);";

// 3. 执行 update 方法.
jdbcTemplate.update(sql, "iPhone3GS", 3333);
jdbcTemplate.update(sql, "iPhone4", 5000);



// 修改数据

// 2. 执行 update 语句
String sql = "update product set pname = ?, price = ? where pid = ?;";
int count = jdbcTemplate.update(sql, "XVIII", 18888, 10);
System.out.println("count = " + count);


// 删除数据
// 2. 执行 delete 操作
String sql = "delete from product where pid = ?;";
int count = jdbcTemplate.update(sql, 7);
System.out.println("count = " + count);
}
}

总结:JdbcTemplate的update方法用于执行DML语句。同时还可以在SQL语句中使用?占位,在update方法的Object… args可变参数中传入对应的参数。

测试类(实现查询)

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    @Test
public void test1() {

// 1. 创建一个 JdbcTemplate 对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());



// queryForObject 方法


// 2. 执行 queryForObject 方法
String sql = "select pname from product where price = 7777";
String pname = jdbcTemplate.queryForObject(sql, String.class);
System.out.println("pname = " + pname);



// queryForMap 方法

// 2. 执行 queryForMap 方法
String sql = "select * from product where pid = ?;";
Map<String, Object> map = jdbcTemplate.queryForMap(sql, 6);
System.out.println("map = " + map);




// objectForList

// 2. 执行 objectForList 方法
String sql = "select * from product where pid < ?;";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, 8);
for (Map<String, Object> map : list) {
System.out.println(map);
}




// 使用RowMapper做映射返回对象

1. 定义Product类
2. 创建JdbcTemplate对象
3. 编写查询的SQL语句
4. 使用JdbcTemplate对象的query方法,并传入RowMapper匿名内部类
5. 在匿名内部类中将结果集中的一行记录转成一个Product对象




// 2. 执行 query 方法
String sql = "select * from product;";
List<Product> list = jdbcTemplate.query(sql, new RowMapper<Product>() {
@Override
public Product mapRow(ResultSet rs, int i) throws SQLException {

Product product = new Product();
int pid = rs.getInt("pid");
String pname = rs.getString("pname");
double price = rs.getDouble("price");
product.setPid(pid);
product.setPname(pname);
product.setPrice(price);

return product;
}
});

// 遍历 list 集合
for (Product product : list) {
System.out.println(product);
}





1. 定义Product类
2. 创建JdbcTemplate对象
3. 编写查询的SQL语句
4. 使用JdbcTemplate对象的query方法,并传入BeanPropertyRowMapper对象



// 2. 执行 query 方法
String sql = "select * from product;";
List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Product.class));

// 3. 遍历 list 集合
for (Product product : list) {
System.out.println(product);
}

}

总结:

JDBCTemplate的query方法用于执行SQL语句,简化JDBC的代码。同时还可以在SQL语句中使用?占位,在query方法的Object... args可变参数中传入对应的参数。

三、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

在Hibernate和Spring 都提供对C3P0连接池支持.

导入2个包

基本操作

          // 核心连接池类

  ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();

  // 设置四个JDBC基本连接属性

  comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");

  comboPooledDataSource.setJdbcUrl("jdbc:mysql:///mydb4?");

  comboPooledDataSource.setUser("root");

  comboPooledDataSource.setPassword("111");

常用基本连接池属性

acquireIncrement  如果连接池中连接都被使用了,一次性增长3个新的连接

initialPoolSize  连接池中初始化连接数量默认:3

maxPoolSize      最大连接池中连接数量默认:15连接

maxIdleTime      如果连接长时间没有时间,将被回收默认:0 连接永不过期

    minPoolSize      连接池中最小连接数量 默认:3

通过c3p0创建数据库连接池对象方式提取到JDBCUtils中

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
public class JDBCUtils {

// c3p0 数据库连接池对象属性
// 这里会自动读取 位于src目录下的c3p0-config.xml 数据库连接池配置文件
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();

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

// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
release(conn, stmt);
}

public static void release(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}

c3p0-config.xml 数据库连接池配置文件 位于src 目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,c3p0框架默认加载这段默认配置 -->
<default-config>
<!-- 配置JDBC 四个基本属性 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4</property>
<property name="user">root</property>
<property name="password">111</property>
</default-config>
<!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
<named-config name="zidingyi">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4</property>
<property name="user">root</property>
<property name="password">111</property>
</named-config>
</c3p0-config>

测试类:

@Test
public void test_jdbcUtils() {

    // 需求 : 查询 user 表中的所有数据

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    try {
        // 1. 建立连接
        conn = JDBCUtils.getConnection();
        // 2. 操作数据
        String sql = "select * from user;";
        stmt = conn.prepareStatement(sql);
        rs = stmt.executeQuery();
        while (rs.next()) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            String email = rs.getString("email");
            System.out.println(id + " : " + username + " : " + password + " : " + email);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 3. 释放资源
        JDBCUtils.release(conn, stmt, rs);
    }
}

四、druid

Druid (德鲁伊) 是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。Druid地址:https://github.com/alibaba/druid 

DRUID连接池使用的jar包:

参数 说明
url 连接数据库的url:jdbc:mysql://localhost:3306/mydb
username 数据库的用户名
password 数据库的密码
driverClassName 驱动类名。根据url自动识别,这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
initialSize 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive 最大连接池数量
maxIdle 已经不再使用,配置了也没效果
minIdle 最小连接池数量
maxWait 获取连接时最大等待时间,单位毫秒。

API介绍

com.alibaba.druid.pool.DruidDataSourceFactory类有创建连接池的方法
1
2
public static DataSource createDataSource(Properties properties)
创建一个连接池,连接池的参数使用properties中的数据

tips:我们可以看到DRUID连接池在创建的时候需要一个Properties对象来设置参数,所以我们使用properties文件来保存对应的参数。

DRUID连接池的配置文件名称随便,因为该配置文件需要我们手动实现加载。

druid.properties文件内容:

1
2
3
4
5
6
7
8
9
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
username=root
password=111
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3

1.使用步骤:

\1. 在src目录下创建一个properties文件,并设置对应参数

\2. 加载properties文件的内容到Properties对象中

\3. 创建DRUID连接池,使用配置文件中的参数

\4. 从DRUID连接池中取出连接

\5. 执行SQL语句

\6. 关闭资源

JDBCUtils 工具类集成 Druid 数据库连接池

public class JDBCUtils {

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
60
61
// 属性
private static final DataSource dataSource;

static {
Properties prop = new Properties();

try {
// 加载配置文件
// 配置文件的位置无所谓,这里放的是项目的目录下,因为Druid数据库连接池需要手动加载配置文件
prop.load(new FileReader("druid.properties"));
// 创建数据库连接池
dataSource = DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
throw new RuntimeException("连接池初始化失败!");
}
}

public static DataSource getDataSource() {
return dataSource;
}

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

// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}

release(conn, stmt);
}

public static void release(Connection conn, Statement stmt) {

if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}

if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// e.printStackTrace(); ignore 忽略.
}
conn = null; // 目的: 让 conn 对象尽早被回收.
}
}
}

测试类

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
   @Test
public void test3() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;

try {
// 1. 建立连接
conn = JDBCUtils.getConnection();

// 2. 操作数据
String sql = "select * from user;";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + username + " : " + password + " : " + email);
}

} catch (SQLException e) {
e.printStackTrace();
} finally {
// 3. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}

Powered by Hexo and Hexo-theme-hiker

Copyright © 2016 - 2018 Francis的个人博客 All Rights Reserved.

UV : | PV :