springboot集成@DS注解实现数据源切换的方法示例

下面是针对“springboot集成@DS注解实现数据源切换的方法示例”的详细讲解,包括两个示例。

一、简介

在Spring Boot中,实现数据源切换最常用的方式是使用@DS注解。它可以在运行时动态地切换数据源。这个注解是基于MyBatis-Plus的,需要引入MyBatis-Plus的核心依赖。

二、操作步骤

1. 引入相关依赖

在pom.xml文件中加入以下依赖:

<!-- 引入MyBatis-Plus核心依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>

2. 定义数据源配置类

创建一个DataSourceConfig类,用于定义数据源的相关信息,其中@Primary注解用于定义主数据源。

@Configuration
@MapperScan(basePackages = "com.example.demo.mapper")
@EnableTransactionManagement
public class DataSourceConfig {

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

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

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

    @Bean
    @ConditionalOnMissingBean(SqlSessionFactory.class)
    public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    @ConditionalOnMissingBean(SqlSessionTemplate.class)
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

3. 定义数据源切换注解

创建一个注解,用于声明需要切换到哪个数据源。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DS {

    String value() default "master";
}

4. 定义数据源切换切面

创建一个切面,用于在执行数据库操作前切换数据源。

@Slf4j
@Aspect
@Component
public class DataSourceAspect {

    @Pointcut("@annotation(com.example.demo.annotation.DS)")
    public void dsPointCut() {}

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DS ds = signature.getMethod().getAnnotation(DS.class);
        if (ds == null) {
            DynamicDataSourceContextHolder.setDataSourceKey("master");
        } else {
            DynamicDataSourceContextHolder.setDataSourceKey(ds.value());
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceKey();
        }
    }

}

5. 使用@DS注解切换数据源

在需要切换数据源的Service或Mapper中使用@DS注解。如果不加@DS注解,则默认使用主数据源。

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    @DS("slave")
    public List<User> list() {
        return userMapper.selectList(null);
    }

}

三、示例

示例1

以下示例中,我们通过调用UserService的list()方法来实现数据源的切换。由于这里使用了@DS注解,所以数据源会切换到slave数据源。

