SpringBoot+Mybatis配置多数据源并且实现事务⼀致性最近博客写得少,不知道怎么说开场⽩了。呃,本⽂⼀共分三部分:SpringBoot+Mybatis环境搭建、两种⽅式配置多数据源、两种⽅式实现跨数据源事务,您可以直接跳到喜欢的部分,不过按顺序看完也不会花很多时间。。。
⼀、搭建SpringBoot+Mybatis框架环境
看标题就知道,这部分不是重点,所以简单说⼀下(如果你是⼩⽩那对不起了~)。
1、引⼊依赖
Mybatis整合包和jdbc驱动包,默认使⽤的是HikariDataSource数据源(如果你要使⽤阿⾥爸爸的Druid就要单独引⼊)。
<dependency>
<groupId&batis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2、填写配置
spring:
datasource:
username: test
password: test
url: jdbc:mysql://jiubugaosuni:8888/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: sql.cj.jdbc.Driver
实际开发中还有其它更详细的配置,这⾥就不列了。还可以配置⼀下Mybatis的参数。
3、建⽴mapper接⼝及配置Mybatis扫描包
建⼀个mapper包并把所有DAO接⼝都放⾥⾯。⽐如StudentMapper长这样。
package cn.zhh.mapper;
import ity.Student;
/**
* 学⽣Mapper
*
* @author Zhou Huanghua
* @date 2019/10/25 23:09
*/
public interface StudentMapper {
/**
* 插⼊⼀条学⽣记录
*
* @param student 学⽣信息
* @return 插⼊数量
*/
int insert(Student student);
/
**
* 根据id删除学⽣记录
*
* @param id 学⽣id
* @return 删除数量
*/
int deleteById(Long id);
}
但是⽬前这些接⼝不会被Mybatis扫描到,所以需要在接⼝上⾯加⼀个Mapper注解。不过,更推荐配置Mybatis扫描包的⽅式,⽐如在启动类加⼀下这个:@MapperScan(basePackages = "cn.zhh.mapper.**")。好像在l也是可以配的,没验证过。
4、l⽂件
推荐在resources⽬录下新建⼀个和Mapper接⼝⼀样的包,把xml⽂件都放⾥⾯,然后什么都不⽤配置。⽐如StudentMapper对应的l长这样。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zhh.mapper.StudentMapper">
<resultMap id="BaseResultMap" type="ity.Student">
<result column="id" jdbcType="BIGINT" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="code" jdbcType="VARCHAR" property="code"/>
<result column="sex" jdbcType="TINYINT" property="sex"/>
<result column="create_time" jdbcType="DATE" property="createTime"/>
<result column="last_update_time" jdbcType="DATE" property="lastUpdateTime"/>
<result column="is_deleted" jdbcType="TINYINT" property="isDeleted"/>
</resultMap>
<insert id="insert" parameterType="ity.Student">
INSERT INTO student (`name`, `code`, `sex`) VALUES (#{name, jdbcType=VARCHAR}, #{code, jdbcType=VARCHAR}, #{sex, jdbcType=TINYINT})    </insert>
<delete id="deleteById" parameterType="java.lang.Long">
DELETE FROM student WHERE id = #{id, jdbcType=BIGINT}
springboot aop
</delete>
</mapper>
另外,在Mapper接⼝的上⾯也是可以写sql的,但是那样不推荐,第⼀是灵活性有限复杂的搞不了,第⼆是不利于统⼀管理维护。
总结Q&A    Q:你这写得太简单了吧!?A:毕竟这不是重点(*^_^*)。
⼆、两种⽅式配置多数据源
啥叫多数据源?简单来说就是⼀个系统需要操作多个数据库(同实例或者不同实例),⼀个读这个写那个,⼀个读那个写这个。
1、动态切换数据源
在进⼊⼀个⽅法执⾏DB操作之前,根据配置(注解或者包名啥的)切换到对应的那个数据源,执⾏完成后再切换回去(可选),这个⽅法执⾏前执⾏后通过AOP处理。
这种⽅式之前写过对应的博客(),此处不再赘述。
如果⽅法使⽤事务的话,可能会导致切换失败。我在项⽬使⽤时遇到过,当时由于⼯期紧没去深⼊研究,直接采⽤了第⼆种实现⽅式。下图是当时百度了⼀下看到的
2、不同的mapper接⼝包使⽤不同的数据源
通过配置不同的Mapper接⼝扫描路径使⽤不同的SqlSessionTemplate来实现。不同的SqlSessionTemplate就是不同的SqlSessionFactory,也就是不同的DataSource。
1)配置两个不同的数据源
spring:
datasource:
username: test
password: test
url: jdbc:mysql://jiubugaosuni:8888/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: sql.cj.jdbc.Driver
datasource2:
username: test2
password: test2
url: jdbc:mysql://biexiangzhidao:6666/test2?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: sql.cj.jdbc.Driver
Java Bean的⽅式注册两个数据源。注意选择⼀个加上@Primary,这样基于Type⽅式的注⼊(如@Autowired)就可以使⽤它作为默认的注⼊对象了。
/**
* 数据源配置
*
* @author Zhou Huanghua
* @date 2019/10/26 0:24
*/
@Configuration
public class DataSourceConfig {
@Bean
@Primary
public DataSource dataSource(@Value("${spring.datasource.username}") String username,
@Value("${spring.datasource.password}") String password,
@Value("${spring.datasource.url}") String url,
@Value("${spring.datasource.driver-class-name}") String driverClassName) {
return createDataSource(username, password, url, driverClassName);
}
@Bean
public DataSource dataSource2(@Value("${spring.datasource2.username}") String username,
@Value("${spring.datasource2.password}") String password,
@Value("${spring.datasource2.url}") String url,
@Value("${spring.datasource2.driver-class-name}") String driverClassName) {
return createDataSource(username, password, url, driverClassName);
}
private DataSource createDataSource(String username, String password, String url, String driverClassName) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setJdbcUrl(url);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
}
2)配置两套Mapper接⼝扫描路径,并指定对应的SqlSessionTemplate
这⾥我们使⽤⼀个外部类两个静态内部类的⽅式使⽤Java Bean配置,分成两个独⽴的类也是可以的。两个basePackages设置不同的sqlSessionTemplateRef属性:mapper包的将使⽤第⼀个数据源,mapper2包的将使⽤第⼆个数据源。使⽤@Primary的⽬的同上。
/**
* MybatisConfig配置类
*
* @author Zhou Huanghua
* @date 2019/10/26 0:31
*/
public class MybatisConfig {
@Configuration
@MapperScan(
basePackages = "cn.zhh.mapper",
sqlSessionTemplateRef = "sqlSessionTemplate")
public static class Db1 {
@Bean
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
Object();
}
@Bean
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
@Primary
public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
@Configuration
@MapperScan(
basePackages = "cn.zhh.mapper2",
sqlSessionTemplateRef = "sqlSessionTemplate2")
public static class Db2 {
@Bean
public SqlSessionFactory sqlSessionFactory2(@Qualifier("dataSource2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
Object();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {            return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public DataSourceTransactionManager dataSourceTransactionManager2(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。