简介

上篇文章咱们讲到了怎么在Spring webFlux中应用r2dbc,明天咱们看一下怎么应用spring-data-r2dbc这个Spring data对r2dbc的封装来进行r2dbc操作。

依赖关系

要应用Spring-datea-r2dbc须要配置上面的依赖关系:

    <dependencies>        <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-data-r2dbc</artifactId>        <version>2.3.3.RELEASE</version>    </dependency>        <!-- R2DBC H2 Driver -->        <dependency>            <groupId>io.r2dbc</groupId>            <artifactId>r2dbc-h2</artifactId>            <version>${r2dbc-h2.version}</version>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-webflux</artifactId>        </dependency>

数据库连贯配置

Spring-data-r2dbc应用的是R2dbcProperties来进行配置文件的读取:

简略看一下R2dbcProperties的定义:

@ConfigurationProperties(prefix = "spring.r2dbc")public class R2dbcProperties {    /**     * Database name. Set if no name is specified in the url. Default to "testdb" when     * using an embedded database.     */    private String name;    /**     * Whether to generate a random database name. Ignore any configured name when     * enabled.     */    private boolean generateUniqueName;    /**     * R2DBC URL of the database. database name, username, password and pooling options     * specified in the url take precedence over individual options.     */    private String url;    /**     * Login username of the database. Set if no username is specified in the url.     */    private String username;    /**     * Login password of the database. Set if no password is specified in the url.     */    private String password;

相应的,看一下咱们的配置文件是怎么样的:

spring.r2dbc.url=r2dbc:h2:mem://./testdbspring.r2dbc.username=saspring.r2dbc.password=password

这里,咱们应用的是H2数据库。

数据库初始化

数据库初始化过程中,咱们须要创立一个users表格,这里咱们在一个initDatabase bean中实现:

    @Bean    public ApplicationRunner initDatabase(DatabaseClient client, UsersDao usersDao) {        List<String> statements = Arrays.asList(                "DROP TABLE IF EXISTS USERS;",                "CREATE TABLE IF NOT EXISTS USERS ( id SERIAL PRIMARY KEY, firstname VARCHAR(100) NOT NULL, lastname VARCHAR(100) NOT NULL);");        statements.forEach(sql -> executeSql(client,sql)                .doOnSuccess(count -> log.info("Schema created, rows updated: {}", count))                .doOnError(error -> log.error("got error : {}",error.getMessage(),error))                .subscribe()        );        return args ->getUser().flatMap(usersDao::save).subscribe(user -> log.info("User saved: {}", user));    }    private Flux<Users> getUser() {        return Flux.just(new Users(null, "John", "Doe"), new Users(null, "Jane", "Doe"));    }    private Mono<Integer> executeSql(DatabaseClient client, String sql) {        return client.execute(sql).fetch().rowsUpdated();    }

下面的例子中,咱们创立数据库分为了两局部,第一局部是数据库schema的操作,咱们执行了drop和create table的操作。

第二局部是向数据库表中插入数据。

留神,下面的两局部操作都须要执行subscribe操作,以触发真正的Reactive操作。

DAO操作

在DAO操作之前,咱们须要创立Users entity:

@Data@AllArgsConstructorpublic class Users {    @Id    private Integer id;    private String firstname;    private String lastname;    boolean hasId() {        return id != null;    }}

再看一下咱们创立的UserDao:

public interface UsersDao extends ReactiveCrudRepository<Users, Long> {    @Query("select id, firstname, lastname from users c where c.lastname = :lastname")    Flux<Users> findByLastname(String lastname);}

留神,这里并不需要增加@Component注解,因为咱们继承了ReactiveCrudRepository,会主动帮咱们创立UsersDao的实例,咱们间接应用就能够了。

ReactiveCrudRepository为咱们封装了一些DAO的基本操作,比方save,saveAll, findById ,existsById等根底操作。

当然,咱们也能够自定义本人的SQL语句,比方下面的findByLastname。

Service操作和Transaction

咱们看一下怎么应用UserDao来进行具体的办法操作:

@Componentpublic class UsersService {    @Resource    private UsersDao usersDao;    @Transactional    public Mono<Users> save(Users user) {        return usersDao.save(user).map(it -> {            if (it.getFirstname().equals("flydean")) {                throw new IllegalStateException();            } else {                return it;            }        });    }}

下面咱们创立了一个save办法,用来保留相应的User对象。

controller

最初,咱们创立一个controller来对外裸露相应的办法:

@RestController@RequiredArgsConstructorpublic class UsersController {    private final UsersDao usersDao;    @GetMapping("/users")    public Flux<Users> findAll() {        return usersDao.findAll();    }}

测试

好了,当初咱们的程序曾经写好了,能够进行测试了。

运行程序,执行:

curl "localhost:8080/users"    [{"id":1,"firstname":"John","lastname":"Doe"},{"id":2,"firstname":"Jane","lastname":"Doe"}]%       

能够看到取出了相应的后果。

完满,试验胜利。

本文的代码:spring-data-r2dbc

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/spring-data-r2dbc/

本文起源:flydean的博客

欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!