mybaties-plus 代码生成器
导入依赖
<!--不需要添加 Mybatis及Mybatis-Spring依赖,Mybatis-Plus会自动维护-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--生成文件所需模板引擎-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
package com.faraway.yy_commons.mybaties;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;
/**
*
* 代码生成器
*
* @author yuanyao@wistronits.com
* create on 2018/7/19 下午4:06
*/
@Slf4j
public class MpGenerator {
public static void main(String[] args) {
AutoGenerator autoGenerator = new AutoGenerator();
// 选择模板引擎
autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setAuthor("yuanyao@wistronits.com");
gc.setOutputDir("/Users/yaoyuan/Desktop/itom_FH/yy_commons/src/main/java");
gc.setFileOverride(false); // 是否覆盖同名文件
gc.setActiveRecord(true);
gc.setEnableCache(false); // 二级缓存
gc.setBaseResultMap(true);
gc.setBaseColumnList(false);
/* 自定义文件命名,注意 %s 会自动填充表实体属性! */
// gc.setMapperName("%sDao");
// gc.setXmlName("%sDao");
// gc.setServiceName("MP%sService");
// gc.setServiceImplName("%sServiceDiy");
// gc.setControllerName("%sAction");
autoGenerator.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert() {
// 自定义数据库表字段类型转换【可选】
@Override
public DbColumnType processTypeConvert(String fieldType) {
System.out.println("转换类型:" + fieldType);
// 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。
return super.processTypeConvert(fieldType);
}
});
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("yaoyuan12345");
dsc.setUrl("jdbc:mysql://localhost:3306/yy_commons?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false");
autoGenerator.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
// strategy.setTablePrefix(new String[] { "test_" });// 此处可以修改为您的表前缀
strategy.setNaming(NamingStrategy.nochange);// 表名生成策略
strategy.setInclude(new String[] { "user" }); // 需要生成的表
// strategy.setExclude(new String[]{"test"}); // 排除生成的表
// 自定义实体父类
// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
// 自定义实体,公共字段
// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
// 自定义 mapper 父类
// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
// 自定义 service 父类
// strategy.setSuperServiceClass("com.baomidou.demo.TestService");
// 自定义 service 实现类父类
// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
// 自定义 controller 父类
// strategy.setSuperControllerClass("com.baomidou.demo.TestController");
// 【实体】是否生成字段常量(默认 false)
// public static final String ID = "test_id";
// strategy.setEntityColumnConstant(true);
// 【实体】是否为构建者模型(默认 false)
// public User setName(String name) {this.name = name; return this;}
// strategy.setEntityBuilderModel(true);
autoGenerator.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.faraway.yy_commons.mybaties.bean");
// pc.setModuleName("test");
autoGenerator.setPackageInfo(pc);
// 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
// InjectionConfig cfg = new InjectionConfig() {
// @Override
// public void initMap() {
// Map<String, Object> map = new HashMap<String, Object>();
// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
// this.setMap(map);
// }
// };
//
// // 自定义 xxList.jsp 生成
// List<FileOutConfig> focList = new ArrayList<>();
// focList.add(new FileOutConfig("/template/list.jsp.vm") {
// @Override
// public String outputFile(TableInfo tableInfo) {
// // 自定义输入文件名称
// return "D://my_" + tableInfo.getEntityName() + ".jsp";
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 调整 xml 生成目录演示
// focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
// @Override
// public String outputFile(TableInfo tableInfo) {
// return "/develop/code/xml/" + tableInfo.getEntityName() + ".xml";
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 关闭默认 xml 生成,调整生成 至 根目录
// TemplateConfig tc = new TemplateConfig();
// tc.setXml(null);
// mpg.setTemplate(tc);
// 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,
// 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称
// TemplateConfig tc = new TemplateConfig();
// tc.setController("...");
// tc.setEntity("...");
// tc.setMapper("...");
// tc.setXml("...");
// tc.setService("...");
// tc.setServiceImpl("...");
// 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
// mpg.setTemplate(tc);
// 执行生成
autoGenerator.execute();
// 打印注入设置【可无】
// System.err.println(mpg.getCfg().getMap().get("abc"));
}
}
注意指定的包名即可
生成的mapper要用注入spring 开启mapper扫描
@MapperScan("com.faraway.yy_commons.mybaties.bean.mapper")
测试
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
IUserService userService;
@GetMapping("/show")
private String testUser() {
Page<User> userPage = userService.selectPage(new Page<>(1, 10));
String s = JSONObject.toJSONString(userPage);
return s;
}
}
至此mybaties-plus 完成
我使用的是mysql8.0.11 所以url路径和mysql5.6版本有出入
使用druid连接池
druid介绍:
Druid是阿里开源的一个JDBC应用组件, 其包括三部分:
DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系。 DruidDataSource 高效可管理的数据库连接池。 SQLParser SQL语法分析 通过Druid连接池中间件, 我们可以实现:
可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。 替换传统的DBCP和C3P0连接池中间件。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。 SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC层的扩展插件。
关于Druid的更多详细信息可以参考Druid官方文档 link
导入依赖:
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
druid-spring-boot-starter对druid配置文件做了一些封装
配置文件
#数据源
spring:
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${dbIp}:${dbPort}/${dbName}?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: ${dbUser}
password: ${dbPwd}
# 配置监控统计拦截的filter , 去掉后监控sql无法统计wall用于防火墙
filters: stat,wall,log4j,config
# 最大连接数
max-active: 100
# 初始化大小
initial-size: 1
# 获取连接等待超时时间
max-wait: 60000
# 最小连接数
min-idle: 1
# 间隔多久检测一次 检测需要关闭的空闲连接 单位毫秒
time-between-eviction-runs-millis: 60000
# 一个连接最小生存时间
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
Druid提供以下几种Filter信息:
default com.alibaba.druid.filter.stat.StatFilter
stat com.alibaba.druid.filter.stat.StatFilter
mergeStat com.alibaba.druid.filter.stat.MergeStatFilter
encoding com.alibaba.druid.filter.encoding.EncodingConvertFilter
log4j com.alibaba.druid.filter.logging.Log4jFilter
log4j2 com.alibaba.druid.filter.logging.Log4j2Filter
slf4j com.alibaba.druid.filter.logging.Slf4jLogFilter
commonlogging com.alibaba.druid.filter.logging.CommonsLogFilter
wall com.alibaba.druid.wall.WallFilter
druid配置信息
通过Druid-Spring-Boot-Starter可以自动完成相关的配置, 而无须自定义配置文件, 具体参考
在此, 主要通过定制的配置文件对Druid进行自定义属性配置,项目中无需加入
配置文件如下:
package com.faraway.yy_commons.utils;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* druid配置文件
*
* @author yuanyao@wistronits.com
* create on 2018/7/20 上午10:42
*/
@Data
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class DruidDataSourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
private int initialSize;
private int minIdle;
private int maxActive = 100;
private long maxWait;
private long timeBetweenEvictionRunsMillis;
private long minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String filters;
}
配置相关的servlett和filter
监控视图
package com.faraway.yy_commons.utils;
import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
/**
* druid监控视图
*
* @author yuanyao@wistronits.com
* create on 2018/7/20 上午10:47
*/
@WebServlet(
urlPatterns = "/druid/*",
initParams= {
@WebInitParam(name = "allow", value = "localhost"),// IP白名单 (没有配置或者为空,则允许所有访问)
// @WebInitParam(name = "deny", value = "192.168.6.73"),// IP黑名单 (存在共同时,deny优先于allow)
@WebInitParam(name = "loginUsername", value = "admin"),// 用户名
@WebInitParam(name = "loginPassword", value = "admin"),// 密码
@WebInitParam(name = "resetEnable", value = "true")// 禁用HTML页面上的“Reset All”功能
}
)
public class DruidStatViewServlet extends StatViewServlet {
private static final long serialVersionUID = 7359758657306626394L;
}
监控拦截器
package com.faraway.yy_commons.utils;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
/**
* druid监控拦截器
*
* @author yuanyao@wistronits.com
* create on 2018/7/20 上午10:42
*/
@WebFilter(
filterName = "druidWebStatFilter",
urlPatterns = "/*",
initParams = {
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"),// 忽略资源
}
)
public class DruidStatFilter {
}
网上大多使用配置类的方式配置,在此也贴出,但是无需使用:
package com.garyond.hurricane.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
@EnableConfigurationProperties({DruidDataSourceProperties.class})
public class DruidConfig {
@Autowired
private DruidDataSourceProperties properties;
@Bean
@ConditionalOnMissingBean
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(properties.getDriverClassName());
druidDataSource.setUrl(properties.getUrl());
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setInitialSize(properties.getInitialSize());
druidDataSource.setMinIdle(properties.getMinIdle());
druidDataSource.setMaxActive(properties.getMaxActive());
druidDataSource.setMaxWait(properties.getMaxWait());
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
druidDataSource.setValidationQuery(properties.getValidationQuery());
druidDataSource.setTestWhileIdle(properties.isTestWhileIdle());
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(properties.getMaxPoolPreparedStatementPerConnectionSize());
try {
druidDataSource.setFilters(properties.getFilters());
druidDataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
/**
* 注册Servlet信息, 配置监控视图
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
//白名单:
servletRegistrationBean.addInitParameter("allow","192.168.6.195");
//IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.
servletRegistrationBean.addInitParameter("deny","192.168.6.73");
//登录查看信息的账号密码, 用于登录Druid监控后台
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "admin");
//是否能够重置数据.
servletRegistrationBean.addInitParameter("resetEnable", "true");
return servletRegistrationBean;
}
/**
* 注册Filter信息, 监控拦截器
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
查看监控
配置完成后, 并完成相关的数据库操作配置, 启动Spring Boot应用程序,就可以通过访问: http://localhost:8888/druid/index.html 访问Druid监控后台页面。
至此配置完毕
多数据源
springboot默认加载配置文件里的配置,配置规则已经定义为单数据源,想要配置多数据源必须禁用默认加载,
多数据源的思路如下:
配置文件里配置多数据源配置信息
创建配置类读取配置文件创建不同的DataSource
使用数据源的时候根据业务不同用aop切换数据源
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
在启动类添加此注解
配置文件:
#数据源
spring:
datasource:
one:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${dbIp}:${dbPort}/${dbName}?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: ${dbUser}
password: ${dbPwd}
two:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${dbIp}:${dbPort}/yy_user?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: ${dbUser}
password: ${dbPwd}
druid:
# 配置监控统计拦截的filter , 去掉后监控sql无法统计wall用于防火墙
filters: stat,wall,log4j,config
# 最大连接数
max-active: 100
# 初始化大小
initial-size: 1
# 获取连接等待超时时间
max-wait: 60000
# 最小连接数
min-idle: 1
# 间隔多久检测一次 检测需要关闭的空闲连接 单位毫秒
time-between-eviction-runs-millis: 60000
# 一个连接最小生存时间
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
数据源配置类:
package com.faraway.yy_commons.dataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
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.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 多数据源配置类
*
* @author yuanyao@wistronits.com
* create on 2018/7/23 上午10:00
*/
@Configuration
public class DataSourceConfig {
@Bean(name = "one")
@ConfigurationProperties(prefix = "spring.datasource.one") // application.properteis中对应属性的前缀
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "two")
@ConfigurationProperties(prefix = "spring.datasource.two") // application.properteis中对应属性的前缀
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
/**
* 动态数据源:通过aop在不同的数据源中切换
*
* @return
*/
@Primary
@Bean(name = "DynamicDataSource")
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 默认数据源
dynamicDataSource.setDefaultTargetDataSource(dataSource1());
// 配置多数据源
Map<Object, Object> map = new HashMap<>();
map.put("one", dataSource1());
map.put("two", dataSource2());
dynamicDataSource.setTargetDataSources(map);
return dynamicDataSource;
}
/**
* 配置@Transactional注解事物
*
* @return
*/
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
}
}
数据源切换
package com.faraway.yy_commons.dataSource;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* 保存切换数据源
*
* @author yuanyao@wistronits.com
* create on 2018/7/23 上午10:52
*/
@Slf4j
public class DataSourceContextHolder {
/** 默认数据源 */
public static final String DEFAULT_DS = "one";
/**
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
*/
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<String>();
/**
* 管理所有的数据源id,用于数据源的判断
*/
public static List<String> datasourceId = new ArrayList<String>();
/**
* @Title: setDateSoureType
* @Description: 设置数据源的变量
* @param dbType
* @return void
*/
public static void setDB(String dbType){
log.info("获取数据源 , 数据源为::" + dbType);
CONTEXT_HOLDER.set(dbType);
}
/**
* @Title: getDateSoureType
* @Description: 获得数据源的变量
* @return String
*/
public static String getDBType(){
return CONTEXT_HOLDER.get();
}
/**
* @Title: clearDateSoureType
* @Description: 清空所有的数据源变量
* @return void
*/
public static void clearDBType(){
CONTEXT_HOLDER.remove();
}
/**
* @Title: existDateSoure
* @Description: 判断数据源是否已存在
* @param dbType
* @return boolean
*/
public static boolean existDateSoure(String dbType ){
return datasourceId.contains(dbType);
}
}
当前数据源
package com.faraway.yy_commons.dataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.util.StringUtils;
/**
* 当前数据源
*
* @author yuanyao@wistronits.com
* create on 2018/7/23 上午11:00
*/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String dbType = DataSourceContextHolder.getDBType();
if (StringUtils.isEmpty(dbType)) {
DataSourceContextHolder.setDB("one");
}
log.info("当前数据源为: " + DataSourceContextHolder.getDBType());
return DataSourceContextHolder.getDBType();
}
}
数据源切换所用注解:
package com.faraway.yy_commons.dataSource;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author yuanyao@wistronits.com
* create on 2018/7/23 上午11:08
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DS {
String value() default "one";
}
切面:
package com.faraway.yy_commons.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.springframework.stereotype.Component;
/**
* 数据源动态切换
*
* @author yuanyao@wistronits.com
* create on 2018/7/23 上午11:10
*/
@Slf4j
@Aspect
@Component
public class DynamicDataSourceAspect {
@Before("@annotation(ds)")
public void beforeSwitchDS(JoinPoint point,DS ds) {
try {
log.info("检测到AOP切面,切换数据源,切换为 , " + ds.value());
String value = ds.value();
DataSourceContextHolder.setDB(value);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
//
@After("@annotation(com.faraway.yy_commons.dataSource.DS)")
public void afterSwitchDS(JoinPoint point) {
log.info("数据源切换完毕,清除相关信息");
DataSourceContextHolder.clearDBType();
}
}
测试:在service中使用
package com.faraway.yy_commons.mybaties.bean.service.impl;
import com.faraway.yy_commons.mybaties.bean.entity.Sys_user;
import com.faraway.yy_commons.mybaties.bean.mapper.Sys_userMapper;
import com.faraway.yy_commons.mybaties.bean.service.ISys_userService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.faraway.yy_commons.dataSource.DS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author yuanyao@wistronits.com
* @since 2018-07-23
*/
@Service
public class Sys_userServiceImpl extends ServiceImpl<Sys_userMapper, Sys_user> implements ISys_userService {
@Autowired
Sys_userMapper userMapper;
@DS("two")
@Override
public List<Sys_user> selectAll() {
List<Sys_user> sys_users = userMapper.selectList(null);
return sys_users;
}
}
数据源切换成功
到 druid 监控页面发现页面提示如下:
(*) property for user to setup
是因为上面构建的数据源并没有使用druid,
所以修改数据源配置类:
package com.faraway.yy_commons.dataSource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
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.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 多数据源配置类
*
* @author yuanyao@wistronits.com
* create on 2018/7/23 上午10:00
*/
@Configuration
public class DataSourceConfig {
@Bean(name = "one")
@ConfigurationProperties(prefix = "spring.datasource.one") // application.properteis中对应属性的前缀
public DataSource dataSource1() {
DruidDataSource build = DruidDataSourceBuilder.create().build();
// return DataSourceBuilder.create().build();
return build;
}
@Bean(name = "two")
@ConfigurationProperties(prefix = "spring.datasource.two") // application.properteis中对应属性的前缀
public DataSource dataSource2() {
DruidDataSource build = DruidDataSourceBuilder.create().build();
// return DataSourceBuilder.create().build();
return build;
}
/**
* 动态数据源:通过aop在不同的数据源中切换
*
* @return
*/
@Primary
@Bean(name = "DynamicDataSource")
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 默认数据源
dynamicDataSource.setDefaultTargetDataSource(dataSource1());
// 配置多数据源
Map<Object, Object> map = new HashMap<>();
map.put("one", dataSource1());
map.put("two", dataSource2());
dynamicDataSource.setTargetDataSources(map);
return dynamicDataSource;
}
/**
* 配置@Transactional注解事物
*
* @return
*/
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
}
}
执行测试代码, 页面成功显示两个数据源.
对于多数据源 , druid配置继承问题暂不研究