当前位置: 首页 > news >正文

JDBC和Mybatis中的批处理

src目录下创建jdbc.properties mysql驱动5.1.6之后,只需要配置url,username,password

mysql 5.1.6之后可以无需Class.forName("com.mysql.jdbc.Driver")
* 从jdk1.5之后可以通过配置文件来配置
* 会自动加载mysql驱动jar包下META-INF/services/java.sql.Driver文本中的类名去注册

JDBC工具类

package com.example;import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;/*** JDBC工具类* @author hrui* @date 2024/8/29 16:45*/
public class JDBCUtils {private static String url;private static String username;private static String password;private static Properties properties=new Properties();static{try {properties.load(new FileInputStream("src\\jdbc.properties"));url = properties.getProperty("url");username = properties.getProperty("username");password = properties.getProperty("password");}catch (IOException e){e.printStackTrace();//throw new RuntimeException(e);}}public static Connection getConnection() throws SQLException {//如果这样写,虽然不需要定义url,username,password,但是每次都要从properties获取url,username,password,效率不高 所以还是定义url,username,password 静态块里赋值//return DriverManager.getConnection(properties.getProperty("url"), properties.getProperty("username"), properties.getProperty("password"));return DriverManager.getConnection(url, username, password);}public static void closed(ResultSet rs, Statement stmt, Connection conn){try {if(rs!=null){rs.close();}if(stmt!=null){stmt.close();}if(conn!=null){conn.close();}}catch (SQLException e){e.printStackTrace();}}
}

 以下执行代码数据一多,执行非常慢

package com.example;import java.sql.Connection;
import java.sql.PreparedStatement;/*** @author hrui* @date 2024/8/29 17:51*/
public class BathDemo {/*** 批处理* JDBC的批处理语句包括下面方法:* addBatch():添加需要批量处理的sql语句或参数* executeBatch():执行批处理语句* clearBatch():清空批处理语句* JDBC连接MySQL时,如果要使用批处理功能,再url中加参数?rewriteBatchedStatements=true* 批处理往往和PreparedStatement一起搭配使用,可以减少编译次数,效率提高* @param args*/public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;long start = System.currentTimeMillis();System.out.println("开始批处理:"+start);try {conn = JDBCUtils.getConnection();//conn.setAutoCommit(false);String sql="insert into admin2 values(null,?,?)";ps = conn.prepareStatement(sql);for (int i = 0; i < 100000; i++) {ps.setObject(1,"hrui"+i);ps.setObject(2,"123456");ps.executeUpdate();}// conn.commit();long end = System.currentTimeMillis();System.out.println("结束批处理:"+end);}catch (Exception e){e.printStackTrace();
//            if(conn!=null){
//                try {
//                    conn.rollback();
//                } catch (Exception e1) {
//                    e1.printStackTrace();
//                }
//            }}finally {JDBCUtils.closed(null,ps,conn);}}
}

以下代码注意在url后面加

?rewriteBatchedStatements=true

JDBC中正确的批处理

package com.example;import java.sql.Connection;
import java.sql.PreparedStatement;/*** @author hrui* @date 2024/8/29 18:59*/
public class BathDemo2 {//正确的批处理方式public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;long start = System.currentTimeMillis();System.out.println("开始批处理:"+start);try {conn = JDBCUtils.getConnection();conn.setAutoCommit(false);String sql="insert into admin3 values(null,?,?)";ps = conn.prepareStatement(sql);//这里执行完  sql已经发送到DBMS进行编译for (int i = 0; i < 1000000; i++) {ps.setObject(1,"hrui"+i);ps.setObject(2,"123456");ps.addBatch();//循环一次 添加到批处理 添加的是参数if((i+1)%2000==0){ps.executeBatch();//满1000条执行一次ps.clearBatch();//执行完清空}}conn.commit();long end = System.currentTimeMillis();System.out.println("结束批处理:"+end);//所用时间秒  一般5000条这样数据大概耗时10秒System.out.println("所用时间:"+(end-start));}catch (Exception e){e.printStackTrace();
//            if(conn!=null){
//                try {
//                    conn.rollback();
//                } catch (Exception e1) {
//                    e1.printStackTrace();
//                }
//            }}finally {JDBCUtils.closed(null,ps,conn);}}
}

DataSource是扩展版就是企业用的,我们现在所有的连接都是从DataSource里拿的  那么像HikariCP,druid,C3P0等数据库连接池都是实现DataSource的  默认我们在使用SpringBoot时候 使用的是HikariCP数据库连接池,也就是说DataSource其实就是数据库连接池的接口,在使用SpringBoot的时候,如果非不想使用默认或者druid,就是不想使用连接池,那么必须要指定一个DataSource的实现类,否则无法连接,Spring提供了一个DriverManagerDataSource,另外一种方式是你自己实现DataSource  然后指定type为自定义的.获取连接之后  还是通过Statement或者PreparedStatement去执行sql

下次是使用连接池的,可以有多个数据库连接去执行SQL操作 因为内存中循环肯定很快

insert into admin(name,pwd) values(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),

配置DriverManagerDataSource

那么再执行下面代码就是一个每次一个连接 insert into admin(name,pwd) values(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx),(xxx,xxx)  执行完关闭conn,

然后再打开 再执行 每次都只有一个连接在处理

速度会慢很多

另外 mybatis的这种执行方式 对于?rewriteBatchedStatements=true好像并没有多大作用,不过有应该是好的

<foreach>标签的影响

