Java JDBC 封装:从原生写法到工具类封装 + 增删改查
在 Java 操作数据库的过程中原生 JDBC 代码存在大量重复逻辑加载驱动、获取连接、释放资源…… 这些代码在每个业务中都要写一遍不仅繁琐还容易出错。本文是个人的一些学习笔记主要内容如下原生 JDBC 写法与封装后写法对比配置文件 工具类封装增删改查 4 个完整测试案例项目结构与代码规范说明一、项目结构说明当前的项目结构如下所有代码均放在com.qcby包下配置文件放在resources目录src ├── main │ ├── java │ │ └── com.qcby │ │ ├── JDBCUtils.java // 封装好的工具类 │ │ ├── TestJDBC.java // 原生JDBC查询案例封装前 │ │ ├── TestJDBCUtils.java // 封装后查询案例 │ │ ├── TestUpdate.java // 封装后增删改案例 │ └── resources │ └── db.properties // 数据库配置文件二、封装前原生 JDBC 写法以查询为例1. 原生代码痛点硬编码数据库连接信息URL、账号、密码修改时需要改代码每次都要手动写加载驱动、获取连接、释放资源的重复代码资源关闭操作分散容易遗漏导致连接泄漏2. 原生查询案例代码TestJDBC.javapackage com.qcby; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class TestJDBC { public static void main(String[] args) throws Exception { // 1. 加载驱动硬编码驱动类路径 Class.forName(com.mysql.cj.jdbc.Driver); // 2. 获取连接硬编码数据库连接信息 String url jdbc:mysql:///jdbcdemo?serverTimezoneUTCuseSSLfalse; String user root; String password Zhen777; Connection conn DriverManager.getConnection(url, user, password); // 3. 获取执行SQL的对象 Statement stmt conn.createStatement(); // 4. 执行查询SQL String sql select * from t_user; ResultSet rs stmt.executeQuery(sql); // 5. 遍历结果集 while (rs.next()) { int id rs.getInt(id); String username rs.getString(username); String pwd rs.getString(password); String email rs.getString(email); System.out.println(id \t username \t pwd \t email); } // 6. 手动释放所有资源顺序结果集→Statement→连接 rs.close(); stmt.close(); conn.close(); } }三、封装配置文件 JDBC 工具类1. 数据库配置文件db.properties放在src/main/resources目录下统一管理数据库连接信息避免硬编码properties# 驱动类路径MySQL8.0用cj包 driverClasscom.mysql.cj.jdbc.Driver # 数据库连接URL必须加时区配置 urljdbc:mysql:///jdbcdemo?serverTimezoneUTCuseSSLfalse # 数据库账号 usernameroot # 数据库密码修改为你自己的 passwordZhen7772. JDBC 工具类JDBCUtils.java封装加载驱动、获取连接、释放资源的通用逻辑一次编写到处使用package com.qcby; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; /** * JDBC工具类封装通用的数据库操作逻辑 * 功能1. 读取配置文件 2. 加载驱动 3. 获取连接 4. 释放资源 */ public class JDBCUtils { // 配置文件对象静态加载一次 private static Properties props new Properties(); // 静态代码块类加载时自动执行只执行一次 static { try { // 读取resources下的db.properties配置文件 props.load(JDBCUtils.class.getClassLoader().getResourceAsStream(db.properties)); // 加载驱动从配置文件读取驱动类路径 Class.forName(props.getProperty(driverClass)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(JDBC工具类初始化失败请检查配置文件, e); } } /** * 获取数据库连接 * return Connection 数据库连接对象 */ public static Connection getConnection() { try { return DriverManager.getConnection( props.getProperty(url), props.getProperty(username), props.getProperty(password) ); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 释放资源查询场景关闭ResultSet、Statement、Connection * param conn 数据库连接对象 * param stmt Statement对象 * param rs 结果集对象 */ public static void close(Connection conn, Statement stmt, ResultSet rs) { try { if (rs ! null) rs.close(); if (stmt ! null) stmt.close(); if (conn ! null) conn.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 释放资源增删改场景关闭Statement、Connection无需关闭ResultSet * param conn 数据库连接对象 * param stmt Statement对象 */ public static void close(Connection conn, Statement stmt) { close(conn, stmt, null); } }四、封装后增删改查1. 查询案例TestJDBCUtils.java使用工具类完成查询代码大幅简化只关注业务 SQLpackage com.qcby; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class TestJDBCUtils { public static void main(String[] args) { Connection conn null; Statement stmt null; ResultSet rs null; try { // 1. 从工具类获取连接一行代码搞定 conn JDBCUtils.getConnection(); // 2. 获取执行SQL的对象 stmt conn.createStatement(); // 3. 编写并执行查询SQL String sql select * from t_user; rs stmt.executeQuery(sql); // 4. 遍历结果集并输出 while (rs.next()) { System.out.println( rs.getInt(id) \t rs.getString(username) \t rs.getString(password) \t rs.getString(email) ); } } catch (Exception e) { e.printStackTrace(); } finally { // 5. 释放所有资源调用工具类方法 JDBCUtils.close(conn, stmt, rs); } } }2. 新增案例TestUpdate.java 中 insert 部分package com.qcby; import java.sql.Connection; import java.sql.Statement; public class TestUpdate { public static void main(String[] args) { Connection conn null; Statement stmt null; try { // 1. 获取连接 conn JDBCUtils.getConnection(); // 2. 获取执行对象 stmt conn.createStatement(); // 3. 编写新增SQL String sql insert into t_user values(null,封装测试,666,testqq.com); // 4. 执行增删改SQLexecuteUpdate返回影响行数 int rows stmt.executeUpdate(sql); System.out.println(新增数据成功影响行数 rows); } catch (Exception e) { e.printStackTrace(); } finally { // 5. 释放资源增删改场景无需ResultSet JDBCUtils.close(conn, stmt); } } }3. 修改案例TestUpdate.java 中 update 部分package com.qcby; import java.sql.Connection; import java.sql.Statement; public class TestUpdate { public static void main(String[] args) { Connection conn null; Statement stmt null; try { conn JDBCUtils.getConnection(); stmt conn.createStatement(); // 修改SQL将用户名为“封装测试”的密码改为888888 String sql update t_user set password888888 where username封装测试; int rows stmt.executeUpdate(sql); System.out.println(修改数据成功影响行数 rows); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.close(conn, stmt); } } }4. 删除案例TestUpdate.java 中 delete 部分package com.qcby; import java.sql.Connection; import java.sql.Statement; public class TestUpdate { public static void main(String[] args) { Connection conn null; Statement stmt null; try { conn JDBCUtils.getConnection(); stmt conn.createStatement(); // 删除SQL删除用户名为“封装测试”的记录 String sql delete from t_user where username封装测试; int rows stmt.executeUpdate(sql); System.out.println(删除数据成功影响行数 rows); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.close(conn, stmt); } } }五、封装前后对比总结对比维度原生 JDBC 写法工具类封装写法代码量每个业务都要写连接、释放资源代码冗余仅关注业务 SQL代码量减少 60% 以上可维护性数据库信息硬编码修改需改动多处代码配置文件统一管理修改仅需改动配置文件错误率手动关闭资源易遗漏导致连接泄漏工具类统一处理避免资源泄漏问题复用性无复用性每个业务重复造轮子工具类可在所有业务中直接调用六、运行与验证步骤检查配置文件确认db.properties中的账号、密码、URL 配置正确运行查询案例执行TestJDBCUtils.java控制台输出t_user表所有数据运行新增案例执行TestUpdate.java中的新增代码控制台输出影响行数1数据库新增一条数据运行修改案例执行修改代码数据库中对应记录的密码被更新运行删除案例执行删除代码数据库中新增的测试数据被删除七、后续优化方向其他博客有介绍引入PreparedStatement防止 SQL 注入封装事务管理方法实现业务操作的原子性增加连接池如 Druid提升数据库连接性能
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2530775.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!