20分钟搞定 SpringBoot+Mybatis+多数据源

前言:

这篇博客是希望帮助您在20分钟左右快速集成多数据源,台上一分钟,台下60秒,如果没能帮到您,不喜勿喷。

业务背景:

        项目中有个需求,需要在Oracle中查询数据,利用查询出来的数据作为触发参数去执行一段业务流程,这段业务流程执行完毕之后,将业务返回来的数据存储进Mysql中,这个需求就涉及到两个数据源。

        解决办法有很多种,比如可以单独写一个脚本先将Oracle的数据导进Mysql等等。不过我使用的是在一个SpringBoot服务中加入两个数据源,这样更简单,也避免了不必要的数据冗余。

环境搭建:

pom:

        说明:

1.我使用的是MP(MybatisPlus),  MP的核心思想是在Mybatis的基础上只做增强,不做改变,所以您如果使用的是Mybatis并不影响。

2. ojdbc6(oracle连接驱动包)添加到pom之后,会拉不下来包,可以参考这篇博客手动打包。maven添加Oracle 依赖,将Oracle的依赖jar包打成依赖引入到maven_wx5fa2b09c753b2的技术博客_51CTO博客

        <!-- SpringBoot 2.6.1 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.6.1</version>
        </dependency>

        <!-- oracle连接驱动 -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.4</version>
        </dependency>
    
        <!-- MP -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <!-- MySql连接驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

yml:

spring:
  # 数据源配置
  datasource:
    # 主数据源(mysql)
    db1:
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/fs_bank?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
      username: root
      password: ********

    # 副数据源(Oracle)
    db2:
      driver-class-name: oracle.jdbc.driver.OracleDriver
      jdbc-url: jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:orcl
      username: s03
      password: ********

相关目录:

代码实现:

DataSourceConfiguration:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;


@Configuration
public class DataSourceConfiguration {

    @Bean("primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    @Primary
    public DataSource primaryDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean("secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource secondaryDataSource(){
        return DataSourceBuilder.create().build();
    }


}

PrimaryConfig:

import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;


@Configuration
@MapperScan(
        basePackages = "com.xxx.xxx.xxx.mapper.db1",
        sqlSessionFactoryRef = "sqlSessionFactoryPrimary",
        sqlSessionTemplateRef ="sqlSessionTemplatePrimary"
)
public class PrimaryConfig {

    private final DataSource primaryDataSource;

    public PrimaryConfig(@Qualifier("primaryDataSource")DataSource primaryDataSource){
        this.primaryDataSource = primaryDataSource;
    }

    @Bean("sqlSessionFactoryPrimary")
    @Primary
    public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(primaryDataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/*.xml"));
        bean.setVfs(SpringBootVFS.class);
        bean.setTypeAliasesPackage("com/xxx/xxx/xxx/domain/entity/db1");
        return bean.getObject();
    }

    @Bean("sqlSessionTemplatePrimary")
    @Primary
    public SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryPrimary());
    }
}

SecondaryConfig:

import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;


@Configuration
@MapperScan(
        basePackages = "com.xxx.xxx.xxx.mapper.db2",
        sqlSessionFactoryRef = "sessionFactorySecondary",
        sqlSessionTemplateRef = "sqlSessionTemplateSecondary"
)
public class SecondaryConfig {
    private final DataSource secondaryDataSource;

    public SecondaryConfig(@Qualifier("secondaryDataSource")DataSource secondaryDataSource){
        this.secondaryDataSource = secondaryDataSource;
    }

    @Bean("sessionFactorySecondary")
    public SqlSessionFactory sessionFactorySecondary() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(secondaryDataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db2/*.xml"));
        bean.setVfs(SpringBootVFS.class);
        bean.setTypeAliasesPackage("com/xxx/xxx/xxx/domain/entity/db2");
        return bean.getObject();
    }

    @Bean("sqlSessionTemplateSecondary")
    public SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception {
        return new SqlSessionTemplate(sessionFactorySecondary());
    }
}

到此,SpringBoot的多数据源就配置完成了,然后实体类,XXXMapper接口,XXXMapper.xml文件等等按照平时的开发流程,配置到相应的位置就可以。

这里贴一套DB2(Oralce)数据源的,DB1(Mysql)也是一样的逻辑,配置好后,我们正常调用Mapper中的接口就行。

实体类:

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.Date;


@Data
@EqualsAndHashCode(callSuper = false)
public class DfcPunishSheetInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 数据库自增序列
     */
    @TableId("GUID")
    private Long guid;

    /**
     * 处罚决定书编号
     */
    @TableField("PUNISHSHEETNO")
    private String punishSheetNo;

    /**
     * 处理日期
     */
    @TableField("DEALDATE")
    private Date dealDate;

    /**
     * 缴款日期
     */
    @TableField("PAYDATE")
    private Date payDate;
}

