1.8381.1批处理基本介绍
1.当需要分批插入或更新记录时。Java的批量更新机制可以使用,允许多句子一次提交给数据库进行批量处理。通常比单独提交更有效。
2.JDBC的批量处理语句包括以下方法:
addBatch():添加需要批量处理的SQL语句或参数
executeBatch():批量执行语句处理;
clearBatch():清空批处理包的句子
3.JDBC连接MySQL时,如果要使用批处理功能,请在url中添加
参数?rewriteBatchedStatements=true
4.批处理通常与PreparedStatement一起使用,可以减少编译次数和操作次数,大大提高效率
1.2应用实例8381.将5000条数据添加到admin2表中,以查看使用批处理需要多长时间
2.注:配置文件jdbcc需要修改.properties
url=jdbc:mysql://localhost:3306/数据库?rewriteBatchedStatements=true
com中的代码.stulzl.batch_.Batch_package com.stulzl.batch_;import com.stulzl.utils.JDBCUtils;import org.junit.jupiter.api.Test;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;///演示Java批处理publicc class Batch_ { //传统方法,向admin2添加5000个数据 @Test public void noBatch() throws Exception { Connection connection = JDBCUtils.getConnection(); String sql = "insert into admin2 values(null,?,?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); System.out.println(“开始执行”); long start = System.currentTimeMillis();//开始时间 for (int i = 0; i < 5000; i++) { preparedStatement.setString(1,"jack"+i); preparedStatement.setString(2,"666"); preparedStatement.executeUpdate(); } long end = System.currentTimeMillis();//结束时间 System.out.println(传统方式=”+(end-start));///传统方式=46544 ///关闭连接 JDBCUtils.close(null,preparedStatement,connection); } ///使用批量添加方法 @Test public void Batch() throws Exception { Connection connection = JDBCUtils.getConnection(); String sql = "insert into admin2 values(null,?,?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); System.out.println(“开始执行”); long start = System.currentTimeMillis();//开始时间 for (int i = 0; i < 5000; i++) { preparedStatement.setString(1,"jack"+i); preparedStatement.setString(2,"666"); ///将sql语句添加到批处理包中 preparedStatement.addBatch(); ///当有1000记录时,再批量处理 if((i+1)%1000=0,{/满1000条sql语句 preparedStatement.executeBatch(); preparedStatement.clearBatch();///清空一把 } } long end = System.currentTimeMillis();//结束时间 System.out.println(“批量方法=”+(end-start));//批量方法=76 ///关闭连接 JDBCUtils.close(null,preparedStatement,connection); }}
代码在E:java学习\初级\course17db_batch_-- 批量处理 838CREATE TABLE admin2(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(32) NOT NULL,PASSWORD VARCHAR(32) NOT NULL);SELECT * FROM admin2 DROP TABLE admin2
2.数据库连接池8402.传统方法5k次连接数据库问题1.编写连接MySQL5000次的程序
2.看看有什么问题,需要多长时间?.=>数据库连接池
com中的代码.stulzl.datasource_ConQuestionpackage com.stulzl.datasource_;import com.stulzl.utils.JDBCUtils;import org.junit.jupiter.api.Test;import java.sql.Connection;//引入连接池问题 840public class ConQuestion { ///代码连接数据库5000次 @Test //看连接-关闭 connection 会耗用多 public void testCon(){ long start = System.currentTimeMillis(); System.out.println(”开始连接..."); for (int i=0;i<5000;i++) { 使用传统的 jdbc 方式,得到连接 Connection connection = JDBCUtils.getConnection(); //做一些工作,比如得到 PreparedStatement ,发送 sql //... // 关闭 JDBCUtils.close(null, null, connection); } long end = System.currentTimeMillis(); System.out.println(传统的方式 5000 次 耗时=" + (end - start));//传统方式 5000 次 耗时=9620 }}
2.2传统的Conection问题分析84001.传统的JDBC数据库连接是通过DriverManager获得的。每次连接到数据库时,都要将Conection加载到内存中,然后验证IP地址、用户名和密码(0.05s~1s时间)。当需要数据库连接时,需要一个数据库。频繁的数据库连接操作会占用大量的系统资源,容易导致服务器崩溃。
2.每次数据库连接,使用后必须断开。如果程序异常,未能关闭,将导致数据库内存泄漏,最终导致数据库重启。
3.传统的获取连接方式无法控制创建的连接数量。如果连接过多,也可能导致内存泄漏和MySQL崩溃。
4.数据库连接技术可用于解决传统开发中的数据库连接问题(connectionpool)。
2.3数据库连接池基本介绍8411.提前将固定数量的连接放入缓冲池中。当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用后再放回去。
2.数据库连接池负责数据库连接的分配、管理和释放,允许应用程序重复使用现有的数据库连接,而不是重建一个。
3.当应用程序向连接池要求的连接数超过最大连接数时,这些请求将被添加到等待队列中
2.4数据库连接池类型8411.Javax用于JDBC数据库连接池.sql.DataSource表示,DataSource只是一个接口,通常由第三方提供
2.C3P0数据库连接池速度相对较慢,稳定性好(hibernate,spring)
3.与c3p0相比,DBCP数据库连接池速度更快,但不稳定
4.Proxol数据库连接池具有监控连接池状态的功能,其稳定性几乎比C3p0BoneCP数据库连接池快
6.Druid(德鲁伊)是阿里提供的集DBCP的数据库连接池、C3P0、Proxool的优点是数据库连接池的集成
2.5C3P0应用实例5000连接数据库842-843使用代码实现c3p0数据库连接池,将SRC目录C3P0java配置文件
com中的代码.stulzl.C3P0_C3P0_package com.stulzl.c3p0_;import com.mchange.v2.c3p0.ComboPooledDataSource;import org.junit.jupiter.api.Test;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;使用///演示c3p0 842-843 class C3P0_ (///先放入jar包 //方式 1: 相关参数,在程序中指定 user, url , password 等 @Test public void TestC3P0_01() throws Exception { //1.创建数据源对象 ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); //2. 相关信息通过配置文件获取 Properties properties = new Properties(); properties.load(new FileInputStream("src\\mysql.properties")); //阅读相关属性数据 String user = properties.getProperty("user"); String password = properties.getProperty("password"); String url = properties.getProperty("url"); String driver = properties.getProperty("driver"); //给数据源combopoleddatasource 设置相关参数 //注:连接管理是由 comboPooledDataSource 来管理 comboPooledDataSource.setDriverClass(driver); comboPooledDataSource.setJdbcUrl(url); comboPooledDataSource.setUser(user); comboPooledDataSource.setPassword(password); ///设置初始连接数 comboPooledDataSource.setInitialPoolSize(10); //设置最大连接数 comboPooledDataSource.setMaxPoolSize(50); ///测试连接池的效率, 测试对 mysql 5000 次操作 long start = System.currentTimeMillis(); for(int i=0;i<5000;i++){ ///这种方法是从 DataSource 接口实现的 Connection connection = comboPooledDataSource.getConnection(); //System.out.println(“连接成功”); //关闭 connection.close(); } long end = System.currentTimeMillis(); System.out.println("c3p0 5000次连接耗时=”+(end-start));//c3p0 5000次连接时间=336 } //方法二使用配置文件模板完成 843 //1. 将 c3p0 提供的 c3p0.config.xml 拷贝到 src 目录下 //2. 该文件指定了连接数据库和连接池的相关参数 @Test public void TestC3P0_02() throws SQLException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("hsp_edu"); ///测试连接池的效率, 测试对 mysql 5000 次操作 long start = System.currentTimeMillis(); for(int i=0;i<500000;i++) { Connection connection = comboPooledDataSource.getConnection(); //System.out.println(连接成功~); connection.close(); } long end = System.currentTimeMillis(); System.out.println("c3p0 第二次5万次连接耗时=+(end-start));//c3p0 第二次5万次连接时间=1630 }}
c3p0配置文件-config.xml<c3p0-config> <!-- 数据源名代表连接池 --> <named-config name="hsp_edu"><!-- 驱动类 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <!-- url--> <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/hsp_db02</property> <!-- 用户名 --> <property name="user">root</property> <!-- 密码 --> <property name="password">lzl</property> <!-- 连接数每次增加--> <property name="acquireIncrement">5</property> <!-- 初始连接数 --> <property name="initialPoolSize">10</property> <!-- 最小连接数 --> <property name="minPoolSize">5</property> <!-- 最大连接数 --> <property name="maxPoolSize">50</property><!-- 最可连接的命令对象数最多 --> <property name="maxStatements">5</property> <!-- 每个连接对象可以连接的命令对象数最多 --> <property name="maxStatementsPerConnection">2</property> </named-config></c3p0-config>
3.Druid(德鲁伊)8443.1应用实例844Druid(德鲁伊)数据库连接池使用代码实现
com中的代码.stulzl.druid_Druid_package com.stulzl.druid_;import com.alibaba.druid.pool.DruidDataSourceFactory;import org.junit.jupiter.api.Test;import javax.sql.DataSource;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.sql.Connection;import java.util.Properties;////演示Druid的使用 844public class Druid_ { @Test public void testDruid() throws Exception { //1. 加入 Druid jar 包 //2. 加入 配置文件 druid.properties , 复制项目的文件 src 目录 //3. 创建 Properties 对象, 读取配置文件 Properties properties = new Properties(); properties.load(new FileInputStream("src\\druid.properties")); //4. 创建指定参数的数据库连接池,Druid连接池 DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); long start = System.currentTimeMillis(); for (int i = 0; i < 500000; i++) { Connection connection = dataSource.getConnection(); //System.out.println(”连接成功!"); connection.close(); } long end = System.currentTimeMillis(); System.out.println(”druid连接池500000操作耗时=+(end-start));//druid连接池50000操作时间=4100 }}
druid配置文件.properties#key=valuedriverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=trueusername=rootpassword=lzl#initial connection SizeinitialSize=10#min idle connecton sizeminIdle=5#max active connection sizemaxActive=50#max wait time (5000 mil seconds)maxWait=5000
3.2将JDBCUtils工具类改为Druid(德鲁伊),实现845连接对象通过德鲁伊数据库连接池获得
在简单的演示下可以使用
com中的代码.stulzl.jdbcutils_druid;JDBCUtils_Druidpackage com.stulzl.jdbcutils_druid;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.FileInputStream;import java.io.IOException;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;///这是基于druid的数据库连接池的工具类 845//将 JDBCUtils 工具类改成 Druid(德鲁伊)实现public class JDBCUtils_Druid { private static DataSource ds; ////在静态代码块中完成ds的初始化 static{ Properties properties = new Properties(); try { properties.load(new FileInputStream("src\\druid.properties")); ds = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } ///编写getconection方法 public static Connection getConnection() throws SQLException { return ds.getConnection(); } //关闭连接, 再次强调: 在数据库连接池技术中,close 并非真的断开了连接 //使用它 Connection 对象放回连接池 public static void close(ResultSet resultSet, Statement statement, Connection connection){ try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { throw new RuntimeException(e); } }}
JDBCUtils测试类Druid_USEpackage com.stulzl.jdbcutils_druid;import com.stulzl.utils.JDBCUtils;import org.junit.jupiter.api.Test;import java.sql.*;///基于druid的数据库连接池测试工具类 845public class JDBCUtils_Druid_USE { @Test public void testSelect(){ System.out.println(使用druid工具类完成); //1.连接 Connection connection = null; //2.组织sql语句 String sql = "select * from actor where id=?"; PreparedStatement preparedStatement=null; ResultSet set = null; try { connection = JDBCUtils_Druid.getConnection(); /3.创建preparedStatent对象 preparedStatement = connection.prepareStatement(sql); //4. 给占位符赋值 preparedStatement.setInt(1,2); //执行,得到结果集 set = preparedStatement.executeQuery(); ///遍历结果集 while(set.next()){ int id = set.getInt("id");//这里提示(”id可以直接写,也可以写数字(按相应顺序) String name = set.getString("name"); String sex = set.getString("sex"); Date borndate = set.getDate("borndate"); String phone = set.getString("phone"); System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone); } } catch (SQLException e) { e.printStackTrace(); } finally { ///关闭资源 JDBCUtils_Druid.close(set,preparedStatement,connection); } }}