Spring Boot WebFlux source operand data integration Mongodb

WebFlux integration Mongodb

Foreword

A talk on the data stored in the memory of formula Map data structure. Such data will not persist, the paper we use MongoDB to achieve WebFlux operations on the data source.

What is MongoDB?

Official website: https: //www.mongodb.com/

MongoDB is based on a distributed file storage database, compiled by the C ++ language, designed to provide scalable WEB application for high-performance data storage solutions.

MongoDB is a product with function between relational databases and non-relational databases, non-relational database functions among the richest and most like a relational database.

Due to ease of operation, we start with a MognoDB service Docker. If Docker is not installed, please refer to the text: Docker installation and basic operation https://www.jianshu.com/p/f272726db9c5

Docker MognoDB installation and start as follows:

1. Create a mount directory

docker volume create mongo_data_db
docker volume create mongo_data_configdb复制代码

2, start MognoDB

docker run -d \
    --name mongo \
    -v mongo_data_configdb:/data/configdb \
    -v mongo_data_db:/data/db \
    -p 27017:27017 \
    mongo \
    --auth复制代码

3, initialize the administrator account

docker exec -it mongo     mongo              admin
                        // 容器名   // mongo命令 数据库名

# 创建最高权限用户
db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "root", db: "admin" } ] });复制代码

4, testing connectivity

docker run -it --rm --link mongo:mongo mongo mongo -u admin -p admin --authenticationDatabase admin mongo/admin复制代码

MognoDB basic operations:

Similarly MySQL command to display the library list:

show dbs复制代码

Using a database

use admin复制代码

Display table list

show collections复制代码

If the table exists city, city format table contents display

db.city.find().pretty()复制代码

structure

Mentioned above similar engineering structures, preparation of a new project this case. Project Figure:

file

The core directory as follows

  • pom.xml maven configuration
  • application.properties profile
  • dao data access layer, this article points

New POM dependence and configuration

The new configuration dependencies in pom.xml:

    <!-- Spring Boot 响应式 MongoDB 依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
    </dependency>复制代码

Similarly with the MySQL JDBC driver and certainly you have to go to the configuration database. In application.properties configure the startup configuration above MongoDB:

Database named admin, account password also is admin.

spring.data.mongodb.host=localhost
spring.data.mongodb.database=admin
spring.data.mongodb.port=27017
spring.data.mongodb.username=admin
spring.data.mongodb.password=admin复制代码

This is a huge problem, why do not we used MySQL database?

The answer is that Spring Data Reactive Repositories currently supports Mongo, Cassandra, Redis, Couchbase. It does not support MySQL, then what why it? It shows the relationship between JDBC and at the Spring Data.

Spring Data Reactive Repositories salient points are Reactive, that is non-blocking. Differences are as follows:

  • JDBC-based realization of the Spring Data, such as Spring Data JPA is blocked. The principle is blocking IO model based on
    consumption of threads per database call (Connection)
  • In a java.sql.Connection transaction can only use that one transaction operation.

Then how asynchronous JDBC fresh ideas nor non-blocking package, Scala library Slick 3 is realized. Simple implementation works as follows:

  • A transaction multiple operations, then share a java.sql.Connection. You can use a transparent transaction management, programming models use a callback to pass
  • Remains limited idle connections

Finally, I firmly believe that soon there will be a non-blocking JDBC. So we are happy to call a MySQL.

Objects

Modify org.spring.springboot.domain package inside the city entity object class. Modify City (City) Object City, the code is as follows:

import org.springframework.data.annotation.Id;

/**
 * 城市实体类
 *
 */
public class City {

    /**
     * 城市编号
     */
    @Id
    private Long id;

    /**
     * 省份编号
     */
    private Long provinceId;

    /**
     * 城市名称
     */
    private String cityName;

    /**
     * 描述
     */
    private String description;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getProvinceId() {
        return provinceId;
    }

    public void setProvinceId(Long provinceId) {
        this.provinceId = provinceId;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}复制代码

@Id annotation tag database table corresponding to the primary key or a unique identifier. Because this is our DO, Data Access Objects to-one mapping to the data store.

MongoDB data access layer CityRepository

CityRepository modified class code is as follows:

import org.spring.springboot.domain.City;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CityRepository extends ReactiveMongoRepository<City, Long> {

}复制代码

CityRepository as long as the interface class can inherit ReactiveMongoRepository. The default will provide many implementations, such as CRUD implementation and a list of query parameters relevant. ReactiveMongoRepository default implementation of the interface as follows:

    <S extends T> Mono<S> insert(S var1);

    <S extends T> Flux<S> insert(Iterable<S> var1);

    <S extends T> Flux<S> insert(Publisher<S> var1);

    <S extends T> Flux<S> findAll(Example<S> var1);

    <S extends T> Flux<S> findAll(Example<S> var1, Sort var2);复制代码

As shown, ReactiveMongoRepository integration class ReactiveSortingRepository, ReactiveCrudRepository achieve many common interfaces:

file

As shown in FIG ReactiveCrudRepository Interface:file

Further it can be seen, the named interface specification is to follow. Common naming rules are as follows:

