目录
一、前言
- 第三节内容,up主要和大家分享一下JDBC Utils方面的内容。
- 注意事项——①代码中的注释也很重要;②不要眼高手低;③点击文章的侧边栏目录或者文章开头的目录可以进行跳转。
- 良工不示人以朴,所有文章都会适时补充完善。大家如果有问题都可以在评论区进行交流或者私信up。 感谢阅读!
二、JDBCUtils说明
1.背景及起因 :
在JDBC核心四部曲中,“获取连接”和“释放资源”的操作会经常用到,并且不同程序之间的代码重合度很高,复用率很低。因此,基于OOP的思想,可以将这些操作封装到类中,这便是JDBC连接的工具类JDBCUtils。不同的JDBC程序只需要调用工具类中的方法即可。
2.示意图 :
示意图如下 :
编辑
3.JDBCUtils类的定义
首先,需要在类中定义四个相关属性,即我们前面小节的演示中都要用到的——driver, url, user, password。因为只需要一份,所以这四个属性均定义为static类型,在static代码块中进行静态属性的初始化操作。至于如何初始化,经过前面小节的学习,想必大家都信手拈来了——定义一个Properties类对象,通过load方法获取配置文件的信息,然后通过getProperty方法根据传入的键获取对应的值,逐个接收即可。
其次,就是定义静态方法了。
获取连接的静态方法可以直接return一个Connection对象,使用DriverManager.getConnection(url, user, password)方法即可。
释放资源的静态方法需要传入以下几个形参——
①ResultSet接口类型的对象(实际接收的是ResultSet接口的实现类);②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); } } }
三、JDBCUtils应用
1.DML的应用 :
我们先来建一张水果表用于演示,创建水果表的代码如下 :
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); } } }
运行效果如下 :
编辑
2.DQL的应用 :
仍然操作水果表,我们希望通过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------------------------------------------------------------------------------");