 Mapper:


import com.xxx.xxx.xxx.domain.entity.db2.DfcPunishSheetInfo;
import org.apache.ibatis.annotations.Mapper;


@Mapper
public interface DfcPunishSheetInfoMapper {
    DfcPunishSheetInfo selectByGuid(Long guid);
}

 Mapper.Xml

<?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.xxx.xxx.xxx.mapper.db2.DfcPunishSheetInfoMapper">

    <!-- 开启二级缓存 -->
    <!--<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>-->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xxx.xxx.xxx.domain.entity.db2.DfcPunishSheetInfo">
        <id column="GUID" property="guid"/>
        <result column="PUNISHSHEETNO" property="punishSheetNo"/>
        <result column="DEALDATE" property="dealDate"/>
        <result column="PAYDATE" property="payDate"/>
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        GUID, PUNISHSHEETNO, DEALDATE, PAYDATE
    </sql>

    <select id="selectByGuid" resultMap="BaseResultMap">
        select <include refid="Base_Column_List"/> from DSF_PUNISHSHEETINFO where GUID = #{guid}
    </select>



</mapper>

测试类:

import com.xxx.xxx.xxx.domain.entity.db2.DfcPunishSheetInfo;
import com.xxx.xxx.xxx.swap.util.JacksonUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DfcPunishSheetInfoMapperTest {
    @Autowired
    private DfcPunishSheetInfoMapper dfcPunishSheetInfoMapper;
    @Test
    void test01(){
        DfcPunishSheetInfo info = dfcPunishSheetInfoMapper.selectByGuid(544957876L);
        System.out.println(JacksonUtil.writeValueToString(info));
    }

}

 运行结果:

{
    "guid":544957876,
    "punishSheetNo":"652325100184036",
    "dealDate":1422934800000,
    "payDate":null
}

 如果运行过程出现以下错误:

java.lang.AbstractMethodError: Method oracle/jdbc/driver/OracleResultSetImpl.getObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; is abstract
 
	at oracle.jdbc.driver.OracleResultSetImpl.getObject(OracleResultSetImpl.java)
	at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:69)
	at com.sun.proxy.$Proxy93.getObject(Unknown Source)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:38)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:28)
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:81)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyAutomaticMappings(DefaultResultSetHandler.java:521)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:402)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
	at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:67)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
	at com.sun.proxy.$Proxy71.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:158)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:76)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:61)
	at com.sun.proxy.$Proxy74.selectList(Unknown Source)
	at com.hzsh.module.user.RetrieveTest.selectByWrapper8(RetrieveTest.java:176)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

网上都说oracle 驱动版本不对,都是扯淡的,我们还是要追源码解决!

问题分析,因为新功能后来加的,新建的实体类,其他的查询映射都是OK的,所以依赖包是没问题的。

关键看报错位置:Method oracle/jdbc/driver/OracleResultSetImpl.getObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; is abstract

追源码过程不贴了,最后发现:

oracle 表中字段是DATE类型,实体类用的LocalDateTime  在做字段映射时出现异常,

解决办法:

