JDBC Batch Updates(二) jdbc批量更新三种模式
yuyutoo 2024-10-28 20:21 5 浏览 0 评论
最近在看一本书《high performance java persistence》,做一下笔记
这章不会太长,也是拓展一下大家的知识。
java.sql.Statement: 执行SQL语句并获取执行结果集,记住喔,这个接口的实现类执行的静态SQL语句喔。
java.sql.PreparedStatement:如果你翻开JDK,里面指的是一个预编译的SQL语句,文绉绉的,其实就是动态传参的SQL语句。
java.sql.CallableStatement:执行存储过程的接口。
Batch updates,中文译过来就是批量更新。我们平时都是用框架去做这些东西,却对底层了解的很少,下面我就和大家介绍一下。
JDBC2.0引入指量更新。这里于多条的DML statements(DML 语句)可以组合在一个请求里面发送给数据库。
看一段代码:
statement.addBatch(
"INSERT INTO post (title, version, id) " + "VALUES ('Post no. 1', 0, 1)");
statement.addBatch(
"INSERT INTO post_comment (post_id, review, version, id) " + "VALUES (1, 'Post comment 1.1', 0, 1)");
int[] updateCounts = statement.executeBatch();
这里就要敲黑板了,是扩充你的知识面的时候。不同的数据库厂商实现的会有所差异的,下面我是根据书还有一些文章来给你解释一下:
首先是Oracle,对于Statement和CallableStatement,其实是没并没有真正的像我上面说的合成一个请求,其实是每一条语句独立执行并没有批量执行,所以性能上面并没有提升的。PrepareStatment是有能进行批量处理的,但是那个batch size你要注意了,官方提出是50-100最佳。原因就是如果批次太大会造成占用太大的内存,通常会导致系统性能下降。
书中原文:
Oracle
For Statement and CallableStatement, the Oracle JDBC Driver doesn’t actually support batching For anything but PreparedStatement, the driver ignores batching, and each statement is executed separately.
然后我又去了官方文档找了一下:http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraperf.htm#JJDBC28752
文档提及
The Oracle implementation of standard update batching does not implement true batching for generic statements and callable statements. Even though Oracle JDBC supports the use of standard batching for Statement and CallableStatement objects, you are unlikely to see performance improvement.
因为我说的不一定正确,书中也不一定正确,所以官方文档是最靠谱的。下面我解析其他数据库厂商的实现再不会贴英文了,但是我会将官方文档贴链接贴着,方便你去查证。
对于Mysql:
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-configuration-properties.html
Mysql默认是没有将多条语句合成一个batch发送给数据库。但是为了达到batch,驱动提供了一个属性rewriteBatchedStatements,当设置为true的时候,你的批处理才会生效,不然你用框架傻傻的写代码,然后会发现怎么性能没上来,换个框架还是没有上来。其实在你jdbc.url拼接的时候加上rewriteBatchedStatements=true就大大的提升了性能了。我就在网上随便找一条sample
master.jdbc.url=jdbc:mysql://112.126.84.3:3306/platform?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
但是这个参数也会带来一定副作用。但是根据官文我也不是很了解是什么意思,如果你知道,评论区留言一下让我知道。
Bulk Operations的操作性能会比batch update好,但是灵活性不如batch update.工作当中我也没涉及到这一块。
主键的生成通常都交给数据库,但是如果获取回生成的主键呢。
通过PrepareStatment有三种方式:
第一种:
PreparedStatement postStatement = connection.prepareStatement(
"INSERT INTO post (title, version) VALUES (?, ?)",
Statement.RETURN_GENERATED_KEYS
);
第二种:
PreparedStatement postStatement = connection.prepareStatement(
"INSERT INTO post (title, version) VALUES (?, ?)",
new int[] {1}
);
第三种:
PreparedStatement postStatement = connection.prepareStatement(
"INSERT INTO post (title, version) VALUES (?, ?)",
new String[] {"id"}
);
根据JDBC4.2的规范,每个driver都必须实现supportsGetGeneratedKeys()来说明是否支持获取主键。是不是觉得很有意思。平时写代码的时候根本没有注意这一块。但是这个对于Statment是强制性要求的,但是对于PrepareStatment是没有要求的。下图算是拓展知识吧。
序列,有一些数据库提供序列就是sequence来将主键的生成和数据插入进行分离。
下面是几种数据分别创表和获取序列的语法
创表:
#Oracle 12c 之前的创建表
CREATE SEQUENCE post_seq;
CREATE TABLE post (
id NUMBER(19,0) NOT NULL, title VARCHAR2(255 CHAR), version NUMBER(10,0) NOT NULL, PRIMARY KEY (id));
CREATE OR REPLACE TRIGGER post_identity BEFORE INSERT ON post
FOR EACH ROW
BEGIN
SELECT post_seq.NEXTVAL INTO :NEW.id
FROM dual;
end;
#Oracle 12c 之后
CREATE TABLE post (
id NUMBER(19,0) NOT NULL GENERATED ALWAYS AS IDENTITY, title VARCHAR2(255 CHAR),
version NUMBER(10,0) NOT NULL,
PRIMARY KEY (id));
SQL Server
CREATE TABLE post (
id BIGINT IDENTITY NOT NULL,
title VARCHAR(255),
version INT NOT NULL,
PRIMARY KEY (id));
PostgreSQL 9.5
CREATE TABLE post (
id SERIAL NOT NULL,
title VARCHAR(255),
version INT4 NOT NULL,
PRIMARY KEY (id)
);
#另外一种创表
CREATE TABLE post (
id INTEGER DEFAULT NEXTVAL('post_id_seq') NOT NULL, title VARCHAR(255),
version INT4 NOT NULL,
PRIMARY KEY (id));
);
MysSQL 5.7
CREATE TABLE post (
id BIGINT NOT NULL AUTO_INCREMENT,
title VARCHAR(255),
version INTEGER NOT NULL,
PRIMARY KEY (id));
获取序列:
#Oracle
SELECT post_seq.NEXTVAL FROM dual;
#SQL Server
SELECT NEXT VALUE FOR post_seq;
#PostgreSQL
SELECT NEXTVAL('post_seq');
可以看到PostgresSQL使用SERIAL,底层还是用序列实现。
下一篇我会聊一下Statement Caching 语句缓存。
相关推荐
- 全局和隐式 using 指令详解(全局命令)
-
1.什么是全局和隐式using?在.NET6及更高版本中,Microsoft引入了...
- 请停止微服务,做好单体的模块化才是王道:Spring Modulith介绍
-
1、介绍模块化单体是一种架构风格,代码是根据模块的概念构成的。对于许多组织而言,模块化单体可能是一个很好的选择。它有助于保持一定程度的独立性,这有助于我们在需要的时候轻松过渡到微服务架构。Spri...
- ASP.NET程序集引用之痛:版本冲突、依赖地狱等解析与实战
-
我是一位多年后端经验的工程师,其中前几年用ASP.NET...
- .NET AOT 详解(.net 6 aot)
-
简介AOT(Ahead-Of-TimeCompilation)是一种将代码直接编译为机器码的技术,与传统的...
- 一款基于Yii2开发的免费商城系统(一款基于yii2开发的免费商城系统是什么)
-
哈喽,我是老鱼,一名致力于在技术道路上的终身学习者、实践者、分享者!...
- asar归档解包(游戏arc文件解包)
-
要学习Electron逆向,首先要有一个Electron开发的程序的发布的包,这里就以其官方的electron-quick-start作为例子来进行一下逆向的过程。...
- 在PyCharm 中免费集成Amazon CodeWhisperer
-
CodeWhisperer是Amazon发布的一款免费的AI编程辅助小工具,可在你的集成开发环境(IDE)中生成实时单行或全函数代码建议,帮助你快速构建软件。简单来说,AmazonCodeWhi...
- 2014年最优秀JavaScript编辑器大盘点
-
1.WebstormWebStorm是一种轻量级的、功能强大的IDE,为Node.js复杂的客户端开发和服务器端开发提供完美的解决方案。WebStorm的智能代码编辑器支持JavaScript,...
- 基于springboot、tio、oauth2.0前端vuede 超轻量级聊天软件分享
-
项目简介:基于JS的超轻量级聊天软件。前端:vue、iview、electron实现的PC桌面版聊天程序,主要适用于私有云项目内部聊天,企业内部管理通讯等功能,主要通讯协议websocket。支持...
- JetBrains Toolbox推出全新产品订阅授权模式
-
捷克知名软件开发公司JetBrains最为人所熟知的产品是Java编程语言开发撰写时所用的集成开发环境IntelliJIDEA,相信很多开发者都有所了解。而近期自2015年11月2日起,JetBr...
- idea最新激活jetbrains-agent.jar包,亲测有效
-
这里分享一个2019.3.3版本的jetbrains-agent.jar,亲测有效,在网上找了很多都不能使用,终于找到一个可以使用的了,这里分享一下具体激活步骤,此方法适用于Jebrains家所有产品...
- CountDownTimer的理解(countdowntomars)
-
CountDownTimer是android开发常用的计时类,按照注释中的说明使用方法如下:kotlin:object:CountDownTimer(30000,1000){...
- 反射为什么性能会很慢?(反射时为什么会越来越长)
-
1.背景前段时间维护一个5、6年前的项目,项目总是在某些功能使用上不尽人意,性能上总是差一些,仔细过了一下代码发现使用了不少封装好的工具类,工具类里面用了好多的反射,反射会影响到执行效率吗?盲猜了一...
- btrace 开源!基于 Systrace 高性能 Trace 工具
-
介绍btrace(又名RheaTrace)是抖音基础技术团队自研的一款高性能AndroidTrace工具,它基于Systrace实现,并针对Systrace不足之处加以改进,核心改进...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- .NET 奇葩问题调试经历之3——使用了grpc通讯类库后,内存一直增长......
- 全局和隐式 using 指令详解(全局命令)
- 请停止微服务,做好单体的模块化才是王道:Spring Modulith介绍
- ASP.NET程序集引用之痛:版本冲突、依赖地狱等解析与实战
- .NET AOT 详解(.net 6 aot)
- 一款基于Yii2开发的免费商城系统(一款基于yii2开发的免费商城系统是什么)
- asar归档解包(游戏arc文件解包)
- 在PyCharm 中免费集成Amazon CodeWhisperer
- 2014年最优秀JavaScript编辑器大盘点
- 基于springboot、tio、oauth2.0前端vuede 超轻量级聊天软件分享
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)