日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Boot 集成 Mybatis 实现双数据源

發(fā)布時(shí)間:2023/12/3 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot 集成 Mybatis 实现双数据源 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自? ?Spring Boot 集成 Mybatis 實(shí)現(xiàn)雙數(shù)據(jù)源

這里用到了Spring Boot + Mybatis + DynamicDataSource配置動(dòng)態(tài)雙數(shù)據(jù)源,可以動(dòng)態(tài)切換數(shù)據(jù)源實(shí)現(xiàn)數(shù)據(jù)庫的讀寫分離。

添加依賴

加入Mybatis啟動(dòng)器,這里添加了Druid連接池、Oracle數(shù)據(jù)庫驅(qū)動(dòng)為例。

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId> </dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId> </dependency><dependency><groupId>com.oracle</groupId><artifactId>ojdbc6</artifactId> </dependency>

添加啟動(dòng)類

@EnableMybatis @EnableTransactionManagement @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) public class Application {public static void main(String[] args) {SpringApplication.run(ServiceApplication.class, args);}} @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }):這里用到了雙數(shù)據(jù)源,需要排除數(shù)據(jù)源的自動(dòng)配置,如果只有一個(gè)數(shù)據(jù)源用Spring Boot的自動(dòng)配置就行。

@EnableTransactionManagement:開啟事務(wù)支持。

@EnableMybatis:開啟Mybatis功能

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(MybatisConfig.class) public @interface EnableMybatis {}

Mybatis配置類

@Configuration @MapperScan(basePackages = DSConfig.BASE_PACKAGES) public class MybatisConfig implements DSConfig {@Primary@Beanpublic DynamicDataSource dynamicDataSource(@Qualifier(DB_MASTER) DataSource master,@Qualifier(DB_SLAVE) DataSource slave) {Map<Object, Object> dsMap = new HashMap<>();dsMap.put(DB_MASTER, master);dsMap.put(DB_MASTER, slave);DynamicDataSource dynamicDataSource = new DynamicDataSource();dynamicDataSource.setDefaultTargetDataSource(master);dynamicDataSource.setTargetDataSources(dsMap);return dynamicDataSource;}@Beanpublic PlatformTransactionManager transactionManager(DynamicDataSource dynamicDataSource) {return new DataSourceTransactionManager(dynamicDataSource);}@Beanpublic SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource)throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dynamicDataSource);sessionFactory.setMapperLocations(((ResourcePatternResolver) new PathMatchingResourcePatternResolver()).getResources(DSConfig.MAPPER_LOCATIONS));return sessionFactory.getObject();}}

DSConfig常量類:

public interface DSConfig {String DS_PREFIX = "spring.datasource";String DS_ACTIVE = "active";String DB_MASTER = "db-master";String DB_SLAVE = "db-slave";String DRUID = "druid";String DRUID_MONITOR_USERNAME = "spring.druid.username";String DRUID_MONITOR_PASSWORD = "spring.druid.password";String DRUID_MONITOR_URL = "/druid/*";String DRUID_FILTER_EXCLUSIONS = "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*";String DRUID_FILTER_URL = "/*";String BASE_PACKAGES = "com.example.**.mapper";String MAPPER_LOCATIONS = "mapper/**/*.xml";}

連接池配置類

Druid連接池的自動(dòng)配置類:

