目录
一、前言
二、JDBCUtils说明
1.背景及起因 :
2.示意图 :
3.JDBCUtils类的定义
三、JDBCUtils应用
1.DML的应用 :
2.DQL的应用 :
四、总结
- 第三节内容,up主要和大家分享一下JDBC Utils方面的内容。
- 注意事项——①代码中的注释也很重要;②不要眼高手低;③点击文章的侧边栏目录或者文章开头的目录可以进行跳转。
- 良工不示人以朴,所有文章都会适时补充完善。大家如果有问题都可以在评论区进行交流或者私信up。 感谢阅读!
在JDBC核心四部曲中,“获取连接”和“释放资源”的操作会经常用到,并且不同程序之间的代码重合度很高,复用率很低。因此,基于OOP的思想,可以将这些操作封装到类中,这便是JDBC连接的工具类JDBCUtils。不同的JDBC程序只需要调用工具类中的方法即可。
示意图如下 :
首先,需要在类中定义四个相关属性,即我们前面小节的演示中都要用到的——driver, url, user, password。因为只需要一份,所以这四个属性均定义为static类型,在static代码块中进行静态属性的初始化操作。至于如何初始化,经过前面小节的学习,想必大家都信手拈来了——定义一个Properties类对象,通过load方法获取配置文件的信息,然后通过getProperty方法根据传入的键获取对应的值,逐个接收即可。
其次,就是定义静态方法了。
获取连接的静态方法可以直接return一个Connection对象,使用DriverManager.getConnection(url, user, password)方法即可。
释放资源的静态方法需要传入几个形参——①ResultSet接口类型的对象(实际接收的是Connection接口的实现类);Statement接口类型的对象(实际接收的是Statement接口的实现类);③Connection接口类型的对象(实际接收的是Connection接口的实现类)。话说为什么要传入这几个参数?
哎哟,瞧你这话问的多见外呀! 仔细回忆一下,我们释放资源时要close的,不就是这几个哥么。其中,注意一下此处Statement类型既可以接收Statement接口的实现类,也可以接收PreparedStatement接口的实现类,即接口的多态。
up以JDBCUtils类为演示类,JDBCUtils代码如下 : (代码中的注释也很重要!)
package utils;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/**
* @author : Cyan_RA9
* @version : 21.0
*/
public class JDBCUtils {
private static String driver; //Driver驱动
private static String url; //Uniform Resource Locator,包含数据库信息
private static String user; //用户名
private static String password; //用户密码
static {
Properties properties = new Properties();
try {
//Class.forName(driver);
properties.load(new FileInputStream("src/api/connection/mysql.properties"));
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
} catch (IOException e) {
/*
实际开发中,往往将捕获到的编译期异常转换为一个运行期异常抛出去;
这时对于调用者来说,
既可以选择捕获该异常,进行进一步的业务处理,也可以选择默认处理该异常,比较方便。
*/
throw new RuntimeException(e);
}
}
//获取连接
public static Connection getConnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//释放资源
/**
* @param resultSet : 结果集(DQL产生)
* @param statement : Statement接口或PreparedStatement接口的实现类
* @param connection : 即通过getConnection方法获取到的连接
*/
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
/*
DML的执行不产生ResultSet结果集,可以传入一个null;
因此要先判断传入的对象是否为空,若非空则调用close方法关闭资源(动态绑定)
*/
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
我们先来建一张水果表用于演示,创建水果表的代码如下 :
CREATE TABLE IF NOT EXISTS fruit(
`id` MEDIUMINT PRIMARY KEY,
`name` VARCHAR(64) NOT NULL DEFAULT '',
`sweetness` TINYINT NOT NULL DEFAULT 0
) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin ENGINE INNODB;
INSERT INTO fruit
VALUES
(1,'apple',13),
(2,'grape',15),
(3,'pear',10);
SELECT * FROM fruit;
fruit表效果如下 :
继续,up以JDBCUtils_Test1类为测试类,在测试类中我们利用工具类JDBCUtils中封装的两个静态方法完成获取连接和释放资源的操作,并在测试类中自定义SQL语句,要求将fruit表中的关于pear的数据更改为关于watermelon的数据。
JDBCUtils_Test1类代码如下 :
package utils;
import org.testng.annotations.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCUtils_Test1 {
@Test
public void testDML() throws ClassNotFoundException {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
Connection connection = null;
//3.执行SQL
String sql = "UPDATE fruit " +
"SET `name` = ?, sweetness = ? " +
"WHERE `name` = ?;";
PreparedStatement preparedStatement = null;
try {
connection = JDBCUtils.getConnection();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "watermelon");
preparedStatement.setInt(2, 16);
preparedStatement.setString(3, "pear");
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//4.释放资源
JDBCUtils.close(null, preparedStatement, connection);
}
}
}
运行效果如下 :
仍然操作水果表,我们希望通过Java程序来查询得到水果表中的内容;up以JDBCUtils_Test2类为第二个测试类,代码如下 :
package utils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCUtils_Test2 {
public static void main(String[] args) throws ClassNotFoundException {
//核心四部曲
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
Connection connection = null;
//3.执行SQL
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
String sql = "SELECT * " +
"FROM fruit ";
try {
connection = JDBCUtils.getConnection();
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
int sweetness = resultSet.getInt("sweetness");
System.out.println(String.format("%d\t%s\t%d\t", id,name,sweetness));
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
//4.释放资源
JDBCUtils.close(resultSet, preparedStatement, connection);
}
}
}
运行结果 :
- ,以上就是JDBC系列博文第三节的全部内容了。
- 总结一下,为了提高代码的复用率,引入工具类JDBCUtils,将JDBC核心四部曲中代码重复率和使用率较高的“获取连接”和“释放资源”通过OOP的思想,封装到JDBCUtils类的静态方法中,具体使用过程中,核心的四部曲还是老样子,只不过可以让你少些很多代码,节省了时间。
- 下一节内容——JDBC 事务和批处理,我们不见不散。感谢阅读!
System.out.println("END------------------------------------------------------------------------------");