中如何实现MySql响应式编程框架(DataR2DBC)应用框架

本文与大家讨论如何实现 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/

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享