SpringBoot integrated dynamic data sources arranged MyBatisPlus

SpringBoot integrated dynamic data sources arranged MyBatisPlus

Tweets: 2018 China's most popular open source software MyBatis-Plus China

MybatisPlus properties
  • Non-invasive : not only enhance the change, it will not have an impact on the introduction of existing projects, such as silky smooth
  • Loss is small : the basic injection start automatically CURD i.e., substantially no loss of performance, object-oriented operating direct
  • Powerful CRUD operations : built-in universal Mapper, Universal Service, the configuration can be achieved only by a small amount of single-table most of the CRUD operations, more powerful conditions constructors, to meet the various needs
  • Lambda forms of support calls : The Lambda expressions, easy preparation of various types of query conditions, without having to worry about the wrong field
  • Supports multiple databases : support for MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, Postgre, SQLServer2005, SQLServer and other databases
  • Automatic generation of primary key support : supports up to four primary key strategies (Distributed contains a unique ID generator - Sequence), freely configurable, perfect to solve the primary key issue
  • XML support hot load : Mapper corresponding XML support thermal loads, for simple CRUD operations, even without XML start
  • Support ActiveRecord model : ActiveRecord form of support calls, just like an entity class inherits Model can be a powerful CRUD operations
  • Support custom global General Procedure : general procedure supports global injection (Write once, use anywhere)
  • Automatically escaped support Keywords : support database keyword (order, key ......) escaped automatically, you can customize Keywords
  • Built-in code generator : the use of code or Maven plugin can quickly generate Mapper, Model, Service, Controller layer code, support template engine, more and more super custom configuration waiting for you to use
  • Built-in pagination plug-in : after MyBatis based on physical pages, developers need not concern specific operations, configure the plug-in, written paging equivalent to general inquiries List
  • Built-in performance analysis plug-ins : Sql statement can be output as well as its execution time, this feature is enabled recommends that developers test time, can quickly ferret out slow query
  • Built-in global blocking plug-ins : Provide a full table delete, update operational intelligence analysis block, also can customize the blocking rules to prevent misuse
  • Built-Sql injection stripper : Supports Sql injection peel, effectively prevent Sql Injection Attacks
Quick Start

Initialization test data table:

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);
DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

Dependent parent project

The project for dependency management, pom follows:

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        <mybatis-plus-version>3.1.1</mybatis-plus-version>
        <mysql-driver-version>5.1.47</mysql-driver-version>
        <druid-version>1.1.10</druid-version>
 </properties>

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Creating MyBaitsPlus project

Dependent as follows:

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-version}</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-driver-version}</version>
        </dependency>

        <!-- druid数据连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid-version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
 </dependencies>
Configuration properties

Here configure a database connection and a data connection pool configuration and the like mybatisplus

server.port=8080

spring.application.name=mybatis

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.druid.filters=stat,slf4j
spring.datasource.druid.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
spring.datasource.druid.stat-view-servlet.deny=192.168.1.73
spring.datasource.druid.stat-view-servlet.reset-enable=false
#Druid 管理账号
spring.datasource.druid.stat-view-servlet.login-username=admin
#Druid 管理密码
spring.datasource.druid.stat-view-servlet.login-password=123456
#com.simple.spring.boot.mapper 该包打印DEBUG级别日志
logging.level.com.simple.spring.boot.mapper=debug

#mybatis plus mapper文件路径
mybatis-plus.mapperLocations=classpath:/mybatis/mapper/*.xml
#mybaits plus 实体类路径
mybatis-plus.typeAliasesPackage=com.simple.spring.**.entities
mybatis-plus.typeEnumsPackage=
#数据库相关配置
#主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
mybatis-plus.global-config.db-config.id-type=UUID
#字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
mybatis-plus.global-config.db-config.field-strategy=not_empty
#驼峰下划线转换
mybatis-plus.global-config.db-config.column-underline=true
#数据库大写下划线转换
#capital-mode: true
#逻辑删除配置
mybatis-plus.global-config.db-config.logic-delete-value=0
mybatis-plus.global-config.db-config.logic-not-delete-value= 1
#mybatis-plus.global-config.db-config.db-type= sqlserver
#刷新mapper 调试神器
mybatis-plus.global-config.refresh=true
# 原生配置
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
mybatis-plus.configuration.call-setters-on-nulls =true
Conventional implement CRUD

Create entity classes:

**
 * 实体类
 * @author: SimpleWu
 * @date: 2019/5/25
 */
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