  • 不需要设置rewriteBatchedStatements=true:因为你使用的是MyBatis的<foreach>标签,这种方式本质上已经生成了一条带有多个值对的SQL语句,类似INSERT INTO admin (name, pwd) VALUES ('name1', 'pwd1'), ('name2', 'pwd2'), ...,这与rewriteBatchedStatements=true的效果类似。
  • 因此,在这种情况下,加上rewriteBatchedStatements=true对性能提升不会有显著作用。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Python数据分析】numpy中的npz和npy的用法和区别
  • scrapy框架--快速了解
  • 队列算法【基于顺序表的环形队列】
  • VMware安装Ubuntu 23.10.1系统图文版
  • 【小白深度学习入门】【1】卷积神经网络CNN 结构、基本原理以及常见问题详解
  • 前端 数值列 禁止输入多个小数点
  • Debian Linux上安装Jumpserver
  • vue-draggable-plus实现某些子元素不被拖拽
  • JS中【querySelectorAll】详解
  • 【Node】【7】函数
  • 8.28-回顾+容器与主机之间的通信+跨主机容器之间的通信
  • NTP简介及相关概念
  • mysql创建存储过程
  • 音频PCM的能量dB计算
  • iOS巨魔商店免越狱作弊解决方案
  • 【Leetcode】101. 对称二叉树
  • 【5+】跨webview多页面 触发事件(二)
  • FineReport中如何实现自动滚屏效果
  • IOS评论框不贴底(ios12新bug)
  • JavaScript中的对象个人分享
  • MySQL的数据类型
  • PAT A1050
  • PHP变量
  • spring boot下thymeleaf全局静态变量配置
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • VuePress 静态网站生成
  • 闭包--闭包之tab栏切换(四)
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 思否第一天
  • 微信支付JSAPI,实测!终极方案
  • linux 淘宝开源监控工具tsar
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 回归生活:清理微信公众号
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • ​一些不规范的GTID使用场景
  • # 数据结构
  • #DBA杂记1
  • (06)Hive——正则表达式
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (55)MOS管专题--->(10)MOS管的封装
  • (C11) 泛型表达式
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (论文阅读30/100)Convolutional Pose Machines
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (算法)N皇后问题
  • (转)一些感悟
  • ./configure、make、make install 命令
  • .JPG图片,各种压缩率下的文件尺寸
  • .net core + vue 搭建前后端分离的框架