您的位置:首页 > 编程语言 > Java开发

spring boot + mybatis + druid 配置双数据源

2018-07-30 22:58 951 查看

要点

因为配置了双数据源,不用到spring自带的数据库连接,所以需要关闭资源的自动配置(没有关闭未必会出错,但关闭了肯定没有错):

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
//组件基包扫描,让spring boot管理其它模块bean类的生命周期
@ComponentScan("com")
public class Schedule {

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


本文档记录多数据源配置中,测试发现无法通过 mapper.xml 进行接口的配置。

具体原因未发现,也未找到解决方式,所以对DB的操作是用的注解的方式。

实现

1 配置数据源信息

以下为其中一个数据源配置信息

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 为必填注解。

在有多个同类型的资源配置时,@primary 标注当前资源为默认配置。

空闲检测等配置,根据具体的业务需求。当前例子配置,是因为每天调用一次,不需要保持连接状态,空闲时将连接断开即可。

主库连接池配置如下:

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 不重复即可。

3 mapper 接口操作类

注意如下几点:

包名,与主库连接池配置的 @MapperScanbasePackages 属性相同,这样即可以用对应的连接池进行数据库操作。

注解用到了两个,@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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息