Mybatis-Plus 之【数据源配置(含多数据源配置)】

MybatisPlus【数据源配置(单、多数据源)】


前言

MybatisPlus多数据源配置主要解决的是多数据库连接和切换的问题。在一些大型应用中,由于数据量的增长或者业务模块的增多,可能需要访问多个数据库。这时,就需要配置多个数据源。


一、单数据源配置

使用方法

坐标依赖:

<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.1</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.28</version>
</dependency>

application.yml配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

通用配置

配置类

@Configuration
@MapperScan(basePackages = {"com.xx.**.mapper"})
public class MybatisPlusConfig {
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
    	//新的分页插件配置方法(Mybatis Plus 3.4.0版本及其之后的版本)
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

二、多数据源配置

坐标依赖【新增】:

<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
	<version>3.1.0</version>
</dependency>

application.yml配置

spring:
  datasource:
    db1:
      url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
    db2:
      url: jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver

1.单配置类

使用方法【配合注解@DS(“db1”)】

@DS(“db1”)是一个MyBatis的注解,用于动态数据源切换。在MyBatis中,我们可以通过在mapper.xml文件或者Java接口上使用@DS注解来指定数据源。

实体类

@Data
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Integer id;
    @TableField("name")
    private String name;
}

Service

@Service
@DS("db1")
public class UserServiceImpl implements UserService {
 
  @Autowired
  private JdbcTemplate jdbcTemplate;
 
  public List selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
 
  @Override
  @DS("db1_1")
  public List selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}

@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。

2.多配置类

使用方法【根据不同Mapper路径配置不同数据源】

多配置类【根据自己需要使用的插件进行配置、不需要的可以删除】

@Configuration
@MapperScan(basePackages = "com.xx.xx.mapper.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")
public class db1DataSourceConfig {
    // 将这个对象放入Spring容器中
    @Bean(name = "db1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource getDateSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "db1SqlSessionFactory")
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource datasource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //configuration配置bean
        //MybatisConfiguration configuration = new MybatisConfiguration();
        //configuration.setMapUnderscoreToCamelCase(true);
        //configuration.setCacheEnabled(false);
        // 配置打印sql语句s
        //configuration.setLogImpl(StdOutImpl.class);
        // 添加自定义SQL注入
        //bean.setConfiguration(configuration);

        //插件对象
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //动态表名
        //DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
		//可以传多个表名参数,指定哪些表使用MonthTableNameHandler处理表名称
        //dynamicTableNameInnerInterceptor.setTableNameHandler(new MonthTableNameHandler("t_table_name"));
		//以拦截器的方式处理表名称
		//可以传递多个拦截器,即:可以传递多个表名处理器TableNameHandler
        //mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);


        //分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        bean.setDataSource(datasource);
        // 设置mybatis的xml所在位置
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/db1/*.xml"));
        bean.setPlugins(mybatisPlusInterceptor);
        return bean.getObject();
    }

    @Bean("db1SqlSessionTemplate")
    public SqlSessionTemplate db1SqlSessionTemplate(
            @Qualifier("db1SqlSessionFactory") SqlSessionFactory sessionFactory) {
        return new SqlSessionTemplate(sessionFactory);
    }

    @Bean("db1TransactionManager")
    public PlatformTransactionManager db1TransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
@Configuration
@MapperScan(basePackages = "com.xx.xx.mapper.db2", sqlSessionFactoryRef = "db2SqlSessionFactory")
public class db2DataSourceConfig {
    // 将这个对象放入Spring容器中
    @Bean(name = "db2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource getDateSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "db2SqlSessionFactory")
    public SqlSessionFactory db2SqlSessionFactory(@Qualifier("db2DataSource") DataSource datasource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        // 设置mybatis的xml所在位置
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/db2/*.xml"));
        bean.setPlugins(mybatisPlusInterceptor);
        return bean.getObject();
    }

    @Bean("db2SqlSessionTemplate")
    public SqlSessionTemplate db2SqlSessionTemplate(
            @Qualifier("db2SqlSessionFactory") SqlSessionFactory sessionFactory) {
        return new SqlSessionTemplate(sessionFactory);
    }

    @Bean("db2TransactionManager")
    public PlatformTransactionManager db2TransactionManager(@Qualifier("db2DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

数据源为db1

package com.xx.xx.mapper.db1;
/**
 Mapper 接口
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DynamicApplication{
    public static void main(String[] args) {
        SpringApplication.run(DynamicApplication.class, args);
    }
}

3.AOP动态切换数据源

使用方法【自定义注解方式】

动态数据源切换类

@NoArgsConstructor
public class DynamicDataSource extends AbstractRoutingDataSource {

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

    /**
     * 取得当前使用的数据源
     * @return 当前使用的数据源
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return getDataSource();
    }

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

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

    /**
     * 清除上下文
     */
    public static void clearDataSource() {
        DB_CONTEXT_HOLDER.remove();
    }

    /**
     * 设置默认数据源,和可切换的数据源Map
     * @param defaultTargetDataSource 默认数据源
     * @param targetDataSources 可切换的数据源Map
     */
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }
}

