[随写笔记]spring boot + myBatis 配置多个数据库
一、在application.properties配置文件中添加数据库信息
# 数据库 1
one.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库 1 使用 xygg的数据库
one.datasource.url=jdbc:mysql://localhost:3306/xygg?characterEncoding=utf-8&useUnicode=true&useSSL=false&serverTimezone=GMT%2B8
one.datasource.username=xygg
one.datasource.password=123456
# 数据库 2
two.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库 2 使用 xiaoyu 的数据库
two.datasource.url=jdbc:mysql://localhost:3306/xiaoyu?characterEncoding=utf-8&useUnicode=true&useSSL=false&serverTimezone=GMT%2B8
two.datasource.username=xygg
two.datasource.password=123456
xygg数据库表
xiaoyu数据库表
二、在dao层增加对每个数据区分的包
三、在resources的mybatis文件夹里增加对于每个数据库的xml文件夹
四、增加一个config包,用于编写spring配置,在config包下增加对每个数据源配置的类
对配置类声明类级注解@Configuration和@MapperScan
@Configuration:声明该类为配置类
@MapperScan:声明扫描,添加两个 basePackages 和 sqlSessionFactoryRef
basePackages:指定该类配置数据库的dao路径
sqlSessionFactoryRef:会话工厂Bean名称
import javax.sql.DataSource;
/**
* 多数据库配置
* 数据库 1 配置
*/
// 声明配置类
@Configuration
// 声明mybatis扫描
// sqlSessionFactoryRef 设置sql会话工厂标识,既会话工厂Bean名称
@MapperScan(basePackages = "com.dao.one" , sqlSessionFactoryRef = "oneSqlSessionFactory")
public class OneDatasourceConfig {
获取application.properties配置的数据库信息
// 获取配置文件数据库信息
@Value("${one.driver-class-name}")
private String driverClassName;
@Value("${one.datasource.url}")
private String url;
@Value("${one.datasource.username}")
private String username;
@Value("${one.datasource.password}")
private String password;
配置数据源和连接池,本例使用spring boot默认的连接池 HikariDataSource
指定Bean名称,用于区分每个数据库配置
// 配置连接池,当前使用spring boot默认连接池 HikariDataSource
@Bean(name = "oneDataSource")
public DataSource slaveDataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setJdbcUrl(url);
dataSource.setDriverClassName(driverClassName);
// 池中最大连接数,包括闲置和使用中的连接
dataSource.setMaximumPoolSize(10);
// 池中维护的最小空闲连接数
dataSource.setMinimumIdle(5);
// 等待来自池的连接的最大毫秒数
dataSource.setConnectionTimeout(30000);
// 连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置
dataSource.setPoolName("oneDataSourcePool");
// mysql使用sysdate() , oracle使用sysdate
dataSource.setConnectionInitSql("select sysdate() from dual");
return dataSource;
}
配置会话工厂
指定入参为指定的数据源Bean
指定数据源映射的xml
/**
* 会话工厂
* @param dataSource 指定上面配置连接池Bean名称
* @return
* @throws Exception
*/
@Bean(name = "oneSqlSessionFactory")
@Primary
public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 配置myBatis的xml配置文件映射路径
// bean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
// 配置myBatis的xml数据库语句映射路径
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("mybatis/one/*Mapper.xml"));
return bean;
}
配置事务管理和会话模板
注意Bean的名称
事务管理Bean名称用于多个数据库区分事务管理
/**
* 事务管理器
* @param dataSource 指定上面配置连接池Bean名称
* @return
*/
@Bean(name = "oneTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("oneDataSource") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
/**
* 会话模板
* @param sqlSessionFactory 指定上面会话工厂Bean名称
* @return
*/
@Bean(name = "oneSqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
其他的数据库配置直接复制,然后更改数据库信息和Bean名称
完成配置类
package com.config;
import com.zaxxer.hikari.HikariDataSource;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* 多数据库配置
* 数据库 1 配置
*/
// 声明配置类
@Configuration
// 声明mybatis扫描
// sqlSessionFactoryRef 设置sql会话工厂标识,用于事务管理
@MapperScan(basePackages = "com.dao.one" , sqlSessionFactoryRef = "oneSqlSessionFactory")
public class OneDatasourceConfig {
// 获取配置文件数据库信息
@Value("${one.driver-class-name}")
private String driverClassName;
@Value("${one.datasource.url}")
private String url;
@Value("${one.datasource.username}")
private String username;
@Value("${one.datasource.password}")
private String password;
// 配置连接池,当前使用spring boot默认连接池 HikariDataSource
@Bean(name = "oneDataSource")
public DataSource slaveDataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setJdbcUrl(url);
dataSource.setDriverClassName(driverClassName);
// 池中最大连接数,包括闲置和使用中的连接
dataSource.setMaximumPoolSize(10);
// 池中维护的最小空闲连接数
dataSource.setMinimumIdle(5);
// 等待来自池的连接的最大毫秒数
dataSource.setConnectionTimeout(30000);
// 连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置
dataSource.setPoolName("oneDataSourcePool");
// mysql使用sysdate() , oracle使用sysdate
dataSource.setConnectionInitSql("select sysdate() from dual");
return dataSource;
}
/**
* 会话工厂
* @param dataSource 指定上面配置连接池Bean名称
* @return
* @throws Exception
*/
@Bean(name = "oneSqlSessionFactory")
@Primary
public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 配置myBatis的xml配置文件映射路径
// bean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
// 配置myBatis的xml数据库语句映射路径
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("mybatis/one/*Mapper.xml"));
return bean;
}
/**
* 事务管理器
* @param dataSource 指定上面配置连接池Bean名称
* @return
*/
@Bean(name = "oneTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("oneDataSource") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
/**
* 会话模板
* @param sqlSessionFactory 指定上面会话工厂Bean名称
* @return
*/
@Bean(name = "oneSqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
数据库 2 完整代码
package com.config;
import com.zaxxer.hikari.HikariDataSource;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* 多数据库配置
* 数据库 1 配置
*/
// 声明配置类
@Configuration
// 声明mybatis扫描
// sqlSessionFactoryRef 设置sql会话工厂标识,用于事务管理
@MapperScan(basePackages = "com.dao.two" , sqlSessionFactoryRef = "twoSqlSessionFactory")
public class TwoDatasourceConfig {
// 获取配置文件数据库信息
@Value("${two.driver-class-name}")
private String driverClassName;
@Value("${two.datasource.url}")
private String url;
@Value("${two.datasource.username}")
private String username;
@Value("${two.datasource.password}")
private String password;
// 配置连接池,当前使用spring boot默认连接池 HikariDataSource
@Bean(name = "twoDataSource")
public DataSource slaveDataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setJdbcUrl(url);
dataSource.setDriverClassName(driverClassName);
// 池中最大连接数,包括闲置和使用中的连接
dataSource.setMaximumPoolSize(10);
// 池中维护的最小空闲连接数
dataSource.setMinimumIdle(5);
// 等待来自池的连接的最大毫秒数
dataSource.setConnectionTimeout(30000);
// 连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置
dataSource.setPoolName("twoDataSourcePool");
// mysql使用sysdate() , oracle使用sysdate
dataSource.setConnectionInitSql("select sysdate() from dual");
return dataSource;
}
/**
* 会话工厂
* @param dataSource 指定上面配置连接池Bean名称
* @return
* @throws Exception
*/
@Bean(name = "twoSqlSessionFactory")
@Primary
public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 配置myBatis的xml配置文件映射路径
// bean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
// 配置myBatis的xml数据库语句映射路径
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("mybatis/two/*Mapper.xml"));
return bean;
}
/**
* 事务管理器
* @param dataSource 指定上面配置连接池Bean名称
* @return
*/
@Bean(name = "twoTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("twoDataSource") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
/**
* 会话模板
* @param sqlSessionFactory 指定上面会话工厂Bean名称
* @return
*/
@Bean(name = "twoSqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
五、在dao.one和com.two包中增加测试接口类,并增加查询方法
one
@Mapper
@Repository
public interface OneTestDao {
List<Map<String,Object>> getUsers();
}
two
@Mapper
@Repository
public interface TwoTestDao {
List<Map<String,Object>> getUserVips();
}
六、在resources/mybatis/one 和resources/mybatis/two 增加mybatis的xml文件,并进行查询表
one
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.one.OneTestDao">
<select id="getUsers" resultType="java.util.Map">
select * from user_ordinary
</select>
</mapper>
two
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.two.TwoTestDao">
<select id="getUserVips" resultType="java.util.Map">
select * from user_vip
</select>
</mapper>
七、编写测试类进行测试
@Autowired
OneTestDao oneTestDao;
@Autowired
TwoTestDao twoTestDao;
@Test
void contextLoads() {
List<Map<String, Object>> users = oneTestDao.getUsers();
List<Map<String, Object>> userVips = twoTestDao.getUserVips();
System.out.println("数据库 1 :" + users);
System.out.println("数据库 2 : " + userVips);
}
数据库 1 :[{user_sex=0, user_create_date=2020-08-06 11:21:43.0, user_id=1, user_name=晓宇哥哥, user_age=0, user_pwd=123, user_update_date=2020-08-06 11:21:43.0, user_acc=xygg}]
数据库 2 : [{user_sex=0, user_create_date=2020-08-06 16:49:02.0, user_id=1, user_name=晓宇VIP, user_age=0, user_pwd=456, user_update_date=2020-08-06 16:49:02.0, user_acc=xiaoyu}]
查询返回成功
事务管理注解如下:
transactionManager 值为事务管理Bean名称
@Transactional(transactionManager = "oneTransactionManager" ,readOnly = false, rollbackFor = Exception.class)