当我们在使用JDBC进行数据库操作的时候,通常需要四个步骤
1.加载并注册数据库驱动(SQL Server,Sqlite,Mysql.....)
关于数据库驱动,这个我个人的见解如下:(可能不太准确)
提供统一接口,这样子来不同的数据库服务厂商只需要写好jar包,然后通过实现统一接口即可
Class.forName(Driver)
2.连接数据库
Connection conn = DriverManager.getConnection()
3.执行sql语句
Statement statement = conn.createStatement();
4.关闭连接(关闭顺序和连接顺序相反)
statement.close(); conn.close();
按照常理来说,这样子写写几个方法是没什么问题,但是当你回过头来看的时候,你会发现代码存在高度冗余,而且每执行一个方法的时候就需要资源连接,释放连接.....
使用JDBC编程将产生大量的冗余代码,需要进行重构与优化。
优化:
(1)数据库连接参数的优化
(2)提取方法,消除冗余代码
(3)提高效率虽然消除了代码冗余,但每执行增、删、改都要重新与数据库建立连接,影响程序的执行效率,如果可以共享连接对象,将提高效率。一旦共享连接对象,又可能造成一个空闲的连接对象被长期占用,导致资源的浪费,可以使用连接池来改进。
(4)降低对数据库结构的依赖虽然不同的数据库表结构不同,但使用JDBC处理数据的代码都高度相似,为了降低对数据库的依赖,提高代码的通用性,各种框架应运而生,如MyBatis等。
所以根据以上的问题,就可以暂时写一个工具类来管理连接和关闭,增强代码的健壮性
代码解析:
1.定义连接参数为静态变量
2.通过properties来出初始化连接参数(为什么:连接灵活,而且需要切换数据库的时候只需要修改配置文件即可,不用费尽心思的导出修改参数)
3.通过ClassLoader来获取当前目录下面的src文件所有内容
4.classloader.getResource得到一个统一资源定位符URL对象
5.获取URL对象的Path作为properties的加载路径
6.getConnection没啥好说的,获取数据库连接对象
7.close方法有两个,重载了一个三个参数的close方法
// 使用 Objects.requireNonNull() 检查 xxx是否为 null, // 如果为 null,则抛出 NullPointerException 异常,并带上指定的错误消息
然后就是是否可以把close的资源提到同一个try-catch里面,显而易见,这个是不行的。
简单举个例子,如果a.close抛出异常了,那么就进入了catch语句,b.close是不会执行的,那么就会造成资源浪费,影响代码的正确性。
try {
a.close();
b.close();
} catch (SQLException throwables) {
// 处理 SQLException 异常,打印异常信息和堆栈跟踪
throwables.printStackTrace();
}
package java6265.dao;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Objects;
import java.util.Properties;
public class DBUtil6265 {
private static String Driver;
private static String Url;
private static String USER;
private static String PW;
/**
* 通过静态代码块进行文件的读取和属性赋值
*/
static {
// 创建 Properties 对象
Properties properties = new Properties();
try {
// 获取文件路径
ClassLoader classLoader = DBUtil6265.class.getClassLoader();
URL url = classLoader.getResource("config/database6265.properties");
String path = url.getPath();
// 加载文件
properties.load(new FileReader(path));
// 获取属性值并赋值
Driver = properties.getProperty("DRIVER");
Url = properties.getProperty("URL");
USER = properties.getProperty("USER");
PW = properties.getProperty("PW");
// 加载数据库驱动类
Class.forName(Driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接对象
*
* @return 返回 Connection 对象
* @throws SQLException 如果获取数据库连接时发生错误,则抛出 SQLException 异常
*/
public static Connection getConnection() throws SQLException {
// 使用 DriverManager 来获取 Connection 对象,并指定数据库连接的 URL、用户名和密码
return DriverManager.getConnection(Url, USER, PW);
}
/**
* 关闭数据库连接和语句的方法
*
* @param connection 数据库连接对象
* @param statement 数据库语句对象
*/
public static void close(Connection connection, Statement statement) {
// 使用 Objects.requireNonNull() 检查 connection 是否为 null,
// 如果为 null,则抛出 NullPointerException 异常,并带上指定的错误消息
Objects.requireNonNull(connection, "Connection must not be null");
// 使用 Objects.requireNonNull() 检查 statement 是否为 null,
// 如果为 null,则抛出 NullPointerException 异常,并带上指定的错误消息
Objects.requireNonNull(statement, "Statement must not be null");
try {
// 关闭 statement 对象
statement.close();
} catch (SQLException throwables) {
// 处理 SQLException 异常,打印异常信息和堆栈跟踪
throwables.printStackTrace();
}
try {
// 关闭 connection 对象
connection.close();
} catch (SQLException throwables) {
// 处理 SQLException 异常,打印异常信息和堆栈跟踪
throwables.printStackTrace();
}
}
/**
* 关闭数据库连接、语句和结果集的方法
*
* @param connection 数据库连接对象
* @param statement 数据库语句对象
* @param resultSet 数据库结果集对象
*/
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
// 使用 Objects.requireNonNull() 检查 connection 是否为 null,
// 如果为 null,则抛出 NullPointerException 异常,并带上指定的错误消息
Objects.requireNonNull(connection, "Connection must not be null");
// 使用 Objects.requireNonNull() 检查 statement 是否为 null,
// 如果为 null,则抛出 NullPointerException 异常,并带上指定的错误消息
Objects.requireNonNull(statement, "Statement must not be null");
// 使用 Objects.requireNonNull() 检查 resultSet 是否为 null,
// 如果为 null,则抛出 NullPointerException 异常,并带上指定的错误消息
Objects.requireNonNull(resultSet, "ResultSet must not be null");
try {
// 关闭 statement 对象
statement.close();
} catch (SQLException throwables) {
// 处理 SQLException 异常,打印异常信息和堆栈跟踪
throwables.printStackTrace();
}
try {
// 关闭 resultSet 对象
resultSet.close();
} catch (SQLException throwables) {
// 处理 SQLException 异常,打印异常信息和堆栈跟踪
throwables.printStackTrace();
}
try {
// 关闭 connection 对象
connection.close();
} catch (SQLException throwables) {
// 处理 SQLException 异常,打印异常信息和堆栈跟踪
throwables.printStackTrace();
}
}
}