创建用户表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sex` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

创建一个User实体类,用于封装用户信息:

@Data
@EqualsAndHashCode(callSuper = false)
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 姓名
     */
    @TableField("name")
    private String name;

    /**
     * 性别
     */
    @TableField("sex")
    private String sex;

}

创建UserMapper,用于操作用户表:

public interface UserMapper extends BaseMapper<User> {
}

创建UserService,用于调用UserMapper来操作数据库:

public interface UserService {

    List<User> list();
}

创建UserServiceImpl,实现UserService:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    @DS("slave")
    public List<User> list() {
        return userMapper.selectList(null);
    }

}

最后,在Controller中调用UserService的list()方法,来获取所有用户信息:

@RestController
public class UserController {

    @Autowired
    private UserService userService;

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

}

示例2

以下示例中,我们使用了@EnableAspectJAutoProxy注解,来开启自动代理,从而实现数据源的切换。

创建User2实体类:

@Data
public class User2 {

    /**
     * 用户ID
     */
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 手机号
     */
    private String mobile;

}

创建User2Mapper:

@Mapper
public interface User2Mapper {

    @DS("slave")
    @Select("select * from user2")
    List<User2> list();

    @Insert("insert into user2(username, password, email, mobile) values(#{username}, #{password}, #{email}, #{mobile})")
    void insert(User2 user2);

}

创建UserService2:

@Service
public class UserService2 {

    @Autowired
    private User2Mapper user2Mapper;

    public List<User2> list() {
        return user2Mapper.list();
    }

    public void insert(User2 user2) {
        user2Mapper.insert(user2);
    }

}

创建UserController2:

@RestController
public class UserController2 {

    @Autowired
    private UserService2 userService2;

    @RequestMapping("/users2")
    public List<User2> list() {
        return userService2.list();
    }

    @RequestMapping("/insert")
    public String insert() {
        User2 user2 = new User2();
        user2.setUsername("test");
        user2.setPassword("123456");
        user2.setEmail("test@example.com");
        user2.setMobile("13800138000");
        userService2.insert(user2);
        return "success";
    }

}

最后,在Application类中添加@EnableAspectJAutoProxy注解,并运行程序,通过curl命令测试:

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class App {
    public static void main( String[] args ) {
        SpringApplication.run(App.class, args);
    }
}
curl http://localhost:8080/users2

四、总结

通过以上步骤,我们就可以实现在Spring Boot中使用@DS注解来实现数据源切换了。在实际的项目中,我们可能需要对数据源进行更加复杂的配置,但是这并不影响我们使用@DS注解来实现数据源的切换,使得我们的应用更加灵活多变。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot集成@DS注解实现数据源切换的方法示例 - Python技术站

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

相关文章

  • Spring Boot日志的打印与持久化详细解析

    Spring Boot日志的打印与持久化详细解析 在Spring Boot应用中,日志是开发和调试的重要工具。通过合理的配置,我们可以实现日志的打印和持久化,方便问题的排查和解决。本文将详细介绍Spring Boot日志的打印与持久化,并包含两条示例。 Spring Boot日志的分类 Spring Boot日志分为如下五个级别: TRACE:跟踪级别,最低…

    Java 2023年5月19日
    00
  • Springboot文件上传功能的实现

    在Spring Boot应用程序中,我们可以使用MultipartFile类和Spring的MultipartResolver接口来实现文件上传功能。在本文中,我们将介绍如何实现Spring Boot文件上传功能。 增加依赖 首先,我们需要在pom.xml文件中增加Spring Boot Web依赖。下面是一个示例: <dependency> &…

    Java 2023年5月18日
    00
  • Java使用pulsar-flink-connector读取pulsar catalog元数据代码剖析

    Java使用Pulsar-Flink-Connector读取Pulsar Catalog元数据代码剖析 简介 Pulsar-Flink-Connector是Flint消费者应用程序和Pulsar之间的桥梁。其提供了灵活且易于使用的API,使得Flint应用程序能够轻松连接和消费Pulsar消息流。本文将详细介绍如何使用Java语言的Pulsar-Flink-…

    Java 2023年6月2日
    00
  • Spring Boot整合web层实现过程详解

    下面给出详细的“SpringBoot整合web层实现过程详解”: 1. 引入依赖 SpringBoot已经内置了常用的Web框架,如SpringMVC、Spring WebFlux等。因此,我们只需要在pom.xml中引入SpringBoot Web依赖即可。 <dependencies> <!–Web相关依赖–> <dep…

    Java 2023年5月15日
    00
  • 使用list stream: 任意对象List拼接字符串

    使用List Stream将任意对象列表拼接成字符串,可以通过以下步骤完成: 准备任意对象类型的列表。 使用 List Stream 将列表转换为字符串。 使用 Collectors.joining() 方法拼接列表元素。 下面是将任意对象列表拼接为字符串的完整代码示例: List<User> userList = Arrays.asList( …

    Java 2023年5月27日
    00
  • spring如何快速稳定解决循环依赖问题

    循环依赖是指两个或多个bean之间互相依赖,形成了循环依赖的关系。这种循环依赖会导致Spring IoC容器无法对bean进行正确的初始化和装配,从而引发一系列问题。这里将详细讲解Spring如何快速稳定解决循环依赖问题的完整攻略。 解决方式一:构造器注入 构造器注入是一种避免循环依赖的较为简单而又有效的方式。具体的实现步骤如下: 将bean的所有依赖项作为…

    Java 2023年5月19日
    00
  • Spring Security动态权限的实现方法详解

    Spring Security动态权限的实现方法详解 什么是动态权限? 在传统的企业应用中,权限被存储在静态的权限表中,着重强调的是用户拥有哪些权限。但是在现实生活中,我们会发现企业的角色是十分复杂的,拥有权限表面看起来是不够的。例如,对于一个CRM系统,管理员可能需要对某些用户进行一些特殊的操作。这种情况下,我们需要实现动态权限,即在运行时动态授权,而不是…

    Java 2023年5月20日
    00
  • JSON各种转换问题(json转List,json转对象等)

    让我为你详细讲解一下“JSON各种转换问题(json转List,json转对象等)”的完整攻略。 JSON转List 假设有一个JSON数组如下: [ { "name": "张三", "age": 23 }, { "name": "李四", "age…

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