The lombokplug-in eliminates the need for getset method.

Creating UserMapperinterfaces, and to achieve BaseMapper<User>this we designated entity class userinterface methods can be used directly.

  • All data query

    public List<User> getList(){
            return userMapper.selectList(null);
    }
  • Query data with query

    public List<User> getListQuery(){
            User user = new User();
            user.setName("SimpleWu");
            Wrapper<User> wrapper = new QueryWrapper<>(user);
            return userMapper.selectList(wrapper);
    }
  • Queries page

    public IPage<User> page(){
            int currentPage = 1 ; //当前页
            int pageSize = 2 ;//每页大小
            IPage<User> page = new Page(currentPage,pageSize);
            page = userMapper.selectPage(page,null);
            return page;
     }
  • The new data entity class

    @Transactional//本地事务开启
    public int insert(){
            User user = new User();
            user.setId(6l);
            user.setName("SimpleWu");
            user.setAge(100);
            user.setEmail("[email protected]");
            return userMapper.insert(user);
     }
  • According to the primary key to delete data

    @Transactional//本地事务开启
     public int deleteById(){
            int userId = 6;
            return userMapper.deleteById(userId);
    }
  • The update data ID

    @Transactional//本地事务开启
     public int updateById(){
            User user = new User();
            user.setId(5l);
            user.setName("update");
            user.setAge(100);
            user.setEmail("[email protected]");
           return userMapper.updateById(user);
    }
  • Conditions constructor

    • UpdateWrapper structural conditions for CRUD
    • QueryWrapper for query construction conditions
    Transactional//本地事务开启
        public int updateWrapperUser(){
            User user = new User();
            user.setId(5l);
            user.setName("update");
            user.setAge(100);
            user.setEmail("[email protected]");
    
            User updateWrapperUser = new User();
            updateWrapperUser.setId(1l);
    
            /**
             * 修改 UpdateWrapper
             * 查询 QueryWrapper
             */
            Wrapper<User> wrapper = new UpdateWrapper<>(updateWrapperUser);
            return userMapper.update(user,wrapper);
     }
  • Mapper Mapper interface binding document

    • In either configuration properites

      #扫描mybatis/mapper下面的所有xml
      mybatis-plus.mapperLocations=classpath:/mybatis/mapper/*.xml
  • UserMapper interface test

public interface UserMapper extends BaseMapper<User> {

    Map<String,Object> queryUser(@Param("USER_ID") String userId);
}

UserMapper.xml, as it follows:

<select id="queryUser" resultType="java.util.HashMap" parameterType="java.lang.String">
        SELECT
          ID,
          NAME
        FROM
          USER
        WHERE ID = #{USER_ID}
</select>

Execute SQL:

public Map<String,Object> myMapper(){
        return userMapper.queryUser("2");
}

In SpringBoot be injected using MybatisPlus tab Bean, and using the starting class @MapperScan("com.simple.spring.boot.mapper")scan file path mapper follows:

@SpringBootApplication
@MapperScan("com.simple.spring.boot.mapper")
public class MybatisPlusApplication {

    /**
     * 分页插件注册
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }

}

Use MyBatisPlus can reduce a lot of our code, but need to write entity classes, there must be lost too.

Dynamic configuration data source

dynamic-datasource-spring-boot-starterIt is based on springbootthe rapid integration of multiple data sources starter.

Advantage

Switching on documentation on dynamic data sources are many, only two core.

  1. Construction of several sets of environment, the advantage is easy to control is also easy to integrate some simple distributed transactions, while more non-dynamic disadvantage of the amount of code, configuration difficult.
  2. Based on spring provides native AbstractRoutingDataSource, referring to some of the documents they achieve switching.

If your data source is less, the scene is not complicated, any more than one can be selected. If you need more features, please try this dynamic data sources.

  1. Packet data source, for a variety of scenes purely docusate separate read and write from a mixed multi-master mode.
  2. Druid simple integration of multiple data sources to monitor data sources, simple integration Mybatis-Plus simplified single table, simple integration P6sy format sql, simple integration Jndi data source.
  3. Druid HikariCp simplify configuration and to provide the global parameters.
  4. Providing custom data source origin (or yml properties using default configuration).
  5. Dynamic data source can increase or decrease after the project started.
  6. Use spel dynamic parameter analysis data sources, such as data acquired from the source session, header and parameters. (Multi-tenant architecture artifact)
  7. The multilayer switching nested data source. (A business ServiceA call ServiceB, ServiceB call ServiceC, each Service is different data sources)
  8. Using regular expressions to match or switching the data source spel (Experimental).

Disadvantaged

You can not use multiple data sources Affairs (under the same transaction can use a data source), other online programs are also not available.

If you need to use distributed transactions, then you should go to the micro-service architecture of the time.

If louder and louder, the project reached 800 star, authors consider the integration of distributed transactions.

PS: If you have just a few database but there is a strong demand for distributed transactions, it is recommended to use traditional methods to build their own sets of environmental integration atomic such, many online Baidu.

Promise

  1. This framework only switching the data source this core of things, and do not limit your specific operation , switching the data source can do any CRUD.
  2. All profiles underscore _split data source 's first name is the group, the same group name of the data source will be placed next group.
  3. Switching the data source to the name of the group, but also specific data source name, using the default load-balancing mechanism to switch when switching.
  4. The default data source name for the Master , you can modify by spring.datasource.dynamic.primary.
  5. Notes on the method takes precedence over the class notes.

Suggest

It is strongly recommended in a master-slave mode to follow the general rules, so that others can more easily understand your code.

Primary database is recommended only perform INSERT UPDATE DELETEoperations.

From the database is recommended only perform SELECToperations.

Quick Start

Add dependency:

<!-- 动态数据源 -->
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>2.5.4</version>
</dependency>

Comment out the original database configuration, adding:

#设置默认的数据源或者数据源组,默认值即为master
spring.datasource.dynamic.primary=master
#主库配置
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=root
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf8
#从库配置
spring.datasource.dynamic.datasource.slave_1.username=root
spring.datasource.dynamic.datasource.slave_1.password=root
spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://localhost:3307/mybatis?useSSL=false&characterEncoding=utf8

Using @DS switching data source.

//使用 slave_1 数据源
@DS("slave_1")
public interface UserMapper extends BaseMapper<User> {

    Map<String,Object> queryUser(@Param("USER_ID") String userId);
}

@DS can be annotated based on the method and, while there is a method based on the annotation on annotation priority .

Notes on the service implementation or mapper interface methods, but strongly not recommended while in service and mapper comment. (May be a problem)

If the primary key is not added to the default data source.

DruidDataSourceAutoConfigureWill inject a DataSourceWrapper, its native will spring.datasourcefind the next url,username,passwordand so on. And we configure the path of dynamic data sources vary, so it is necessary to exclude:

spring:
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure

Or excluded in the classes:

@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)

Then replace the properties configuration information:

#公共配置 Druid登录账号 密码
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=123456
spring.datasource.dynamic.druid.initial-size=5
spring.datasource.dynamic.druid.min-idle=5
spring.datasource.dynamic.druid.maxActive=20
spring.datasource.dynamic.druid.maxWait=60000
spring.datasource.dynamic.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.dynamic.druid.minEvictableIdleTimeMillis=300000
spring.datasource.dynamic.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.dynamic.druid.testWhileIdle=true
spring.datasource.dynamic.druid.testOnBorrow=false
spring.datasource.dynamic.druid.testOnReturn=false
spring.datasource.dynamic.druid.poolPreparedStatements=true
spring.datasource.dynamic.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.dynamic.druid.filters=stat,slf4j
spring.datasource.dynamic.druid.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
spring.datasource.dynamic.druid.web-stat-filter.enabled=true
spring.datasource.dynamic.druid.web-stat-filter.url-pattern=/*
spring.datasource.dynamic.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.dynamic.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.dynamic.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
spring.datasource.dynamic.druid.stat-view-servlet.deny=192.168.1.73
spring.datasource.dynamic.druid.stat-view-servlet.reset-enable=false

Benpian Code Case Address:

https://github.com/450255266/open-doubi

Guess you like

Origin www.cnblogs.com/SimpleWu/p/10930388.html