修改实体类LocalDateTime类型为Date类型
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 首先,为了使用多数据源和分布式事务,我们需要添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.6</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> ``` 接下来,我们需要在application.properties文件中配置数据源和事务管理器: ```properties # 配置主数据源 spring.datasource.url=jdbc:mysql://localhost:3306/main_db?characterEncoding=utf8&useSSL=false spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 配置从数据源 spring.datasource.slave.url=jdbc:mysql://localhost:3306/slave_db?characterEncoding=utf8&useSSL=false spring.datasource.slave.username=root spring.datasource.slave.password=root spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver # 配置Mybatis mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.example.entity # 配置Druid数据源 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.druid.initial-size=1 spring.datasource.druid.max-active=10 spring.datasource.druid.min-idle=1 spring.datasource.druid.max-wait=60000 spring.datasource.druid.time-between-eviction-runs-millis=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false spring.datasource.druid.filters=stat,wall,log4j spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 配置事务管理器 spring.transaction.default-timeout=600 spring.transaction.rollback-on-commit-failure=true spring.transaction.allow-bean-definition-overriding=true spring.transaction.jta.registry-name=atomikos spring.jta.enabled=true spring.jta.atomikos.connectionfactory.min-pool-size=5 spring.jta.atomikos.connectionfactory.max-pool-size=10 spring.jta.atomikos.connectionfactory.borrow-connection-timeout=30 spring.jta.atomikos.connectionfactory.max-idle-time=60 spring.jta.atomikos.connectionfactory.concurrency-level=100 ``` 然后,我们需要创建两个数据源的配置类,分别为主数据源和从数据源: ```java @Configuration @MapperScan(basePackages = "com.example.mapper.main", sqlSessionTemplateRef = "mainSqlSessionTemplate") public class MainDataSourceConfig { @Bean(name = "mainDataSource") @ConfigurationProperties(prefix = "spring.datasource") public DataSource mainDataSource() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "mainSqlSessionFactory") public SqlSessionFactory mainSqlSessionFactory(@Qualifier("mainDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/main/*.xml")); return bean.getObject(); } @Bean(name = "mainTransactionManager") public DataSourceTransactionManager mainTransactionManager(@Qualifier("mainDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "mainSqlSessionTemplate") public SqlSessionTemplate mainSqlSessionTemplate(@Qualifier("mainSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } } ``` ```java @Configuration @MapperScan(basePackages = "com.example.mapper.slave", sqlSessionTemplateRef = "slaveSqlSessionTemplate") public class SlaveDataSourceConfig { @Bean(name = "slaveDataSource") @ConfigurationProperties(prefix = "spring.datasource.slave") public DataSource slaveDataSource() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "slaveSqlSessionFactory") public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/slave/*.xml")); return bean.getObject(); } @Bean(name = "slaveTransactionManager") public DataSourceTransactionManager slaveTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "slaveSqlSessionTemplate") public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } } ``` 最后,我们需要在事务管理器上添加注解@EnableTransactionManagement,并在需要使用事务的方法上添加注解@Transactional: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Transactional(rollbackFor = Exception.class, transactionManager = "mainTransactionManager") @Override public void save(User user) { userMapper.insert(user); } @Transactional(rollbackFor = Exception.class, transactionManager = "slaveTransactionManager") @Override public User findById(int id) { return userMapper.selectByPrimaryKey(id); } } ``` 以上就是使用SpringBoot+Mybatis+druid多数据源和分布式事务的基本步骤。 ### 回答2: Spring Boot是一个用于构建独立的、生产级的应用程序的框架。它简化了应用程序的开发过程,并通过自动配置来减少了繁琐的配置。MyBatis是一个ORM(对象关系映射)框架,它提供了将数据库操作映射到Java对象的功能。Druid是一种高性能的数据库连接池。 要在Spring Boot中使用MyBatis和Druid进行多数据源配置和分布式事务管理,可以按照以下步骤进行操作: 1. 添加依赖:在项目的pom.xml文件中,添加Spring BootMyBatis和Druid的依赖。 2. 配置数据源:在application.properties文件中,配置并命名多个数据源,设置数据库连接等信息。 3. 创建数据源配置类:创建一个配置类,使用@Configuration注解将其标记为配置类,并使用@ConfigurationProperties注解将数据源属性注入。 4. 创建数据源:根据配置类中的属性,创建多个数据源,并将其加入到数据源路由器中。 5. 配置MyBatis:创建一个配置类,使用@MapperScan注解设置MyBatis的mapper接口路径,并将数据源注入到SqlSessionFactory中。 6. 配置分布式事务:使用@EnableTransactionManagement注解启用事务管理,并配置事务管理器。 7. 编写数据库操作代码:在mapper接口中定义数据库操作方法,并在Service层中调用这些方法进行数据库操作。 通过以上步骤,你就可以在Spring Boot项目中完成MyBatis和Druid的多数据源配置和分布式事务管理。不过需要注意的是,使用多数据源和分布式事务会增加项目的复杂性和性能开销,所以在使用之前需要仔细考虑是否真正需要这些功能。 ### 回答3: Spring Boot是一种快速构建Java应用程序的框架,MyBatis是一种流行的Java持久化框架,Druid是一种高性能的数据库连接池。本文将介绍如何在Spring Boot中使用MyBatis和Druid来实现多数据源和分布式事务。 要使用多个数据源,我们首先需要配置多个数据源。在Spring Boot中,我们可以通过在application.properties或者application.yml文件中配置多个数据源的连接信息。我们需要为每个数据源指定不同的URL、用户名和密码。然后,我们可以使用@Primary和@Qualifier来指定主数据源和其他数据源。 在配置数据源后,我们需要配置MyBatis来使用这些数据源。我们可以通过创建多个SqlSessionFactory来实现多数据源,然后在每个SqlSessionFactory中设置相应的数据源。我们还可以使用@MapperScan注解来自动扫描和注册Mapper接口。 在使用MyBatis和多个数据源时,我们可能会遇到事务管理的问题。为了解决这个问题,我们可以使用Spring Boot提供的@Transactional注解来标记需要进行事务管理的方法,然后Spring Boot会自动为我们处理事务。对于需要跨多个数据源进行事务管理的情况,我们可以使用JTA(Java Transaction API)实现分布式事务。在Spring Boot中,我们可以使用Atomikos或Bitronix等JTA提供商来实现分布式事务。 总结起来,使用Spring BootMyBatis和Druid,我们可以很容易地实现多数据源和分布式事务。通过正确配置数据源和使用相关注解,我们可以在几分钟内完成这些任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值