tk-mybatis整合springBoot使用两个数据源的方法

下面是“tk-mybatis整合springBoot使用两个数据源的方法”的完整攻略及两条示例:

一、准备工作

在进行整合之前,我们需要做以下准备工作:

  1. 创建两个数据库,分别为db1db2,并分别创建表user,表结构如下:
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
  1. pom.xml中添加tk-mybatisdruidmysql-connector-java依赖:
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.1.5</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.9</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.22</version>
</dependency>

二、配置数据源

application.yml中配置数据源,如下:

spring:
  datasource:
    master:
      url: jdbc:mysql://localhost:3306/db1?useSSL=false&serverTimezone=UTC
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
    slave:
      url: jdbc:mysql://localhost:3306/db2?useSSL=false&serverTimezone=UTC
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver

### druid连接池配置
  druid:
    master:
      maxActive: 32
      initialSize: 2
      minIdle: 2
      maxWait: 60000
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      validationQuery: select 1 from dual
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      filters: stat
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    slave:
      maxActive: 32
      initialSize: 2
      minIdle: 2
      maxWait: 60000
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      validationQuery: select 1 from dual
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      filters: stat
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

上面的配置中,我们使用了两个数据源,分别为masterslave,并分别对应db1db2两个数据库。其中,我们使用了druid连接池来管理数据源,提高应用的性能。

三、整合tk-mybatis

application.yml中配置tk-mybatis,如下:

tk:
  mybatis:
    mapper-locations: classpath:mapper/**Mapper.xml
    config-location: classpath:mybatis-config.xml
    check-config-location: true
    mapper-ids: com.example.mapper.*
    sqlSessionTemplate:
      masters: masterSqlSessionTemplate
      slaves: slaveSqlSessionTemplate

com.example.config包中创建DataSourceConfig类,如下:

@Configuration
@Slf4j
public class DataSourceConfig {

    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    public DynamicDataSource dynamicDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                               @Qualifier("slaveDataSource") DataSource slaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>(2);
        targetDataSources.put("master", masterDataSource);
        targetDataSources.put("slave", slaveDataSource);
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
        return dynamicDataSource;
    }

    @Bean(name = "masterTransactionManager")
    public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "slaveTransactionManager")
    public DataSourceTransactionManager slaveTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/master/*.xml"));
        return bean.getObject();
    }

    @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 = "masterSqlSessionTemplate")
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "slaveSqlSessionTemplate")
    public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

com.example.config包中创建DynamicDataSource类,实现动态数据源切换,代码如下:

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSource();
    }

}

com.example.config包中创建DynamicDataSourceContextHolder类,定义数据源的上下文,代码如下:

public class DynamicDataSourceContextHolder {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    /**
     * 设置数据源名
     *
     * @param dataSource 数据源名
     */
    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    /**
     * 获取数据源名
     *
     * @return 数据源名
     */
    public static String getDataSource() {
        return contextHolder.get();
    }

    /**
     * 清除数据源名
     */
    public static void clearDataSource() {
        contextHolder.remove();
    }

}

com.example.aop包中创建DataSourceAop类,为数据源切换提供切面支持,代码如下:

@Slf4j
@Aspect
@Component
public class DataSourceAop {

    @Pointcut("@annotation(com.example.annotation.Slave) ")
    public void dsSlavePointcut() {
    }

    @Before("dsSlavePointcut()")
    public void setSlaveDataSource(JoinPoint joinPoint) {
        DynamicDataSourceContextHolder.setDataSource("slave");
    }

    @After("dsSlavePointcut()")
    public void restoreDataSource(JoinPoint joinPoint) {
        DynamicDataSourceContextHolder.clearDataSource();
    }

}

com.example.annotation包中创建Slave注解,用于标注从数据源,代码如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Slave {

}

四、示例

1. 使用主数据源的示例

com.example.mapper.master包中创建UserMapper接口,定义查询方法,如下:

@Mapper
public interface UserMapper {

    List<User> selectAll();

}

com.example.service包中创建UserService类,注入UserMapper,实现查询所有用户的方法,如下:

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public List<User> getAllUsers() {
        return userMapper.selectAll();
    }

}

com.example.controller包中创建UserController类,注入UserService,实现查询所有用户的接口,如下:

@RestController
public class UserController {

    @Autowired
    UserService userService;

    @GetMapping("/users")
    public List<User> getUsers() {
        return userService.getAllUsers();
    }

}

启动应用,在浏览器中访问http://localhost:8080/users,可以查看到主数据源中的所有用户。

2. 使用从数据源的示例

com.example.mapper.slave包中创建UserMapper接口,定义查询方法,如下:

@Mapper
public interface UserMapper {

