在上一篇介绍JDBC基础使用的博文中,简单了解到JDBC的使用。但是,也看出了一定的弊端:重复代码量较大。在我们每次新建一个JDBC的类操作数据库时,都要不停的进行驱动的注册,数据库的连接,参数的输入等大量重复性的操作。所以,有没有什么方法简化这一类的操作呢?
其实,将这些重复的代码进行抽取,作为一个工具类,每次使用的时候进行调用即可,这样便能够达到代码的可复用性。
抽取JDBC工具类的思路:

  1. 将注册驱动进行抽取
  2. 抽取一个方法获取连接对象
    • 需求:不必传递参数,并且保证工具类的通用性。
    • 解决:配置文件。

一、获取连接

因为我们需要将JDBC抽取为工具类,便于使用。故采取静态方法。

1.注册驱动
1
2
3
4
// 用于注册驱动,加载
public static Connection getConnection() throws Exception {
return DriverManager.getConnection(url, user, password);
}
2.关闭资源
关闭资源
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
// 用于关闭资源
public static void close(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 方法的重载。当需要对数据库进行查询的操作时,便需要这里的第三个参数,读取完数据后,需要关闭ResultSet占用的资源
public static void close(Statement stmt, Connection conn, ResultSet rs) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3.配置文件的读取
配置文件的读取
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
// 因为对配置文件的读取,只需要读取一次即可拿到这些值。故采用静态代码块。
static {
//读取资源文件,获取值
try {
// 1.创建Properties集合类
Properties pro = new Properties();
// 获取src路径下的文件的方法-->ClassLoader(类加载器,可以将字节码文件,加载进内存,且内获取src下的资源路径)
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
// 以当前src为文件绝对路径,获取文件资源的src
//URL统一资源标识符
URL resource = classLoader.getResource("jdbc.properties");
//通过getPath获取它的字符串路径
String path = resource.getPath();
// System.out.println(path);
// 2.加载文件
pro.load(new FileReader(path));
// 3.获取数据、复制
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");

Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
4. 配置文件

配置文件放在当前模块src目录下。文件名后缀为.properties。以下为配置文件可写的内容:

1
2
3
4
url=jdbc:mysql://ip:port/database             //填写数据库的url,例如本地url=jdbc:mysql://localhost:3306/db3
user=root //数据库用户
password=123456 // 用户密码
driver=com.mysql.jdbc.Driver //注册驱动路径
5.代码总结
代码总结
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
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
// 为了使Connection方法可以接受到值,故将参数提升到成员变量的位置上
// 只有静态修饰的变量,才能被静态方法所访问,才能被静态代码块所访问
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 文件的读取,只需要读取一次,即可拿到这些值。使用静态代码块完成
*/
static {
//读取资源文件,获取值
try {
// 1.创建Properties集合类
Properties pro = new Properties();
// 获取src路径下的文件的方法-->ClassLoader(类加载器,可以将字节码文件,加载进内存,且内获取src下的资源路径)
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
// 以当前src为文件绝对路径,获取文件资源的src
//URL统一资源标识符
URL resource = classLoader.getResource("jdbc.properties");
//通过getPath获取它的字符串路径
String path = resource.getPath();
// System.out.println(path);
// 2.加载文件
pro.load(new FileReader(path));
// 3.获取数据、复制
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* 工具类,方便使用,故采用静态方法
*
* @return 连接对象
*/
// 用于注册驱动,加载
public static Connection getConnection() throws Exception {
return DriverManager.getConnection(url, user, password);
}

// 用于关闭资源
public static void close(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}

}
}

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

二、 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
import cn.li.util.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBCDemo10 {
public static void main(String[] args) {

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

try {
conn = JDBCUtils.getConnection(); // 获取数据库连接对象
String sql = "select * from user where username = ? and password = ?"; // 采用预编译的方式,提高效率,预防SQL注入
pstmt = conn.prepareStatement(sql); // 获取sql执行对象
pstmt.setString(1, "Tom");
pstmt.setString(2, "1234");
rs = pstmt.executeQuery();
boolean next = rs.next();
System.out.println(next); // 判断此用户是否存在
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(pstmt, conn, rs); //资源的释放
}

}
}
从以上代码实例中,可以看出我们抽取出的JDBCUtils工具类,大大简化了代码,并且增加了代码的可复用性。当我们需要更改数据库的相关配置时,只需要更改配置文件即可,而我们的JDBCUtils工具类却不用更改。

参考文献

[1] Itcast视频讲义

[2] Java项目读取resources资源文件路径那点事


Comment