【SpringBoot DB 系列】Jooq 之新增记录使用姿势
【SpringBoot DB 系列】Jooq 之新增记录使用姿势
接下来我们开始进入 jooq 的增删改查的使用姿势系列,本篇将主要介绍如何利用 jooq 来实现添加数据
<!-- more -->
I. 项目搭建
本项目借助SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
进行开发
1. 项目依赖
关于如何创建一个 SpringBoot 的项目工程,不再本文的描述范围内,如有兴趣可以到文末的个人站点获取
在这个示例工程中,我们的选用 h2dabase 作为数据库(方便有兴趣的小伙伴直接获取工程源码之后,直接测试体验),因此对应的 pom 核心依赖如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
2. 数据库初始化
我们借助jooq-codegen-maven
插件来自动生成数据库相关的代码,对这一段逻辑感兴趣的小伙伴可以参考博文:【DB 系列】Jooq 代码自动生成
后文中使用的表结构如下
DROP TABLE IF EXISTS poet;
CREATE TABLE poet (
`id` int NOT NULL,
`name` varchar(20) NOT NULL default '',
CONSTRAINT pk_t_poet PRIMARY KEY (ID)
);
DROP TABLE IF EXISTS poetry;
CREATE TABLE poetry (
`id` int NOT NULL,
`poet_id` int NOT NULL default '0',
`title` varchar(128) not null default '',
`content` varchar(128) not null default '',
CONSTRAINT pk_t_poetry PRIMARY KEY (ID)
);
3. 配置文件
h2database 的连接配置如 application.properties
#Database Configuration
spring.datasource.url=jdbc:h2:~/h2-jooq-poet
spring.datasource.username=test
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
#jOOQ Configuration
spring.jooq.sql-dialect=H2
spring.datasource.initialization-mode=never
spring.datasource.continueOnError=true
##h2 web console设置
spring.datasource.platform=h2
#进行该配置后,h2 web consloe就可以在远程访问了。否则只能在本机访问。
spring.h2.console.settings.web-allow-others=true
#进行该配置,你就可以通过YOUR_URL/h2访问h2 web consloe
spring.h2.console.path=/h2
#进行该配置,程序开启时就会启动h2 web consloe
spring.h2.console.enabled=true
II. 新增记录
接下来我们进入正式的数据插入的使用姿势介绍,一般来说新增数据会区分单个和批量两种方式,下面我们分别进行介绍
1. Record 实体类新增方式
在 jooq 中,借助自动生成的 Record 类来实现新增是最简单的 case,如下
private static final PoetTB table = PoetTB.POET;
@Autowired
private DSLContext dsl;
/**
* 新增记录
*
* @param id
* @param name
* @return
*/
public boolean save(int id, String name) {
PoetPO record = dsl.newRecord(table);
record.setId(id);
record.setName(name);
return record.insert() > 0;
}
注意:
- 实体类的创建方式:
PoetPO record = dsl.newRecord(table);
,不要直接 new 一个对象出来使用
2. 链式写法
下面介绍的这种写法和 sql 非常相似,也是我个人用的比较多的方式,特点就是一目了然
public boolean save2(int id, String name) {
return dsl.insertInto(table).set(table.ID, id).set(table.NAME, name).execute() > 0;
}
3. InsertQuery 方式
上面两种写法比较常见,而直接使用 InsertQuery 的方式,在实际的业务开发中可能并没有上面的优雅,但某些特殊场景下还是很有用的
/**
* 不使用自动生成的代码来原生插入数据
*
* @param id
* @param name
* @return
*/
public boolean save3(int id, String name) {
// 当不使用自动生成的对象时,table可以用 DSL.table()指定,列可以用 DSL.field()指定
InsertQuery insertQuery = dsl.insertQuery(DSL.table("poet"));
insertQuery.addValue(DSL.field("id", Integer.class), id);
insertQuery.addValue(DSL.field("name", String.class), name);
return insertQuery.execute() > 0;
}
注意一下上面的用法,InsertQuery
本身的使用没有什么值得说到的,重点在上面的实现中,并没有利用自动生成的代码,如
- table:
DSL.table(表名)
- field:
DSL.field(列名,类型)
通过上面的的 case,我们可以知道在不自动生成 DB 对应的代码前提下,如何进行数据库的操作
4. Record 实体批量保存
借助dsl.batchInsert
来批量添加实体,属于最基础的使用姿势了
private PoetPO bo2po(PoetBO bo) {
PoetPO po = dsl.newRecord(table);
po.setId(bo.getId());
po.setName(bo.getName());
return po;
}
/**
* 通过Record执行批量添加
*
* @param list
* @return
*/
public boolean batchSave(List<PoetBO> list) {
List<PoetPO> poList = list.stream().map(this::bo2po).collect(Collectors.toList());
int[] ans = dsl.batchInsert(poList).execute();
System.out.println(JSON.toJSONString(ans));
return true;
}
5. 链式批量保存
同样是类 sql 的链式插入方式,需要注意一下与前面的单条记录的链式插入的区别,下面这种写法和 sql 的批量插入的写法及其相似
/**
* 类sql写法,批量添加
*
* @param list
* @return
*/
public boolean batchSave2(List<PoetBO> list) {
InsertValuesStep2<PoetPO, Integer, String> step = dsl.insertInto(table).columns(table.ID, table.NAME);
for (PoetBO bo : list) {
step.values(bo.getId(), bo.getName());
}
return step.execute() > 0;
}
6. InsertQuery 批量保存
上面介绍了 InsetQuery 的单条插入方式,下面的批量写法基本上没有太大的区别
/**
* 不基于自动生成的代码,来批量添加数据
*
* @param list
* @return
*/
public boolean batchSave3(List<PoetBO> list) {
InsertQuery insertQuery = dsl.insertQuery(DSL.table("poet"));
for (PoetBO bo : list) {
insertQuery.addValue(DSL.field("id", Integer.class), bo.getId());
insertQuery.addValue(DSL.field("name", String.class), bo.getName());
insertQuery.newRecord();
}
return insertQuery.execute() > 0;
}
7. 测试 case
接下来测试一下上面的 6 个方法执行
public void test() {
this.save(11, "一灰");
this.save2(12, "一灰灰");
this.save3(13, "一灰灰Blog");
this.batchSave(Arrays.asList(new PoetBO(14, "yh"), new PoetBO(15, "yhh")));
this.batchSave2(Arrays.asList(new PoetBO(16, "yihui"), new PoetBO(17, "yihuihui")));
this.batchSave3(Arrays.asList(new PoetBO(18, "YiHui"), new PoetBO(19, "YiHuiBlog")));
RecordMapper<PoetPO, PoetBO> mapper =
dsl.configuration().recordMapperProvider().provide(table.recordType(), PoetBO.class);
List<PoetBO> result = dsl.selectFrom(table).fetch().map(mapper);
System.out.println(result);
}
输出结果如下
[1,1]
[PoetBO (1, 李白), PoetBO (2, 艾可翁), PoetBO (11, 一灰), PoetBO (12, 一灰灰), PoetBO (13, 一灰灰Blog), PoetBO (14, yh), PoetBO (15, yhh), PoetBO (16, yihui), PoetBO (17, yihuihui), PoetBO (18, YiHui), PoetBO (19, YiHuiBlog)]
II. 其他
0. 项目
系列博文
项目源码
- 工程:https://github.com/liuyueyi/spring-boot-demo
- 项目源码:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/108-jooq-curd
1. 一灰灰 Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
- 一灰灰 Blog 个人博客 https://blog.hhui.top
- 一灰灰 Blog-Spring 专题博客 http://spring.hhui.top
- 用 TensorFlow 让你的机器人唱首原创给你听
- Spring Cloud限流详解(附源码)
- 手动安装Docker 17.06
- 详述使用 IntelliJ IDEA 解决 jar 包冲突的问题
- Spring Cloud各组件重试总结
- js或者php浮点数运算产生多位小数的理解
- 纠错帖:Zuul & Spring Cloud Gateway & Linkerd性能对比
- 你知道 Python 这五个有趣的彩蛋吗?
- [图解DS基础概念]Critical value,Alpha,Z-score,P-value 关系
- Docker系列教程02-Docker安装(CentOS7/Ubuntu/macOS/Windows)
- Docker系列课程01-Docker简介
- document.ready 与 window.onload的区别
- react+redux+webpack教程1
- LINC switch系列之配置与运行
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 测试仓库推介(下)
- 如何进行数据标注(1)
- 百度黄埔学院:交通枢纽高密人流下的防疫筛查解决方案技术理解(1)
- 百度黄埔学院:交通枢纽高密人流下的防疫筛查解决方案技术理解(2)
- 百度黄埔学院:十行代码高效完成深度学习POC
- 【数据相关】目标检测中的数据标注及格式转换代码
- 科学与艺术的融合:遗传算法绘制蒙娜丽莎
- “工业听诊”中多声源事件检测与定位
- 工业党福利:使用PaddleX高效实现指针型表计读取系列文章(2)
- 【三维点云系列】PCL点云库之数据文件与IO操作
- Jvm故障处理工具
- 递增子序列
- redis学习(二)
- You-Get 使用方法
- 接口测试 Mock 实战 | 结合 jq 完成批量化的手工 Mock