@Configuration @Import({ PropertiesConfig.class }) @ConditionalOnClass(DruidDataSource.class) @ConditionalOnProperty(prefix = DSConfig.DS_PREFIX, value = DSConfig.DS_ACTIVE, havingValue = DSConfig.DRUID) public class DruidAutoConfig implements DSConfig {private Logger logger = LoggerUtils.getLogger(this);@Bean(name = DB_MASTER, initMethod = "init", destroyMethod = "close")public DataSource dataSourceMaster(DruidMasterProperties masterProperties) throws SQLException {logger.debug("master properties: {}", masterProperties.toString());DruidDataSource dds = new DruidDataSource();dds.setDriverClassName(masterProperties.getDriverClassName());dds.setUrl(masterProperties.getUrl());dds.setUsername(masterProperties.getUsername());dds.setPassword(masterProperties.getPassword());dds.setInitialSize(masterProperties.getInitialSize());dds.setMinIdle(masterProperties.getMinIdle());dds.setMaxActive(masterProperties.getMaxActive());dds.setMaxWait(masterProperties.getMaxWait());dds.setTimeBetweenEvictionRunsMillis(masterProperties.getTimeBetweenEvictionRunsMillis());dds.setMinEvictableIdleTimeMillis(masterProperties.getMinEvictableIdleTimeMillis());dds.setValidationQuery(masterProperties.getValidationQuery());dds.setTestOnBorrow(masterProperties.isTestOnBorrow());dds.setTestWhileIdle(masterProperties.isTestWhileIdle());dds.setTestOnReturn(masterProperties.isTestOnReturn());dds.setPoolPreparedStatements(masterProperties.isPoolPreparedStatements());dds.setMaxPoolPreparedStatementPerConnectionSize(masterProperties.getMaxPoolPreparedStatementPerConnectionSize());dds.setFilters(masterProperties.getFilters());return dds;}@Bean(name = DB_SLAVE, initMethod = "init", destroyMethod = "close")public DataSource dataSourceSlave(DruidSlaveProperties slaveProperties) throws SQLException {logger.debug("slave properties: {}", slaveProperties.toString());DruidDataSource dds = new DruidDataSource();dds.setDriverClassName(slaveProperties.getDriverClassName());dds.setUrl(slaveProperties.getUrl());dds.setUsername(slaveProperties.getUsername());dds.setPassword(slaveProperties.getPassword());dds.setInitialSize(slaveProperties.getInitialSize());dds.setMinIdle(slaveProperties.getMinIdle());dds.setMaxActive(slaveProperties.getMaxActive());dds.setMaxWait(slaveProperties.getMaxWait());dds.setTimeBetweenEvictionRunsMillis(slaveProperties.getTimeBetweenEvictionRunsMillis());dds.setMinEvictableIdleTimeMillis(slaveProperties.getMinEvictableIdleTimeMillis());dds.setValidationQuery(slaveProperties.getValidationQuery());dds.setTestOnBorrow(slaveProperties.isTestOnBorrow());dds.setTestWhileIdle(slaveProperties.isTestWhileIdle());dds.setTestOnReturn(slaveProperties.isTestOnReturn());dds.setPoolPreparedStatements(slaveProperties.isPoolPreparedStatements());dds.setMaxPoolPreparedStatementPerConnectionSize(slaveProperties.getMaxPoolPreparedStatementPerConnectionSize());dds.setFilters(slaveProperties.getFilters());return dds;}@Beanpublic ServletRegistrationBean druidServletRegistrationBean(EnvConfig env) {String username = env.getStringValue(DSConfig.DRUID_MONITOR_USERNAME);String password = env.getStringValue(DSConfig.DRUID_MONITOR_PASSWORD);return new ServletRegistrationBean(new DruidStatViewServlet(username, password),DSConfig.DRUID_MONITOR_URL);}@Beanpublic FilterRegistrationBean druidFilterRegistrationBean() {WebStatFilter wsf = new WebStatFilter();FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(wsf);filterRegistrationBean.setUrlPatterns(Arrays.asList(DSConfig.DRUID_FILTER_URL));filterRegistrationBean.setInitParameters(Collections.singletonMap("exclusions", DSConfig.DRUID_FILTER_EXCLUSIONS));return filterRegistrationBean;}}

根據(jù)類路徑下有DruidDataSource這個(gè)類即有Druid這個(gè)jar包和配置文件中spring.datasource.active=druid才開啟對Druid連接池的自動(dòng)配置。

導(dǎo)入的配置文件:

@Configuration @ComponentScan(basePackages = "com.example.common.config.properties") public class PropertiesConfig {}

DruidMasterProperties、DruidSlaveProperties屬性文件讀取的配置省略。

連接池監(jiān)控配置類:

public class DruidStatViewServlet extends StatViewServlet {private static final long serialVersionUID = 1L;private String username;private String password;@Overridepublic String getInitParameter(String name) {if ("loginUsername".equals(name)) {return username;}if ("loginPassword".equals(name)) {return password;}return super.getInitParameter(name);}public DruidStatViewServlet(String username, String password) {super();this.username = username;this.password = password;}public String getUsername() {return username;}public String getPassword() {return password;}}

在META-INF/spring.factories中加入Druid自動(dòng)配置映射:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.common.config.ds.DruidAutoConfig


切換數(shù)據(jù)源

切換數(shù)據(jù)源注解:

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DS {String value() default DSConfig.DB_MASTER; }

動(dòng)態(tài)數(shù)據(jù)源類:

public class DynamicDataSource extends AbstractRoutingDataSource {private final Logger logger = LoggerUtils.getLogger(this);@Overrideprotected Object determineCurrentLookupKey() {logger.debug("當(dāng)前數(shù)據(jù)源為{}", DataSourceContextHolder.getDS());return DataSourceContextHolder.getDS();}}

動(dòng)態(tài)數(shù)據(jù)源AOP實(shí)現(xiàn)類:

@Aspect @Component public class DynamicDataSourceAspect {@Before("@annotation(DS)")public void beforeSwitchDS(JoinPoint point) {Class<?> className = point.getTarget().getClass();String methodName = point.getSignature().getName();Class<?>[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();String dataSource = DataSourceContextHolder.DEFAULT_DS;try {Method method = className.getMethod(methodName, argClass);if (method.isAnnotationPresent(DS.class)) {DS annotation = method.getAnnotation(DS.class);dataSource = annotation.value();}} catch (Exception e) {e.printStackTrace();}DataSourceContextHolder.setDS(dataSource);}@After("@annotation(DS)")public void afterSwitchDS(JoinPoint point) {DataSourceContextHolder.clearDS();}}

綁定當(dāng)前線程數(shù)據(jù)源類:

public class DataSourceContextHolder {public static final String DEFAULT_DS = DSConfig.DB_MASTER;private static final ThreadLocal<String> DS_HOLDER = new ThreadLocal<>();public static void setDS(String dbType) {DS_HOLDER.set(dbType);}public static String getDS() {return (DS_HOLDER.get());}public static void clearDS() {DS_HOLDER.remove();} }

總結(jié)

以上是生活随笔為你收集整理的Spring Boot 集成 Mybatis 实现双数据源的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。