目录
- 背景
- springboot 配置文件
- mybatis 配置文件
- 编写jdbc配置类
- 注意点
- ServiceImpl
- 总结
背景
公司项目需要用到多个数据源,因为数据来源于不同的系统,所以这里简单描述下 springboot多数据源如何配置与使用, 以及涉及到 多事务管理器如何配置与使用
springboot 配置文件
spring:
datasource:
bigdata:
driver-class-name: com.mysql.jdbc.Driver
url: yoururl
username: username
password: root
jx:
driver-class-name: com.mysql.jdbc.Driver
url: yoururl
username: username
password: root
在yml配置文件中 填写好自己的两个数据源连接信息
mybatis 配置文件
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 打印SQL语句到控制台 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!--<setting displayText="logImpl" value="NO_LOGGING" />-->
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
<setting name="localCacheScope" value="STATEMENT"/>
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
<property name="supportMethodsArguments" value="true"/>
<property name="params" value="pageNum=pageNumKey;pageSize=pageSizeKey;"/>
</plugin>
</plugins>
</configuration>
- settings 里面包含了一些简单的设置 ,这些设置基本写了注释,可以详细看下,可以选择性加一些
- plugins 里面加入了 分页插件,用的是 github开源的插件, 挺好用的,也可以自己写。 自己的写的话可以增加一些特性啥的,具体可以百度,不再赘诉。
编写jdbc配置类
这里为了便于识别,将两个数据源的配置放在了两个configure中
@Configuration
@MapperScan(basePackages = BigdataDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "bigdataSqlSessionFactory")
public class BigdataDataSourceConfig {
static final String PACKAGE = "xxxxxxxx";
static final String MAPPER_LOCATION = "xxxxxxxx";
@Value("${spring.datasource.bigdata.url}")
private String url;
@Value("${spring.datasource.bigdata.username}")
private String user;
@Value("${spring.datasource.bigdata.password}")
private String password;
@Value("${spring.datasource.bigdata.driver-class-name}")
private String driverClass;
@Value("${mybatis.config-location}")
private String configLocation;
@Value("${mybatis.mapper-locations}")
private String mapperLocations;
@Value("${mybatis.type-aliases-package}")
private String typeAliasesPackage;
@Bean(name = "bigdataDataSource")
@Primary
public DataSource bigdataDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "bigdataTransactionManager")
@Primary
public DataSourceTransactionManager bigdataTransactionManager() {
return new DataSourceTransactionManager(bigdataDataSource());
}
@Bean(name = "bigdataSqlSessionFactory")
@Primary
public SqlSessionFactory bigdataSqlSessionFactory(@Qualifier("bigdataDataSource") DataSource bigdataDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(bigdataDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(BigdataDataSourceConfig.MAPPER_LOCATION));
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//设置 mybatis配置, 不然mybatis配置文件里面配置的东西无法生效
sessionFactory.setConfigLocation(resolver.getResource(configLocation));
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
return sessionFactory.getObject();
}
}
注意点
-
PACKAGE
: *mapper.java 类所在的包路径 -
MAPPER_LOCATION
: *mapper.xml 所在的包路径 我这里是classpath:mapper/bigdata/*.xml
-
sessionFactory.setConfigLocation(resolver.getResource(configLocation));
加载 自己编写的mybatis 配置类,不然设置的那些参数,以及分页插件不会生效。 (比如 *mapper.xml 查询结果不会自动将下划线转驼峰并映射到 java entity类的字段上, 一般出现这种情况,要么就是 mybatis-config.xml 里面settings没有设置该项, 要么就是没有加载到 mybatis配置文件) -
@Bean(name = "bigdataTransactionManager")
这里是设置这个数据源的事务管理器
, 所有通过该数据源的数据库动作都归于这个名字叫“bigdataTransactionManager”的事务管理器
另一个数据源配置类就不贴出来了,基本配置一样 ,但是需要将数据源名称修改一下,然后上述四个注意点也需要按实际情况进行修改。
ServiceImpl
在ServiceImpl文件 中,我们需要使用 @Transcational()
注解来使用 事务管理器。
但是我们实际上注册了两个, 如果不指定事务管理器的, springboot是不知道该使用那个的。
不过我们在注册的时候,在 @Bean(name = "bigdataTransactionManager")
, 这一行下面使用了 @Primary
注解。
所以我们的spring
会默认使用 bigdataTransactionManager
这个事务管理器。
如果当你需要用到 另一个事务管理器的时候,你需要在你的 @Transcational
注解中指定事务管理器名称
ps: 可以使用在方法上,也可以加在 serviceImpl文件最上方
@Transactional(readOnly = true, transactionManager = "primaryTxxxxxxxxxxx")
@Transactional(readOnly = true, transactionManager = "anotherTxxxxxxxxxx")
总结
Springboot帮我们做了很多事情, 但是其实明白里面的设计还是比较重要的, 至少你从0搭建一个代码框架的时候不会有太多问题。
记录一下自己的问题,也希望能够帮助到正在学习的各位