在使用mybatis plus 时这个增强工具最大的贡献就是代码自动生成:(代码自动生成文章)https://blog.csdn.net/weixin_45863786/article/details/104544388(解决 not found mapper:https://blog.csdn.net/weixin_45863786/article/details/110954847),和BaseMapper增强工具,如果在某些业务情况下考虑跨数据库服务查询,怎样解决mybatis plus 多数据源问题,及使用多数据源无法使用BaseMapper增强工具解决方法,直接上代码。
#多数据源配置
datasource.ev.driver-class-name = com.mysql.cj.jdbc.Driver
datasource.ev.url = jdbc:mysql://xx.xxx.xx.xx:6033/ev?useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&useSSL=false&jdbcCompliantTruncation=false
datasource.ev.username = xx
datasource.ev.password = xx
datasource.l2.driver-class-name = com.mysql.cj.jdbc.Driver
datasource.l2.url = jdbc:mysql://xx.xxx.xx.xx:3306/iov_cpsp?useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&jdbcCompliantTruncation=false
datasource.l2.username = xx
datasource.l2.password = xx
datasource.app.driver-class-name = com.mysql.cj.jdbc.Driver
datasource.app.url = jdbc:mysql://xx.xxx.xx.xx:3306/fleet?useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&jdbcCompliantTruncation=false
datasource.app.username = xx
datasource.app.password = xx
package com.ly.mp.app.common.multiple.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 定义数据源枚举
* @author huangan
* @date 2020/11/30 9:56
*/
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum DataSourceEnum {
EV("ev"),
L2("l2"),
APP("app");
private String value;
}
package com.ly.mp.app.common.multiple.annotation;
import com.ly.mp.app.common.multiple.enums.DataSourceEnum;
import java.lang.annotation.*;
/**
* 定义数据源注解
* @author huangan
* @date 2020/11/30 9:58
*/
@Inherited
@Target(value = {ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
DataSourceEnum value() default DataSourceEnum.EV;
}
package com.ly.mp.app.common.multiple;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 多数据源
* @author huangan
* @date 2020/11/30 10:09
*/
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal contextHolder = new InheritableThreadLocal<>();
@Override
protected Object determineCurrentLookupKey() {
return this.getDataSource();
}
/**
* 设置数据源
*
* @param db
*/
public static void setDataSource(String db) {
contextHolder.set(db);
}
/**
* 取得当前数据源
*
* @return
*/
public static String getDataSource() {
return contextHolder.get();
}
/**
* 清除上下文数据
*/
public static void clear() {
contextHolder.remove();
}
}
package com.ly.mp.app.common.multiple.aop;
import com.ly.mp.app.common.multiple.MultipleDataSource;
import com.ly.mp.app.common.multiple.annotation.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* 数据要aop切换
* @author huangan
* @date 2020/11/30 10:07
*/
@Component
@Slf4j
@Aspect
@Order(-1)
public class DataSourceAspect {
@Pointcut("this(com.baomidou.mybatisplus.core.mapper.BaseMapper)")
private void pointCut() { }
@Before("pointCut()")
public void before(JoinPoint joinPoint){
Class> c = joinPoint.getTarget().getClass();
//获取构造函数中的
Class>[] interfaces = c.getInterfaces();
Arrays.stream(interfaces).forEach(
x->{
if(x.isAnnotationPresent(DataSource.class)){
DataSource dataSourceKey = x.getAnnotation(DataSource.class);
MultipleDataSource.setDataSource(dataSourceKey.value().getValue());
}
}
);
}
@After("pointCut()")
public void doAfter() {
MultipleDataSource.clear();
}
}
package com.ly.mp.app.config;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.ly.mp.app.common.multiple.MultipleDataSource;
import com.ly.mp.app.common.multiple.enums.DataSourceEnum;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* MybatisPlus配置类
* @author huangan
* @date 2020/11/16 17:36
*/
@Configuration
public class MybatisPlusConfig {
/**
* @description: 配置分页插件
* @author: gradual
* @param: []
* @return: com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
/**
* @description: SQL执行效率插件
* @author: gradual
* @param: []
* @return: com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
/**
* 逻辑删除用,3.1.1之后的版本可不需要配置该bean,但项目这里用的是3.1.0的
* @author David Hong
* @return com.baomidou.mybatisplus.core.injector.ISqlInjector
*/
@Bean
public ISqlInjector sqlInjector() {
return (ISqlInjector) new LogicSqlInjector();
}
@Bean(name = "l2")
@ConfigurationProperties(prefix = "datasource.l2")
public DataSource l2() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "app")
@ConfigurationProperties(prefix = "datasource.app")
public DataSource app() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "globalConfig")
@Primary
public GlobalConfig globalConfig() {
GlobalConfig globalConfig = new GlobalConfig();
return globalConfig;
}
@Bean
@Primary
public DataSource multipleDataSource(@Qualifier("l2") DataSource l2,@Qualifier("app") DataSource app) {
MultipleDataSource multipleDataSource = new MultipleDataSource();
Map
package com.ly.mp.app.mapper;
import com.ly.mp.app.common.multiple.annotation.DataSource;
import com.ly.mp.app.common.multiple.enums.DataSourceEnum;
import com.ly.mp.app.entity.po.TAppUserPassLogin;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
*
* 用户登录验证 Mapper 接口
*
*
* @author huangan
* @since 2020-12-07
*/
@DataSource(DataSourceEnum.APP)
public interface TAppUserPassLoginMapper extends BaseMapper {
}