    @Slave
    List<User> selectAll();

}

com.example.service包中创建UserService类,注入UserMapper,实现查询所有用户的方法,如下:

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public List<User> getAllUsers() {
        return userMapper.selectAll();
    }

}

com.example.controller包中创建UserController类,注入UserService,实现查询从数据源所有用户的接口,如下:

@RestController
public class UserController {

    @Autowired
    UserService userService;

    @GetMapping("/slave-users")
    public List<User> getSlaveUsers() {
        return userService.getAllUsers();
    }

}

启动应用,在浏览器中访问http://localhost:8080/slave-users,可以查看到从数据源中的所有用户。

到这里,tk-mybatis整合springBoot使用两个数据源的方法就详细讲解完毕了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:tk-mybatis整合springBoot使用两个数据源的方法 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 全面汇总SpringBoot和SpringClould常用注解

    Spring Boot和Spring Cloud是Java开发中非常流行的框架,它们提供了许多注解来帮助开发人员更加高效地构建和部署应用程序。本文将全面汇总Spring Boot和Spring Cloud常用注解,并提供两个示例来演示如何使用这些注解。 Spring Boot常用注解 @SpringBootApplication @SpringBootApp…

    Java 2023年5月15日
    00
  • form表单数据封装成json格式并提交给服务器的实现方法

    将Form表单数据封装成JSON格式并提交给服务器的实现方法具体分为两个步骤: 获取表单数据并封装成JSON格式 在前端使用JavaScript将表单数据封装成JSON格式,JavaScript中可以使用FormData对象来获取表单数据,再将其转换为JSON格式.以下是封装成JSON格式的示例代码: // 获取表单数据并封装成JSON格式 let form…

    Java 2023年6月15日
    00
  • 在JSP中如何实现MD5加密的方法

    在JSP中实现MD5加密有多种方法,其中最为常见的是使用Java的MessageDigest类。下面是实现MD5加密的完整攻略。 步骤一:引入MessageDigest类 Java的MessageDigest类是用于生成消息摘要的工具类。为了在JSP中使用它,我们需要在JSP页面中导入java.security.MessageDigest类。 <%@ …

    Java 2023年6月15日
    00
  • Java 下数据业务逻辑开发技术 JOOQ 和 SPL

    Java 下数据业务逻辑开发技术 JOOQ 和 SPL 的完整攻略 JOOQ(Java Object Oriented Querying)是一个 Java 版本的关系型数据库操作工具,它可以让用户使用 Java 对象和方法进行 SQL 查询和更新操作,JOOQ 可以解决 SQL 代码繁琐、难以维护、不能重用等问题。而 SPL(Stored Procedure…

    Java 2023年5月19日
    00
  • Android互联网访问图片并在客户端显示的方法

    下面是详细的”Android互联网访问图片并在客户端显示的方法”攻略: 1. 加载本地图片 在Android中,你可以通过使用ImageView组件来显示一张本地的图片。下面是一个示例代码,该代码将图片文件res/drawable-hdpi/icon.png放入ImageView组件中。 <ImageView android:id="@+id…

    Java 2023年6月15日
    00
  • Java实现经典游戏泡泡堂的示例代码

    Java实现经典游戏泡泡堂的示例代码攻略 概述 本文将介绍如何使用Java实现经典游戏泡泡堂的示例代码。泡泡堂是一款非常受欢迎的街机游戏,同时它也是一款非常好的练习Java编程技巧的项目,包括了面向对象编程、多线程、网络编程等各种核心技术点。 准备工作 在开始编写泡泡堂代码之前,我们需要先准备一些工作: 安装Java JDK,并设置好环境变量; 选择一个合适…

    Java 2023年5月19日
    00
  • Java 内存安全问题的注意事项

    Java 内存安全问题的注意事项 Java 是目前世界上使用最广泛的编程语言之一,因为其平台无关性和安全性被广泛应用于企业级应用开发和互联网应用开发等各个领域。但是,在使用 Java 进行编程时,我们也需要注意 Java 内存安全问题。 什么是 Java 内存安全问题 Java 内存安全问题是指程序中发生的由于原始数据类型和对象的引用不当使用,导致程序在运行…

    Java 2023年5月27日
    00
  • Java Instrumentation API的作用是什么?

    Java Instrumentation API是一个强大的工具,允许开发人员在运行时修改Java应用程序的字节码。它提供了一个API来监视和管理类的加载,允许我们在运行时操作Java类。该API的主要作用有: 在类加载器将类加载到Java虚拟机(JVM)中之前转换类的字节码; 测量代码的性能; 在运行时收集和处理Java类的状况信息,以便深入调试问题。 在…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部