springboot框架 mybatis整合多數據源配置

背景:

     最近在學習當中,學到了多數據源的配置,在網上找了很多的資料一邊配置,一邊踩坑,也一邊在學習,以此記錄一下吧。

參考:

 本文參考了幾個文章,但是或多多少都有些問題,所以我自己整合了下。鏈接放出

https://blog.csdn.net/maoyeqiu/article/details/74011626

https://blog.csdn.net/mxw2552261/article/details/78640062

出現的問題:

https://my.oschina.net/chinesedragon/blog/1647846

前期準備:

 springboot 2.0, mybatis,工具類:SqlSessionFactory 和 SqlSessionTemplate

 

多數據源:

 首先將我的配置貼出來(聲明一下,我這裏用的yml格式)

spring:
  ###主數據源
  primary:
    datasource:
      name: test1
      jdbc-url: jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=true
      username: root
      password: root
      type: com.alibaba.druid.pool.DruidDataSource

  ###第二數據源
  secondary:
    datasource:
      name: test2
      jdbc-url: jdbc:mysql://localhost:3306/test2?characterEncoding=utf8&useSSL=true
      username: root
      password: root
      type: com.alibaba.druid.pool.DruidDataSource

 我在這裏配置了兩個數據源,如果有多個,以此類推往下配置即可,我用的是mysql。

坑1

   這裏有一點說一下,如果配置單數據源應該是 spring.datasource.name,這裏因爲配置多個應該按照spring.yourname.datasource.name,差別是在datasource前邊加了一個自定義的名字,這樣來區分多個數據源,而且如果不加的話會在編譯的時候報錯 配置文件內duplicate datasource。

坑2

   這裏在配置數據庫連接的時候一般單源或者springboot1.x版本都用的是 url:xxxxxxxx,而現在這種情況,多個源而且我的版本是2.0的所以應該寫成jdbc-url: xxxxx,具體是因爲版本還是多個數據源的原因只能去問大神了。

 數據源配置好了以後,在springboot內啓動時會自動加載數據源的配置,這時候會出錯,所以我們在你的啓動類application.java內的註解添加一個屬性。

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableTransactionManagement
public class JisusearchApplication {


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

  就是在 啓動註解這裏SpringBootApplication 添加了exclude屬性。這裏是防止springboot自動創建datasource,而忽略我們的配置。

 

新建datasource:

  我們禁掉了springboot默認創建的datasource,接下來我們就自己來創建我們需要的多個datasource。

  1、新建一個類,來配置datasource

@Configuration
public class DataSourceConfig {

    /**
     * 主數據源
     * @return
     */
    @Bean(name = "primaryDataSource")
//    @Qualifier("primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.primary.datasource")
    public DataSource primary() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 從數據源
     * @return
     */
    @Bean(name = "secondaryDataSource")
//    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.secondary.datasource")
    public DataSource secondary() {
        return DataSourceBuilder.create().build();
    }


}

首先  @Configuration 指定該類爲spring的配置類相當於xml,

然後配置你在你的properties或yml文件內配置的數據源信息

@ConfigurationProperties(prefix = "spring.secondary.datasource")

這個註解會去properties文件內找你指定的前綴爲spring.secondary.datasource的配置,因此這個值要跟你配置文件內些的一致。

名字你當然可以自定義了,我這個可能會有些長。

   注意

這裏需要注意的是 我註釋掉的註解@Qulifier 就是爲該類指定名字的,因爲我用了註解bean所以不能重複指定,不然會報錯,還有就是這裏可以指定一個默認的數據源 @Primary(指定默認數據源),網上也有人說沒有必要,但是我這裏不指定會報錯。

這個坑請知道的大神 指點一下。

2、接下來使用工具類SqlSessionFactory和 SqlSessionTemplate 來完善你的配置

我的是分開創建的,即你有幾個數據源就創建幾個配置類,當然你先創建的多,也可以將這一步與上一步整合到一個類當中,看個人需要了。

上代碼:

@Configuration
@MapperScan(basePackages = {"com.example.jisusearch.primarydao"}, sqlSessionFactoryRef = "primarySqlSessionFactory")
public class MybatisPrimaryConfig {

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Bean
    public SqlSessionFactory primarySqlSessionFactory () throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(primaryDataSource);
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate primarySqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(primarySqlSessionFactory());
        return template;
    }
}