  • Keywords :: method named
  • And :: findByNameAndPwd
  • Or :: findByNameOrSex
  • Is :: findById
  • Between :: findByIdBetween
  • Like :: findByNameLike
  • NotLike :: findByNameNotLike
  • OrderBy :: findByIdOrderByXDesc
  • Not :: findByNameNot

Common cases, the code is as follows:

    Flux<Person> findByLastname(String lastname);

    @Query("{ 'firstname': ?0, 'lastname': ?1}")
    Mono<Person> findByFirstnameAndLastname(String firstname, String lastname);

    // Accept parameter inside a reactive type for deferred execution
    Flux<Person> findByLastname(Mono<String> lastname);

    Mono<Person> findByFirstnameAndLastname(Mono<String> firstname, String lastname);

    @Tailable // Use a tailable cursor
    Flux<Person> findWithTailableCursorBy();复制代码

Source level

ReactiveCrudRepository abstraction reactive package, as shown:

file

Here we can see that the reactive support also supported RxJava. Corresponding to the old CrudRepository added ReactiveCrudRepository interfaces and various storage implementation.

And a processor-based controller class Handler Controller

Modifications Handler, the following code:

@Component
public class CityHandler {

    private final CityRepository cityRepository;

    @Autowired
    public CityHandler(CityRepository cityRepository) {
        this.cityRepository = cityRepository;
    }

    public Mono<City> save(City city) {
        return cityRepository.save(city);
    }

    public Mono<City> findCityById(Long id) {

        return cityRepository.findById(id);
    }

    public Flux<City> findAllCity() {

        return cityRepository.findAll();
    }

    public Mono<City> modifyCity(City city) {

        return cityRepository.save(city);
    }

    public Mono<Long> deleteCity(Long id) {
        cityRepository.deleteById(id);
        return Mono.create(cityMonoSink -> cityMonoSink.success(id));
    }
}复制代码

Do not Mono, Flux stranger to him as an object can be. Continue modifications controller class Controller, code is as follows:

@RestController
@RequestMapping(value = "/city")
public class CityWebFluxController {

    @Autowired
    private CityHandler cityHandler;

    @GetMapping(value = "/{id}")
    public Mono<City> findCityById(@PathVariable("id") Long id) {
        return cityHandler.findCityById(id);
    }

    @GetMapping()
    public Flux<City> findAllCity() {
        return cityHandler.findAllCity();
    }

    @PostMapping()
    public Mono<City> saveCity(@RequestBody City city) {
        return cityHandler.save(city);
    }

    @PutMapping()
    public Mono<City> modifyCity(@RequestBody City city) {
        return cityHandler.modifyCity(city);
    }

    @DeleteMapping(value = "/{id}")
    public Mono<Long> deleteCity(@PathVariable("id") Long id) {
        return cityHandler.deleteCity(id);
    }
}复制代码

Run the project

CRUD of Spring Boot Webflux a project on the development is completed, the next run the project under verification. IDEA using the right side of the toolbar, click the Maven Project Tab, click the Maven plugin using the following installcommand. Or use the command line of the form, in the project root directory, execute instructions Maven clean-up and installation of:

cd springboot-webflux-3-mongodb
mvn clean install复制代码

See the success of the output in the console:

... 省略
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:30 min
[INFO] Finished at: 2017-10-15T10:00:54+08:00
[INFO] Final Memory: 31M/174M
[INFO] ------------------------------------------------------------------------复制代码

IDEA performed in the Applicationclass started, the normal mode or any Debug mode. You can see the output of a successful run in the console:

... 省略
2018-04-10 08:43:39.932  INFO 2052 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext     : Started HttpServer on /0:0:0:0:0:0:0:0:8080
2018-04-10 08:43:39.935  INFO 2052 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2018-04-10 08:43:39.960  INFO 2052 --- [           main] org.spring.springboot.Application        : Started Application in 6.547 seconds (JVM running for 9.851)复制代码

Open POST MAN tool for development required. Perform the following actions:

New city information POST http://127.0.0.1:8080/cityfile

Connecting MongoDB, verification data

MongoDB connection

docker run -it --rm --link mongo:mongo mongo mongo -u admin -p admin --authenticationDatabase admin mongo/admin复制代码

file

Display library list:

show dbs复制代码

Using a database

use admin复制代码

Display table list

show collections复制代码

If the table exists city, city format displayed table of contents:

db.city.find().pretty()复制代码

file

to sum up

Here, the Spring WebFlux discuss how to integrate MongoDB. Integration with other storage Cassandra, Redis, Couchbase, on any different. Below, we will be able to integrate Thymeleaf, better page display for everyone. By the way so that we learn the basic usage under Thymeleaf.

This article from the blog article multiple platforms OpenWrite release!

Guess you like

Origin juejin.im/post/5dad6c5d5188257a7306885b