告别 JdbcTemplate,SpringBoot 新特性:JdbcClient 更强大

点击关注公众号,Java干货及时送达👇

SpringBoot 3.2 引入了JdbcClient API组件可以对数据库操作,实际上JdbcClient是在JdbcTemplate基础上进行了封装。

SpringBoot 3.2引入了新的 JdbcClient 用户数据库操作,JdbcClient对JdbcTemplate进行了封装,采用了 fluent API 的风格,可以进行链式调用。

自此,spring自带的数据库操作有了4种方式:

  • JdbcTemplate

  • JdbcClient

  • SpringDataJdbc

  • SpringDataJpa

对于不适合使用复杂的ORM框架,或者需要编写复杂的SQL的场景,可以使用JdbcClient自己编写SQL来操作数据库。不过JdbcClient不支持数据的批量操作和存储过程调用,对于这种情况就需要使用JdbcTemplate。

一、概述

JdbcClient是一个轻量的数据库操作框架,采用 fluent API 风格,简单灵活,易于阅读和维护,支持编写复杂的SQL。

二、引入 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;
}

三、查询操作

通过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);
  }
}

来源|https://springcamp.cn

 
 
 
 

ef09104d945d728655f4003d2ba2933c.gif

 
 

不好意思,ELK 该换了!

if 判断泛滥?试一试规则执行器,太香了!

为什么游戏公司不使用微服务架构

推荐给你3个完美替代 Navicat 的工具

 
 
 
 
 
 
 
 
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值