SpringBoot+Mybatis-plus多数据源配置(MySQL、Sqlserver)

前言:

    本章案例利用dynamic-datasource-spring-boot-starter集成多数据源,mybaits-plus采用3.3.0版本,主要讲述配置多数据源,其案例中也包含了逻辑删除、攻击SQL阻断解析器、p6spySQL性能分析打印、事务以及分页和乐观锁插件。

    dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器,其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.0.x。

 

一、pom.xml

<!--代码简化,工具相关 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<!--SQLServer 驱动-->
<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>sqljdbc4</artifactId>
    <version>4.0</version>
    <scope>runtime</scope>
</dependency>

<!--mysql 驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>2.4.2</version>
</dependency>

<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.8.0</version>
</dependency>

 

二、application.yml

server:
  port: 8888
  servlet:
    context-path: /server
spring:
  application:
    name: springboot-manyDataSources
  datasource:
    p6spy: true
    dynamic:
      datasource:
        master:
          driver-class-name: com.p6spy.engine.spy.P6SpyDriver
          url: jdbc:p6spy:mysql://localhost:3306/datasourceName?characterEncoding=utf8&useSSL=false&serverTimezone=GMT
          username: root
          password: root
#          url: jdbc:mysql://localhost:3306/ datasourceName?characterEncoding=utf8&useSSL=false&serverTimezone=GMT
#          username: root
#          password: root
#          driver-class-name: com.mysql.cj.jdbc.Driver

        db2:
          driver-class-name: com.p6spy.engine.spy.P6SpyDriver
          url: jdbc:p6spy:sqlserver://localhost:1433;DatabaseName=datasourceName
          username: sa
          password: root
#          url: jdbc:sqlserver://localhost:1433;DatabaseName= datasourceName
#          username: sa
#          password: root
#          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

#日志
logging:
  level:
    com.example.demo : debug

 

三、spy.properties

modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

 

四、MybatisPlusConfig 

@Configuration
@EnableTransactionManagement//开启事务
public class MybatisPlusConfig {
    /**
     * mybatisplus 分页插件
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();

        List<ISqlParser> sqlParserList = new ArrayList<>();
        // 攻击 SQL 阻断解析器、加入解析链;防止小白或者恶意进行delete update 全表操作。注:若表配置使用了逻辑删除将正常执行删除。
        sqlParserList.add(new BlockAttackSqlParser());
        paginationInterceptor.setSqlParserList(sqlParserList);
        return paginationInterceptor;
    }

    /**
     *乐观锁插件:当要更新一条记录的时候,希望这条记录没有被别人更新
     * @return
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

 

五、entity

5.1 ManageUser 

@Data
@Builder
@Accessors(chain = true)
@TableName("manage_user")
@EqualsAndHashCode(callSuper = false)
public class ManageUser extends Model<ManageUser> {

    private static final long serialVersionUID = 1L;

    /**
     * 管理员ID
     */
    @TableId(value = "ID", type = IdType.AUTO)
    private Integer id;
    /**
     * 登陆名
     */
    @TableField("USERNAME")
    private String username;
    /**
     * 密码
     */
    @TableField("PASSWORD")
    private String password;
    /**
     * 对应的角色Id
     */
    @TableField("ROLE_ID")
    private Integer roleId;
    /**
     * 是否删除
     */
    @TableField("IS_DEL")
    @TableLogic
    private Integer isDel = 0;

    @TableField("VERSION")
    @Version
    private Integer version;

    @Override
    protected Serializable pkVal() {
        return this.id;
    }

}

 

5.2  VDepart

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("v_depart")
public class VDepart extends Model<VDepart> {

    private static final long serialVersionUID = 1L;
    
    @TableId(value = "ID", type = IdType.AUTO)
    private Integer id;

    private String code;

    private String name;
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
}

 

六、controller

6.1 ManageUserController 

@Slf4j
@RestController
@RequestMapping("/manageUser")
@Transactional(rollbackFor=Exception.class)
public class ManageUserController {

    @Autowired
    private ManageUserService manageUserService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/userList")
    public List<ManageUser> userList(){
        return manageUserService.list(null);
    }

    //逻辑删除
    @GetMapping("/deleteUser")
    public boolean deleteUser(){
        return manageUserService.removeById(4);
    }

    //jdbcTemplate
    @GetMapping("/deleteUserTrue/{userId}")
    public boolean deleteUserTrue(@PathVariable("userId") String userid){
        boolean flag = false;
        int update = jdbcTemplate.update("DELETE FROM MANAGE_USER WHERE ID = ?;",userid);
        if(update>0){flag = true;}
        log.info("影响的行数:{} ", update);
        return flag;
    }

    //SQL 阻断解析器
    @GetMapping("/deleteUserAll")
    public boolean deleteUserAll(){
        return manageUserService.remove(null);
    }

    //乐观锁
    @GetMapping("/updateUser")
    public boolean updateUser(){
        return manageUserService.updateUser();
    }

    //事务
    @GetMapping("/addUser")
    public boolean addUser(){
        boolean root = manageUserService.save(ManageUser.builder().username("root").password("4ec847db9bc2bad60e4279cce1fad5db").roleId(1).build());
        int i = 1/0;
        manageUserService.remove(null);
        return root;
    }
}

 

6.2  VDepartController 

@RestController
@RequestMapping("/vDepart")
public class VDepartController {

    @Autowired
    private VDepartService vDepartService;

    @GetMapping("/vDepartList")
    public List<VDepart> accountList(){
        return vDepartService.list();
    }

    @GetMapping("/vDepartPage/{page}/{limit}")
    public List<VDepart> vDepartPage(@PathVariable("page") int page, @PathVariable("limit") int limit){
        IPage<VDepart> page1 = vDepartService.page(new Page<>(page, limit));
        return page1.getRecords();
    }
}

 

七、 使用 @DS 切换数据源,不加@DS注解则默认master数据源

@DS 可以注解在方法上和类上,同时存在方法注解优先于类上注解。注解在service实现或mapper接口方法上,但强烈不建议同时在service和mapper注解。 (可能会有问题)

@DS("db2")
@Service
public class VDepartServiceImpl extends ServiceImpl<VDepartMapper, VDepart> implements VDepartService {

}

 

目录结构:

释:ManageUser为mysql数据库用户表,VDepart为sqlserver数据库视图

 

 

 

posted @ 2020-03-29 23:09  一月1  阅读(7931)  评论(4编辑  收藏  举报