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數據庫視圖

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM