天天看點

spring boot整合mybatis通用mapper實作Druid多資料源

      在以前的項目中用springMVC加原生的mybatis架構使用過多資料源的配置,是用xml配置的。在這次的新項目裡面使用到了tk的通用mapper,剛好項目結束,利用空閑時間寫了個全注解的多資料源配置小demo。

現在網際網路項目中流行使用Mybatis架構和Druid資料庫連接配接池進行資料庫的操作。本來直接是用的spring boot整合mybatis做的多資料源,因為剛結束的項目中使用到了通用mapper這個免去sql編寫,提高開發效率的元件,是以順帶的把這個元件也內建進來了。

因為主要講的是多資料源的實作,對其他的架構元件就不花費太多的筆墨,以後會另外的花時間去記錄。

首先看下項目的整體結構:

spring boot整合mybatis通用mapper實作Druid多資料源

datasource包下面放的是資料源一和資料源二的配置

mapper包下面放的對應的mapper檔案,注意包要細分到不同的來源,比喻mapper.source1和mapper.source2,不同來源庫的mapper檔案要放到不同的source包下面。

項目是用maven工具建構的,肯定少不了在pom.xml檔案裡面添加相應的jar依賴:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.lms</groupId>
   <artifactId>multiple-datasource</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>multiple-datasource</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.2.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <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>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
      </dependency>

      <!-- druid連接配接池-->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid</artifactId>
         <version>1.1.8</version>
      </dependency>

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

      <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>1.3.2</version>
      </dependency>
      <!--tk通用mapper-->
      <dependency>
         <groupId>tk.mybatis</groupId>
         <artifactId>mapper-spring-boot-starter</artifactId>
         <version>1.2.4</version>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
         <optional>true</optional>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>
      

添加完依賴之後就要開始配置資料庫了,在application.properties檔案裡面配置資料庫的位址和druid相關的一些配置:

mybatis.type-aliases-package=com.lms.multipledatasource.entity


spring.datasource.source1.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.source1.url = jdbc:mysql://192.168.2.115:3306/data_source_test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.source1.username = root
spring.datasource.source1.password = 8Nj1jo+I8f1qNQ
#使用Druid資料源
spring.datasource.source1.initialSize=5
# 初始化大小,最小,最大
spring.datasource.source1.minIdle=5
spring.datasource.source1.maxActive= 20
# 配置擷取連接配接等待逾時的時間
spring.datasource.source1.maxWait= 60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接配接,機關是毫秒
spring.datasource.source1.timeBetweenEvictionRunsMillis= 60000
# 配置一個連接配接在池中最小生存的時間,機關是毫秒
spring.datasource.source1.minEvictableIdleTimeMillis= 300000
spring.datasource.source1.validationQuery= select 'x'
spring.datasource.source1.testWhileIdle= true
spring.datasource.source1.testOnBorrow= false
spring.datasource.source1.testOnReturn= false
# 打開PSCache,并且指定每個連接配接上PSCache的大小
spring.datasource.source1.poolPreparedStatements= true
spring.datasource.source1.maxPoolPreparedStatementPerConnectionSize= 20
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用于防火牆
spring.datasource.source1.filters= stat,wall,slf4j
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.source1.connectionProperties= druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000


spring.datasource.source2.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.source2.url = jdbc:mysql://192.168.2.115:3306/data_source_test2?useUnicode=true&characterEncoding=utf-8
spring.datasource.source2.username = root
spring.datasource.source2.password = 8Nj1jo+I8f1qNQ
#使用Druid資料源
spring.datasource.source2.initialSize=5
# 初始化大小,最小,最大
spring.datasource.source2.minIdle=5
spring.datasource.source2.maxActive= 20
# 配置擷取連接配接等待逾時的時間
spring.datasource.source2.maxWait= 60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接配接,機關是毫秒
spring.datasource.source2.timeBetweenEvictionRunsMillis= 60000
# 配置一個連接配接在池中最小生存的時間,機關是毫秒
spring.datasource.source2.minEvictableIdleTimeMillis= 300000
spring.datasource.source2.validationQuery= select 'x'
spring.datasource.source2.testWhileIdle= true
spring.datasource.source2.testOnBorrow= false
spring.datasource.source2.testOnReturn= false
# 打開PSCache,并且指定每個連接配接上PSCache的大小
spring.datasource.source2.poolPreparedStatements= true
spring.datasource.source2.maxPoolPreparedStatementPerConnectionSize= 20
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用于防火牆
spring.datasource.source2.filters= stat,wall,slf4j
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.source2.connectionProperties= druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      

mybatis.type-aliases-package配置可以自動的掃描mapper檔案,但是需要在Mapper接口上标注@Mapper注解,下面配置了兩個資料源source1和source2,如果還有更多的資料源,隻需要依次的添加就可以了。

接下來建立兩個資料源配置類DataSourceOneConfig和DataSourceTwoConfig

在配置資料源的時候,必要要配置一個主資料源,在這裡把DataSourceOneConfig作為主資料源

@Configuration
//掃描Mapper  basePackages要精确到source1目錄便于進行不同資料源的區分
@MapperScan(basePackages = "com.lms.multipledatasource.mapper.source1", sqlSessionTemplateRef = "sqlSessionTemplateOne")
public class DataSourceOneConfig {

    @Bean(name = "dataSourceOne")
    @ConfigurationProperties(prefix = "spring.datasource.source1")
    @Primary //設定主資料源
    public DataSource DataSourceOne(){
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;

    }

    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        registrationBean.addInitParameter("allow", "127.0.0.1"); // IP白名單 (沒有配置或者為空,則允許所有通路)
        registrationBean.addInitParameter("deny", ""); // IP黑名單 (存在共同時,deny優先于allow)
        registrationBean.addInitParameter("loginUsername", "admin");
        registrationBean.addInitParameter("loginPassword", "admin");
        registrationBean.addInitParameter("resetEnable", "false");
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean druidWebStatViewFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new WebStatFilter());
        registrationBean.addInitParameter("urlPatterns", "/*");
        registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*");
        return registrationBean;
    }


    @Bean(name = "sqlSessionFactoryOne")
    @Primary
    public SqlSessionFactory sqlSessionFactoryOne(@Qualifier("dataSourceOne") DataSource dataSource)throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    @Bean(name = "dataSourceTransactionManagerOne")
    @Primary
    public DataSourceTransactionManager dataSourceTransactionManagerOne(@Qualifier("dataSourceOne") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplateOne")
    @Primary
    public SqlSessionTemplate sqlSessionTemplateOne(@Qualifier("sqlSessionFactoryOne") SqlSessionFactory sqlSessionFactory)throws Exception{
        return new SqlSessionTemplate(sqlSessionFactory);
    }


}      

@Configuration 說明這是一個配置類                                                                                                           

@MapperScan  掃描mapper接口和進行容器管理,注意的是basePackages要精确到source1目錄便于和不同資料源的區分    

@Primary 标志主資料源,一定要有且隻能有一個主資料源,不然會報錯的。                                                           

@ConfigurationProperties 讀取properties配置檔案裡面的以spring.datasource.source1開頭的資料庫配置

在配置datasource的時候一定要用DruidDataSource類,不然的話druid資料庫連接配接池是不會起作用的                

public DataSource DataSourceOne(){
    DruidDataSource dataSource = new DruidDataSource();
    return dataSource;

}      

druidStatViewServlet()和druidWebStatViewFilter()是配置durid的登陸位址和登陸賬戶的。

同理DataSourceTwoConfig類中的配置和DataSourceOneConfig裡面的是差不多的 ,把source1改為source2即可,并且不需要@Primary注解

@Configuration
@MapperScan(basePackages = "com.lms.multipledatasource.mapper.source2", sqlSessionTemplateRef = "sqlSessionTemplateTwo")
public class DataSourceTwoConfig {

    @Bean(name = "dataSourceTwo")
    @ConfigurationProperties(prefix = "spring.datasource.source2")
    public DataSource DataSourceOne(){
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }

    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        registrationBean.addInitParameter("allow", "127.0.0.1"); // IP白名單 (沒有配置或者為空,則允許所有通路)
        registrationBean.addInitParameter("deny", ""); // IP黑名單 (存在共同時,deny優先于allow)
        registrationBean.addInitParameter("loginUsername", "admin");
        registrationBean.addInitParameter("loginPassword", "admin");
        registrationBean.addInitParameter("resetEnable", "false");
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean druidWebStatViewFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new WebStatFilter());
        registrationBean.addInitParameter("urlPatterns", "/*");
        registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*");
        return registrationBean;
    }

    @Bean(name = "sqlSessionFactoryTwo")
    public SqlSessionFactory sqlSessionFactoryOne(@Qualifier("dataSourceTwo") DataSource dataSource)throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    @Bean(name = "dataSourceTransactionManagerTwo")
    public DataSourceTransactionManager dataSourceTransactionManagerOne(@Qualifier("dataSourceTwo") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplateTwo")
    public SqlSessionTemplate sqlSessionTemplateOne(@Qualifier("sqlSessionFactoryTwo") SqlSessionFactory sqlSessionFactory)throws Exception{
        return new SqlSessionTemplate(sqlSessionFactory);
    }      

到這裡,基本的資料源配置就已經差不多結束了,接下來的service,mapper,conttroller就和平常寫項目是一樣的,沒有什麼太大的差別。

因為使用的是tk通用mapper,是以我們在自己定義一個接口去是繼承tk的兩個接口Mapper<T>, MySqlMapper<T> ,自己定義的接口名稱可以随自己定,和普通的接口一樣,沒有特殊的要求。在這裡取名為CommnMapper<T>,注意的是一定要帶上泛型。這個接口上面不需要任何的注解

public interface CommnMapper<T> extends Mapper<T>, MySqlMapper<T> {

}      

然後建立一個UserInfoOneMapper接口繼承剛剛建立的CommnMapper接口,接口上面要添加@Component和@Mapper來說明這個接口是一個元件和一個mapper檔案

@Component
@Mapper
public interface UserInfoOneMapper  extends CommnMapper<UserInfoEntity>{

}      

這個mapper連接配接的是userinfo表,是以泛型裡面用的是UserInfoEntity對象。mapper連接配接的是哪個表,泛型裡面對應的就是哪個表對應的實體類對象。

@Component
@Table(name = "userinfo")
public class UserInfoEntity {

    @Id
    private Integer id;
    private String userName;
    private String departName;
    private Date created;

      

@Table裡面name的值是資料庫裡面對應的表名,一定不要填錯了。

然後我們就可以在service裡面調用mapper的增删查改方法來對表裡面的資料進行對應的操作了。因為這隻是一個demo,是以就沒有建立service層,直接在controller執行個體化了mapper調用了對應的方法

@RestController
public class UserInfoController {
    @Autowired
    private UserInfoOneMapper userInfoOneMapper;
    @Autowired
    private UserInfoTwoMapper userInfoTwoMapper;


    @RequestMapping("/getOneUserById")
    public UserInfoEntity getOneUserById(Integer id){
        UserInfoEntity entity = new UserInfoEntity();
        entity.setId(id);
        UserInfoEntity entity1 = userInfoOneMapper.selectOne(entity);
        return entity1;
    }

    @RequestMapping("/getAllUserForOne")
    public List<UserInfoEntity> getAllUserForOne(){
        List<UserInfoEntity> allUser = userInfoOneMapper.selectAll();
        return allUser;
    }

    @RequestMapping("/getTwoUserById")
    public UserInfoEntity getTwoUserById(Integer id){
        UserInfoEntity entity = new UserInfoEntity();
        entity.setId(id);
        UserInfoEntity entity1 = userInfoTwoMapper.selectOne(entity);
        return entity1;
    }

    @RequestMapping("/getAllUserForTwo")
    public List<UserInfoEntity> getAllUserForTwo(){
        List<UserInfoEntity> allUser = userInfoTwoMapper.selectAll();
        return allUser;
    }
}      

啟動項目,在postman裡面調用不同的接口,可以擷取到不同的表裡面的資料。                                                                       

調用getOneUserById,傳id=1獲得傳回資料:

spring boot整合mybatis通用mapper實作Druid多資料源

調用getTwoUserById,傳id=1獲得傳回資料:

spring boot整合mybatis通用mapper實作Druid多資料源

繼續閱讀