本文与大家讨论如何实现 MySql 响应式交互。
Data R2DBC 项目是一个提供的数据库反应式编程框架。R2DBC 是 . R2DBC 是一个 API 规范倡议,它声明了一个由驱动程序供应商实现的反应式 API,并以反应式编程方式访问他们的关系数据库。为数据库实现反应式编程并不容易。传统的 JDBC 协议是一个完全阻塞的 API,所以反应式编程可以说是对 JDBC 协议的“颠覆”。
这里再次强调反应式编程。反应式编程是一种非阻塞的异步编程模式,反应式编程提供了一种友好、直观、易于理解的编码模式来处理异步结果(参考上一篇)。也就是说,应用程序向数据库发送SQL后,应用程序线程不需要阻塞等待数据库返回结果,而是直接返回处理其他任务。数据库SQL处理完成后,调用线程处理结果。
到目前为止,Data R2DBC 项目支持以下数据库:
H2 (io.r2dbc:r2dbc-h2)
(org.:r2dbc-)
SQL (io.r2dbc:r2dbc-mssql)
MySQL (dev.miku:r2dbc-mysql)
-sql MySQL (com..-sql:-r2dbc-mysql)
(io.r2dbc:r2dbc-)
(com…r2dbc:-r2dbc)
下面基于MySql,介绍如何使用Data R2DBC。
导入依赖
org.springframework.boot
spring-boot-starter-data-r2dbc
dev.miku
r2dbc-mysql
0.8.2.RELEASE
配置文件
spring.r2dbc.url=r2dbcs:mysql://127.0.0.1:3306/bin-springreactive?useSSL=false
spring.r2dbc.username=...
spring.r2dbc.password=...
Data R2DBC 可以与 Data JPA 结合使用。其实R2DBC的使用和原来的JPA没有太大区别,使用起来也很简单。只是 Data JPA 中的方法返回真实值,而在 R2DBC 中,返回数据流 Mono 和 Flux。
简单介绍一个Data JPA。Data JPA是在ORM框架和JPA规范的基础上封装的一套JPA(Java API)应用框架。简而言之,它是一个类似的框架(Data JPA 底层操作数据库)。
它是Data R2DBC中的一个重要概念,它封装了一个实体的操作,相当于一个dao(Data安卓连接mysql数据库,数据访问对象)。
如果应用中有实体,对应的表。实体定义如下:
public class DeliveryCompany {
@Id
private long id;
private String name;
private String label;
private Integer level;
...
}
@Id 注释标记 id 属性。
下面我们定义一个继承自and的itory接口。
@Repository
public interface DeliveryCompanyRepository extends R2dbcRepository {
...
}
就是实现的接口,继承自ry,ry接口提供了增删改查的模板方法。
public interface ReactiveCrudRepository extends Repository {
Mono save(S var1);
Flux saveAll(Iterable var1);
Flux saveAll(Publisher var1);
Mono findById(ID var1);
Mono findById(Publisher var1);
...
}
注意这里返回的结果是 Mono 和 Flux 等异步结果。这是响应式交互和非响应式交互的最大区别。
如果要自定义操作,有以下几种方式:
(1) 由方法名定义
只要我们通过规则定义方法名,就会为我们生成 SQL。
// 按名称查找
Flux findByName(String name);
// 查找给定范围内的
Flux findByIdGreaterThan(Long startId);
// 查找大于给定id的数据
Flux findByIdGreaterThan(Long startId);
// 查询名称以给定字符串开头的数据
Flux findByNameStartingWith(String start);
// 分页
Flux findByIdGreaterThanEqual(Long startId, Pageable pageable);
注意以上方法名需要根据规范定义
findByName -> findBy
findByIdGreaterThan -> findByGreaterThan
它会为我们生成相应的SQL,非常方便。这种方法可以满足大多数简单的查询。
对应删除操作
Mono deleteByName(String name);
详细的方法命名规则请参考官方文档。
(2)手动写SQL
对于复杂的SQL,开发者也可以手写SQL,
@Query("select id,name from delivery_company where id in (:ids)")
Flux findByIds2(List ids);
@Query("select id,name from delivery_company where name = :name")
Flux findByName2(String name);
@Modifying
@Query("update delivery_company set name = :name where id = :id")
Mono update2(@Param("id") long id, @Param("name") String name);
可以看到,写SQL也很简单,对设置参数的支持也很好。
没有办法使用JPQL(Java Query),但是使用原生SQL是没有问题的。
如果你用过,应该用过下面这个判断参数不为空的方法
SELECT * FROM delivery_company
WHERE name = #{name}
AND label like #{label}
可惜JPA没有办法支持。如果有同学知道,请不吝赐教。
(3) 使用
或者,可以使用自动生成的 SQL
@Autowired
private R2dbcEntityTemplate template;
public Flux getByName3(String name) {
return template
.select(DeliveryCompany.class)
.from("delivery_company")
.matching(Query.query(Criteria.where("name").is(name))).all();
// Criteria.where("name").is(name).and
}
public Mono update3(DeliveryCompany company) {
return template
.update(DeliveryCompany.class)
.inTable("delivery_company")
.matching(Query.query(Criteria.where("id").is(company.getId())))
.apply(Update.update("name", company.getName()));
}
该方法可以实现判断参数不是空查询,但是使用起来比较复杂(我们也可以封装起来方便我们使用)。
(4)Data R2DBC中也支持,我们定义的可以继承自,该接口提供以下模板方法
public interface ReactiveQuerydslPredicateExecutor {
Mono findOne(Predicate var1);
Flux findAll(Predicate var1);
Flux findAll(Predicate var1, Sort var2);
Flux findAll(Predicate var1, OrderSpecifier... var2);
Flux findAll(OrderSpecifier... var1);
Mono count(Predicate var1);
Mono exists(Predicate var1);
}
Data R2DBC中也支持@注解,这里不再深入。
Data R2DBC支持事务,用法很简单,业务方法加@即可
@Transactional
public Flux save(List companyList) {
Flux result = Flux.just();
for (DeliveryCompany deliveryCompany : companyList) {
result = result.concat(result, repository.save(deliveryCompany));
}
return result;
}
为了演示事务的使用,没有调用方法,而是循环插入数据并返回最终结果。注意最终结果 Flux 和 Mono 必须作为方法返回值安卓连接mysql数据库,因为反应式编程的异常信息存储在这些结果中(而不是在方法被调用时抛出),所以这些结果必须作为方法返回值,否则无法知道方法是否报错,事务无法回滚。
Data R2DBC与Data JPA的使用基本相同,所以本文主要是介绍Data JPA的使用。
我以前没有使用过 Data JPA。本文主要是介绍。还有很多东西没有涉及到,比如id生成、多表查询等,这里就不做介绍了。
文章来源:http://www.toutiao.com/a6984373796518035982/