Spring Boot 3.2 新特性:JdbcClient
👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
《项目实战(视频)》:从书中学,往事上“练” 《互联网高频面试题》:面朝简历学习,春暖花开 《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题 《精进 Java 学习指南》:系统学习,互联网主流技术栈 《必读 Java 源码专栏》:知其然,知其所以然
👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:
Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud 视频教程:https://doc.iocoder.cn 【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本
SpringBoot 3.2引入了新的 JdbcClient 用于数据库操作,JdbcClient对JdbcTemplate进行了封装,采用了 fluent API 的风格,可以进行链式调用。
自此,spring自带的数据库操作有了4种方式:JdbcTemplate、JdbcClient、SpringDataJdbc、SpringDataJpa。
对于不适合使用复杂的ORM框架,或者需要编写复杂的SQL的场景,可以使用JdbcClient自己编写SQL来操作数据库。不过JdbcClient不支持数据的批量操作和存储过程调用,对于这种情况就需要使用JdbcTemplate。
具体的代码参照示例项目:https://github.com/qihaiyan/springcamp/tree/master/spring-data-jdbc-client
一、概述
JdbcClient是一个轻量的数据库操作框架,采用 fluent API 风格,简单灵活,易于阅读和维护,支持编写复杂的SQL。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro 视频教程:https://doc.iocoder.cn/video/
二、引入 JdbcClient
首先引入 spring-data-jdbc 依赖。
在 build.gradle 中增加一行代码:
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
在Service中直接注入JdbcClient即可:
@Component
public class DbService {
@Autowired
private JdbcClient jdbcClient;
}
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud 视频教程:https://doc.iocoder.cn/video/
三、查询操作
通过JdbcClient,可以按照主键查数据,也可以按照自定义查询条件查数据。
按照主键查数据:
public MyData findDataById(Long id) {
return jdbcClient.sql("select * from my_data where id = ?")
.params(id)
.query(MyData.class)
.single();
}
按照自定义查询条件查数据:
public List<MyData> findDataByName(String name) {
return jdbcClient.sql("select * from my_data where name = ?")
.params(name)
.query(MyData.class)
.list();
}
以上两种查询方式,查询条件中的变量使用的是占位符,JdbcClient也支持按照参数名进行查询:
public Integer insertDataWithNamedParam(MyData myData) {
Integer rowsAffected = jdbcClient.sql("insert into my_data values(:id,:name) ")
.param("id", myData.id())
.param("name", myData.name())
.update();
return rowsAffected;
}
当参数比较多时,可以将参数放到一个Map中,用Map进行查询:
public List<MyData> findDataByParamMap(Map<String, ?> paramMap) {
return jdbcClient.sql("select * from my_data where name = :name")
.params(paramMap)
.query(MyData.class)
.list();
}
当查询返回的结果不能简单的映射到一个类时,可以编写RowMapper,适用于SQL语句比较复杂的场景:
public List<MyData> findDataWithRowMapper() {
return jdbcClient.sql("select * from my_data")
.query((rs, rowNum) -> new MyData(rs.getLong("id"), rs.getString("name")))
.list();
}
同时也支持查询记录数:
public Integer countByName(String name) {
return jdbcClient.sql("select count(*) from my_data where name = ?")
.params(name)
.query(Integer.class)
.single();
}
四、插入数据
可以使用 JdbcClient 的 update 方法进行数据的插入和更新。
通过占位符参数插入数据:
public Integer insertDataWithParam(MyData myData) {
Integer rowsAffected = jdbcClient.sql("insert into my_data values(?,?) ")
.param(myData.id())
.param(myData.name())
.update();
return rowsAffected;
}
通过命名参数插入数据:
public Integer insertDataWithNamedParam(MyData myData) {
Integer rowsAffected = jdbcClient.sql("insert into my_data values(:id,:name) ")
.param("id", myData.id())
.param("name", myData.name())
.update();
return rowsAffected;
}
直接插入整个对象:
public Integer insertDataWithObject(MyData myData) {
Integer rowsAffected = jdbcClient.sql("insert into my_data values(:id,:name) ")
.paramSource(myData)
.update();
return rowsAffected;
}
五、总结
通过上述的示例,可以看到基本的数据库操作都可以用 JdbcClient 实现,避免了复杂的ORM框架的使用,切操作要比ORM框架简单灵活的多。fluent API 的风格也更容易编写和阅读。
完整的数据库操作方法的调用演示:
@Slf4j
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private DbService dbService;
@Override
public void run(String... args) {
MyData myData = new MyData(1L, "test");
log.info("insert rows: {}", dbService.insertDataWithObject(myData));
MyData myData2 = new MyData(2L, "test");
dbService.insertDataWithParam(myData2);
MyData myData3 = new MyData(3L, "author");
dbService.insertDataWithNamedParam(myData3);
log.info("findDataById: {}", dbService.findDataById(1L));
log.info("findDataByName: {}", dbService.findDataByName("test"));
log.info("findDataWithRowMapper: {}", dbService.findDataWithRowMapper());
log.info("findDataByParamMap: {}", dbService.findDataByParamMap(Map.of("name", "author")));
log.info("countByName: {}", dbService.countByName("test"));
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
微信扫码关注该文公众号作者