這裏引入上一步配置的datasource,並通過註解@Qualifier 來指定你目前這個SqlSessionFactory使用的是哪個數據源,類上加上註解@Configuration 聲明該類爲配置類;

@MapperScan(basePackages = {"com.example.jisusearch.primarydao"}, sqlSessionFactoryRef = "primarySqlSessionFactory")

該註解來指定你哪個包要使用這個數據源,要寫全路徑,不然會報錯,後邊這個屬性則是你SqlSessionFactory的bean的名字。

這裏是一個數據源的配置,接下來配置另外一個,類似就直接上代碼了。

@Configuration
@MapperScan(basePackages = {"com.example.jisusearch.secondarydao"}, sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class MybatisSecondaryConfig {

    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

    @Bean
    public SqlSessionFactory secondarySqlSessionFactory() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(secondaryDataSource);
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate secondarySqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(secondarySqlSessionFactory());
        return template;
    }
}

因爲我想要分開所以我建了兩個dao,你也可以在一個dao內指定這兩個,但是@MapperScan(basePackages = {"com.example.jisusearch.secondarydao"}) 這裏就不能寫到包了,路徑應該寫到你指定的mapper上,xml或者java類,例如:com.example.jisusearch.secondarydao.UserDao,多個的話用逗號分開就可以了。

3、新建dao

@Mapper
public interface PrimaryDao {

    @SelectProvider(type = PrimaryProviders.class, method = "getUserSql")
    @Results(id = "systemUser", value = {
            @Result(property = "userId", column = "user_id"),
            @Result(property = "username", column = "username"),
            @Result(property = "createUserId", column = "create_user_id"),
            @Result(property = "createTime", column = "create_time"),
    })
    UserModule getUser (String id);

    @ResultMap("systemUser")
    @SelectProvider(type = PrimaryProviders.class, method = "getUserByParamsSql")
    UserModule getUserByParams (String id);

}

   

擴展一下:我這裏做了字段的映射使用的是 @Results和@Result,因爲這兩個都是方法級的註解,所以爲了能共用我爲@Results加了id的屬性,其他的地方引用使用@ResultMap("yourResultId"),有人說這樣不可以,但是本人親測可用。

另外一個dao包下的方法

@Mapper
public interface SecondaryDao {

    @SelectProvider(type = SecondaryProviders.class, method = "getUserSql")
    @Results(id = "systemUser", value = {
            @Result(property = "userId", column = "user_id"),
            @Result(property = "username", column = "username"),
            @Result(property = "createUserId", column = "create_user_id"),
            @Result(property = "createTime", column = "create_time"),
    })
    UserModule getUser(@Param("id") String id);


}

  這裏sql語句我都是用java寫的,dao層用的註解@SelectProvider,因爲本人實在不喜歡寫xml -_-!!!。

4、寫你的test類或者使用三層,將到dao正常的注入到你的service或controller內,就可以正常使用了。

    @Resource
    private PrimaryDao primaryDao;
    @Resource
    private SecondaryDao secondaryDao;

    @RequestMapping("/primary/user")
    public Result findUser(String id) {
        Result re = new Result();
        Map<String, Object> map = new HashMap<>();
        UserModule userModule = primaryDao.getUser(id);
        UserModule userModule1 = secondaryDao.getUser(id);
        UserModule userModule2 = primaryDao.getUserByParams(id);
        map.put("first", userModule);
        map.put("second", userModule1);
        map.put("third", userModule2);
        re.setData(map);
        return re;
    }

  這裏有個坑,就是注入你的dao時不能使用autowired,因爲會報錯,你現在多個數據源而不是單個了

好了, 我的配置到此就結束了,代碼直接copy可用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章