主页 > 开源代码  > 

JDBC进阶

JDBC进阶
一 实体类和ORM

对指定的对象的属性封装 package com.ax.advance.pojo; public class Employee { private Integer id; private String degree; private String major; private String school1; private String school2; private String school3; private Integer userId; public Employee(Integer id, String degree, String major, String school1, String school2, String school3, Integer userId) { this.id = id; this.degree = degree; this.major = major; this.school1 = school1; this.school2 = school2; this.school3 = school3; this.userId = userId; } public Employee() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDegree() { return degree; } public void setDegree(String degree) { this.degree = degree; } public String getMajor() { return major; } public void setMajor(String major) { this.major = major; } public String getSchool1() { return school1; } public void setSchool1(String school1) { this.school1 = school1; } public String getSchool2() { return school2; } public void setSchool2(String school2) { this.school2 = school2; } public String getSchool3() { return school3; } public void setSchool3(String school3) { this.school3 = school3; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } @Override public String toString() { return "Employee{" + "id=" + id + ", degree='" + degree + '\'' + ", major='" + major + '\'' + ", school1='" + school1 + '\'' + ", school2='" + school2 + '\'' + ", school3='" + school3 + '\'' + ", userId=" + userId + '}'; } } 数据封装在对象当中 package com.ax.advance; import com.ax.advance.pojo.Employee; import java.sql.*; public class JDBCa { public static void main(String[] args) throws SQLException { //获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/itheima", "root", "tan2179432748"); //预编译SQL语句 PreparedStatement preparedStatement = connection.prepareStatement("select * from tb_user_edu where degree = ?"); //为问号占位符赋值,并执行SQL语句,接收返回的结果集 preparedStatement.setString(1, "本科"); //处理结果集 ResultSet resultSet = preparedStatement.executeQuery(); //遍历结果集 Employee employee = null; while (resultSet.next()) { int id = resultSet.getInt("id"); String degree = resultSet.getString("degree"); String major = resultSet.getString("major"); String primaryschool = resultSet.getString("primaryschool"); String middleschool = resultSet.getString("middleschool"); String university = resultSet.getString("university"); int userId = resultSet.getInt("userid"); //封装对象 employee = new Employee(id, degree, major, primaryschool, middleschool, university, userId); System.out.println(employee); } //资源的释放(先开后放) resultSet.close(); preparedStatement.close(); connection.close(); } } 对象再封装在集合当中 package com.ax.advance; import com.ax.advance.pojo.Employee; import java.sql.*; import java.util.ArrayList; public class JDBCb { public static void main(String[] args) throws SQLException { //获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/itheima", "root", "tan2179432748"); //预编译SQL语句 PreparedStatement preparedStatement = connection.prepareStatement("select * from tb_user_edu where degree = ?"); //为问号占位符赋值,并执行SQL语句,接收返回的结果集 preparedStatement.setString(1, "本科"); //处理结果集 ResultSet resultSet = preparedStatement.executeQuery(); //创建集合存储对象 ArrayList<Employee> employees = new ArrayList<>(); //遍历结果集 Employee employee = null; while (resultSet.next()) { employee = new Employee(); employee.setId(resultSet.getInt("id")); employee.setDegree(resultSet.getString("degree")); employee.setMajor(resultSet.getString("major")); employee.setSchool1(resultSet.getString("primaryschool")); employee.setSchool2(resultSet.getString("middleschool")); employee.setSchool3(resultSet.getString("university")); employee.setUserId(resultSet.getInt("userid")); employees.add(employee); } //输出 employees.forEach(System.out::println); } } 二 主键回显

主键回显指在数据库插入操作后,自动获取数据库生成的主键值(如自增ID、序列值等),并将其回填到程序中的对象或变量中。其核心目的是解决多表关联插入时主键依赖问题,例如:主表插入后需获取自增ID,才能将子表数据的外键关联到该ID

实现目的:有效地处理自动生成的主键值

代码实现

package com.ax.advance; import com.ax.advance.pojo.Employee2; import java.sql.*; public class JDBCc { public static void main(String[] args) throws SQLException { // 获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/itheima", "root", "tan2179432748"); // 预编译SQL语句并设置返回主键 PreparedStatement preparedStatement = connection.prepareStatement("insert into ax_new (name, school, age) values (?,?,?)", Statement.RETURN_GENERATED_KEYS); //创建对象 Employee2 employee2 = new Employee2(null, "张三", "清华大学", 20); preparedStatement.setString(1, employee2.getName()); preparedStatement.setString(2, employee2.getSchool()); preparedStatement.setInt(3, employee2.getAge()); // 执行SQL语句,返回受影响的行数(这里已经添加了,主键是自动增长的) int i = preparedStatement.executeUpdate(); ResultSet resultSet = null; // 判断是否添加成功 if (i > 0) { System.out.println("添加成功"); //获取当前新增数据的主键列,回显到Java封装的对象Employee2的id属性中,返回结果放在ResultSet中 resultSet = preparedStatement.getGeneratedKeys(); while (resultSet.next()) { employee2.setId(resultSet.getInt(1)); } System.out.println(employee2); } else { System.out.println("添加失败"); } //释放资源 if (resultSet != null) { resultSet.close(); } preparedStatement.close(); connection.close(); } } 三 批量操作

通过合理使用JDBC批量操作,可显著减少网络往返和数据库负载,提升应用性能。

JDBC的批量操作允许一次性执行多个SQL语句,显著提升数据库操作的效率,尤其适用于大量数据插入、更新或删除的场景。

代码实现:

package com.ax.advance; import java.sql.*; public class JDBCd { public static void main(String[] args) throws SQLException { //获取连接对象 Connection connection = DriverManager. getConnection("jdbc:mysql://localhost/itheima?rewriteBatchedStatements=True", "root", "tan2179432748"); // 预编译SQL语句 PreparedStatement preparedStatement = connection.prepareStatement("insert into ax_new (name, school, age) values (?,?,?)"); for (int i = 0; i < 10; i++){ preparedStatement.setString(1, "ax" + i); preparedStatement.setString(2, "清华大学" + i); preparedStatement.setInt(3, i); // 添加到批处理中 preparedStatement.addBatch(); } //执行批处理 preparedStatement.executeBatch(); //资源释放 preparedStatement.close(); connection.close(); } } 四 连接池

DBC连接池是一种管理和复用数据库连接的技术,旨在减少频繁创建/关闭连接的开销,提升应用性能。(在每次操作数据库都要获取新连接,使用完毕就close释放,频繁的创建和销毁造成资源浪费,连接的数量无法把控对服务器来说压力巨大。)

传统JDBC连接的缺点:

高开销:每次操作都新建连接,涉及网络握手、身份验证等耗时操作。

资源浪费:频繁开关连接会导致数据库负载过高。

难以应对高并发:大量并发请求时,频繁创建连接会导致性能瓶颈。

连接池的核心思想:

预创建连接:初始化时创建一定数量的连接,放入“池”中。

复用连接:应用从池中借用连接,用完后归还(而非关闭)。

动态管理:根据负载动态调整池中的连接数量。

常见连接池:

1 Druid连接池的使用

硬编码

package com.ax.advance.pool; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidPooledConnection; import org.junit.jupiter.api.Test; import java.sql.SQLException; public class DruidTest { @Test public void testHardCodeDruid() throws SQLException { //创建DruidDataSource对象 DruidDataSource druidDataSource = new DruidDataSource(); //设置连接池的配置信息 //必须 druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); druidDataSource.setUrl("jdbc:mysql://localhost/itheima"); druidDataSource.setUsername("root"); druidDataSource.setPassword("tan2179432748"); //非必须 druidDataSource.setInitialSize(10); druidDataSource.setMaxActive(20); //通过连接池获取连接对象 DruidPooledConnection connection = druidDataSource.getConnection(); //基于connection进行CRUD //回收连接对象(将连接归还给连接池,而不是释放资源) connection.close(); } }

软编码(不基于maven管理工具)

代码实现:

@Test public void testResourcesDruid() throws Exception { // 创建Properties集合,用于存储连接池的配置信息(key和value) // Properties 是 Java 中用来处理属性文件的一个类,通常用于加载配置文件中的键值对。 Properties properties = new Properties(); // 读取外部配置文件,获取输入流,加载到Properties集合中 // 使用ClassLoader的getResourceAsStream方法来获取资源的输入流,这样可以确保在任何环境下都能正确找到资源文件。 // "db.properties" 是一个典型的数据库连接属性文件,其中包含了数据库驱动、URL、用户名、密码等信息。 InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("db.properties"); properties.load(inputStream); // 加载输入流中的内容到Properties对象中 // 创建DruidDataSource对象 // Druid是一个高效的数据库连接池实现,通过传递Properties对象给createDataSource方法, // 我们可以初始化一个包含所有必要配置的连接池。 DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); // 通过连接池获取连接对象 // getConnection 方法从连接池中获取一个可用的数据库连接,这比直接创建新的数据库连接更加高效。 Connection connection = dataSource.getConnection(); System.out.println(connection); // 输出连接对象,通常是调试用 // 基于connection进行CRUD操作 // 这里可以根据需要执行查询、插入、更新或删除操作。具体实现依赖于业务逻辑需求。 // 回收连接对象(将连接归还给连接池,而不是释放资源) // 调用close方法并不是真的关闭连接,而是将连接返回到连接池中,以便后续使用。 connection.close(); } 2 Hikari连接池的使用(省略-后期补充)

标签:

JDBC进阶由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“JDBC进阶