spring boot + mybatis + druid 配置雙數據源

要點

  1. 由於配置了雙數據源,不用到spring自帶的數據庫鏈接,因此須要關閉資源的自動配置(沒有關閉未必會出錯,但關閉了確定沒有錯):

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)java

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
//組件基包掃描,讓spring boot管理其它模塊bean類的生命週期
@ComponentScan("com")
public class Schedule {

    public static void main(String[] args) {
        SpringApplication.run(Schedule.class, args);
    }
}
  1. 本文檔記錄多數據源配置中,測試發現沒法經過 mapper.xml 進行接口的配置。

具體緣由未發現,也未找到解決方式,因此對DB的操做是用的註解的方式。mysql

實現

1 配置數據源信息

如下爲其中一個數據源配置信息spring

spring.secondary.datasource.driverClassName = com.mysql.jdbc.Driver
spring.secondary.datasource.url = jdbc:mysql://10.10.14.56:3306/ppj?characterEncoding=UTF-8&rewriteBatchedStatements=true
spring.secondary.datasource.username = ppj.
spring.secondary.datasource.password = ppj.

2 數據庫配置信息

如下爲主庫配置信息, @primary 爲必填註解。sql

在有多個同類型的資源配置時,@primary 標註當前資源爲默認配置。數據庫

空閒檢測等配置,根據具體的業務需求。當前例子配置,是由於天天調用一次,不須要保持鏈接狀態,空閒時將鏈接斷開便可。apache

主庫鏈接池配置以下:session

package com.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 配置主數據庫源
 * 有多候選者狀況下,primary必寫,否則會出現衝突;
 * 採用primary消解的對象,默認採用
 *
 * @author pengpj
 * @date 2018/7/23
 */
@Configuration
@MapperScan(basePackages = "com.mapper.alarm", sqlSessionTemplateRef = "primarySST")
public class PrimaryDataSourceConfig {

    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String userName;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.driverClassName}")
    private String driverClass;

    @Primary
    @Bean(name = "primaryDS")
    public DataSource primaryDataSource() {

        DruidDataSource dataSource = new DruidDataSource();

        //基本鏈接信息
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClass);

        //具體配置
        dataSource.setInitialSize(1);
        dataSource.setMinIdle(0);
        dataSource.setMaxActive(1);

        //空閒檢測
        dataSource.setTestWhileIdle(true);
        //調用鏈接時檢測是否可用
        dataSource.setTestOnBorrow(true);
        dataSource.setValidationQuery("select 1");
        //獲取鏈接的等待超時時間
        dataSource.setMaxWait(1000 * 20L);
        //檢測須要關閉的空閒鏈接
        dataSource.setTimeBetweenEvictionRunsMillis(1000 * 30L);
        //鏈接池的最小生存時間
        dataSource.setMinEvictableIdleTimeMillis(1000 * 30L);

        return dataSource;

    }

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

    @Primary
    @Bean(name = "primaryTM")
    public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDS") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Bean(name = "primarySST")
    public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySSF") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

另外一數據庫配置鏈接池配置如上,刪去 @primary 註解,並更改 Bean 中 name 值,name 不重複便可。mybatis

3 mapper 接口操做類

注意以下幾點:app

  • 包名,與主庫鏈接池配置的 @MapperScan 中 basePackages 屬性相同,這樣便可以用對應的鏈接池進行數據庫操做。
  • 註解用到了兩個,@Mapper@Repository,前者是 mabatis,後者是 spring 用於實例化。

以主庫mapper爲例:測試

package com.mapper.alarm;

import com.cvte.alarm.platform.user.copy.entity.AlarmUser;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

/**
 * 用戶操做
 *
 * @author pengpj
 * @date 2018/5/4
 */
@Mapper
@Repository
public interface AlarmUserMapper {

    /**
     * 插入數據
     *
     * @param entity user
     * @return change row number
     */
    @Insert("INSERT INTO" +
            "    alarm_user(user_name,user_login_name,email,pwd,user_type,auth_type,create_time,update_time,uid) " +
            "    VALUES(#{userName},#{userLoginName},#{email},#{pwd},#{userType},#{authType},#{createTime},#{updateTime},#{uid})")
    Integer insert(AlarmUser entity);

    /**
     * 經過 userLoginName 查詢用戶信息
     *
     * @param userLoginName userLoginName
     * @return user
     */
    @Select("SELECT * FROM alarm_user WHERE user_login_name = #{userLoginName}")
    @Results(
            {
                    @Result(property = "uid",column = "uid"),
                    @Result(property = "userLoginName",column = "user_login_name")
            }
    )
    AlarmUser findUserByUserLoginName(@Param("userLoginName") String userLoginName);
}

4 接口調用

Spring注入後,便可用接口進行數據庫操做。

用例調用代碼以下:

··· 省略

    public void execute() {

        List<ApmUser> apmUsers = apmUserMapper.obtainApmUserAfterTimestamp(timestamp);

    }

    private AlarmUserMapper alarmUserMapper;

    @Autowired
    public UserUpdateSchedule(AlarmUserMapper alarmUserMapper) {
        this.alarmUserMapper = alarmUserMapper;
    }
相關文章
相關標籤/搜索