多数据源配置类

@Component
@Configuration
public class DataSourceConfig {

    /**
     * 创建数据源db1
     * @return 数据源db1
     */
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db1")
    public DataSource db1DataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 创建数据源db2
     * @return 数据源db2
     */
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db2")
    public DataSource db2DataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 数据源配置
     * @param db1数据源db1
     * @param db2数据源db2
     * @return 动态数据源切换对象。
     * @Description @Primary赋予该类型bean更高的优先级,使至少有一个bean有资格作为autowire的候选者。
     */
    @Bean
    @Primary
    public DataSource dataSource(@Qualifier("db1") DataSource db1,
                                 @Qualifier("db2") DataSource db2) {
        Map<Object, Object> dsMap = new HashMap<>(2);
        dsMap.put("db1", db1);
        dsMap.put("db2", db2);
        return new DynamicDataSource(db1, dsMap);
    }
}

启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@Import({DataSourceConfig.class})
public class DynamicApplication{
    public static void main(String[] args) {
        SpringApplication.run(DynamicApplication.class, args);
    }

}

创建自定义注解【用来指定使用哪个数据源】

/**
 * @Description 在方法上使用,用于指定使用哪个数据源
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    String name() default "";
}

创建AOP【根据注解的参数切换数据源】

/**
 * @Description 多数据源切换AOP,@Order(-100)是为了保证AOP在事务注解之前生效,Order的值越小,优先级越高
 */
@Aspect
@Component
@Order(-100)
@Slf4j
public class DataSourceAspect {

    @Pointcut("execution(* com.xx.xx.service..*.*(..))")
    private void dsPointCut() {
    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取当前指定的数据源
        MethodSignature ms = (MethodSignature) joinPoint.getSignature();
        Method method = ms.getMethod();
        DataSource dataSource = method.getAnnotation(DataSource.class);

        if (Objects.isNull(dataSource)) {
            // 使用默认数据源
            DynamicDataSource.setDataSource("db1");
            log.info("默认数据源启动");
        } else {
            // 匹配到的话,设置到动态数据源上下文中
            DynamicDataSource.setDataSource(dataSource.name());
            log.info("匹配到数据源:{}", dataSource.name());
        }

        try {
            // 执行目标方法,返回值即为当前方法的返回值
            return joinPoint.proceed();
        } finally {
            // 方法执行完毕之后,销毁当前数据源信息,进行垃圾回收
            DynamicDataSource.clearDataSource();
            log.info("清空数据源");
        }
    }
}

Service

@Service
public class UserServiceImpl implements UserService {
 
  @Autowired
  private JdbcTemplate jdbcTemplate;
 
  @DataSource(name = "db1")
  public List selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
 
  @Override
  @DataSource(name = "db2")
  public List selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}

总结

1、三种数据源配置的方法可根据实际需要选择
2、使用 @DS 注解切换数据源时,使用springboot数据源的自动配置,需要将DataSourceConfig配置注释掉
3、使用 @DataSource 自定义注解时,排除springboot数据源的自动配置,引入DataSourceConfig配置

  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Spring Boot中整合Mybatis配置JNDI数据源的方法如下: 1. 在application.properties或application.yml文件中,配置JNDI数据源的相关信息。例如,可以使用以下配置: ``` spring.datasource.jndi-name=jndi/oscardb ``` 2. 在Mybatis配置文件中,指定Mapper文件的位置。例如,可以使用以下配置: ``` mybatis.mapper-locations=classpath:mapper/*.xml ``` 3. 在Spring Boot的启动类中,添加`@MapperScan`注解来扫描Mapper接口。例如,可以使用以下配置: ``` @SpringBootApplication @MapperScan("com.example.mapper") public class Application { public static void main(String\[\] args) { SpringApplication.run(Application.class, args); } } ``` 4. 在Spring Boot配置类中,使用`@Bean`注解配置JNDI数据源。例如,可以使用以下配置: ``` @Configuration public class DataSourceConfig { @Bean public DataSource dataSource() throws NamingException { JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean(); jndiObjectFactoryBean.setJndiName("java:comp/env/jdbc/数据库名"); jndiObjectFactoryBean.afterPropertiesSet(); return (DataSource) jndiObjectFactoryBean.getObject(); } } ``` 通过以上步骤,你可以在Spring Boot中成功配置JNDI数据源并整合Mybatis。 #### 引用[.reference_title] - *1* [springboot + mybatis + jndi](https://blog.csdn.net/jiandong06/article/details/108659673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [SpringBoot整合MybatisPlus多数据源](https://blog.csdn.net/qq_37284798/article/details/129279732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring整合mybatis配置JNDI数据源](https://blog.csdn.net/mwx523037520036/article/details/127700054)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值