Home > Java > javaTutorial > body text

How to configure dynamic data sources in Spring to achieve separation of reading and writing

高洛峰
Release: 2017-01-24 10:53:59
Original
1631 people have browsed it

Preface

Recently, due to the needs of work, a project to be built needs to realize the separation of reading and writing of data sources. The code is shared here, and friends in need can refer to it and learn.

The first is to configure the data source

<!--读数据源配置-->
<bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"destroy-method="close">
//配置省略
</bean>
 
<!--写数据源配置-->
<bean id="writeDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"destroy-method="close">
//配置省略
</bean>
 
<!-- 动态数据源 -->
<bean id = "dataSource" class="com.potato.common.bean.DynamicDataSource" >
 <!-- 已配置的数据源 -->
 <property name="targetDataSources"> 
 <map>  
  <entry key="READ" value-ref="readDataSource"/>  
  <entry key="WRITE" value-ref="writeDataSource"/> 
 </map>
 </property>
 <!-- 默认的数据源 -->
 <property name="defaultTargetDataSource" ref="writeDataSource"/>
</bean>
Copy after login

How to switch the data source? Through the configuration of the dynamic data source, we know that switching is performed through key. Here we need to use org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource. We can write our own dynamic data source class DynamicDataSource to inherit it.

public class DynamicDataSource extends AbstractRoutingDataSource {
 @Override
 protected Object determineCurrentLookupKey() { 
  return DataSourceContextHolder.getType();
 }
}
Copy after login


You also need a place to store the key DataSourceContextHolder. To ensure thread safety during switching, we use ThreadLocal to save our key.

public class DataSourceContextHolder {
 private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceContextHolder.class);
 public static final String DATA_SOURCE_WRITE = "WRITE";
 public static final String DATA_SOURCE_READ = "READ";
 // 线程本地环境
 private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
 
 // 设置数据源类型
 public static void setType(String type) {
  if(LOGGER.isDebugEnabled())
   LOGGER.debug("==============切换数据源,类型:"+type+"================");
  contextHolder.set(type);
 }
 // 获取数据源类型
 public static String getType() {
  return (contextHolder.get());
 }
 // 清除数据源类型
 public static void clearType() {
  contextHolder.remove();
 }
}
Copy after login


Okay, we can dynamically switch data sources by operating DataSourceContextHolder. Friends may ask, do you have to manually select the data source type to switch every time you call a method? Of course not, Spring AOP comes on the scene.

@Component
@Aspect
public class DynamicDataSourceAspect {
 
 @Pointcut("execution (* com.potato.orm.mapper.*.select*(..)) || execution (* com.potato.orm.mapper.*.count*(..)) ")
 public void readMethodPointcut() {}
 
 @Pointcut("execution (* com.potato.orm.mapper.*.insert*(..)) || execution (* com.potato.orm.mapper.*.update*(..)) || execution (* com.potato.orm.mapper.*.delete*(..))")
 public void writeMethodPointcut() {}
 
 @Before("readMethodPointcut()")
 public void switchReadDataSource(){
  //System.out.println("============切换到读数据源===========");
  DataSourceContextHolder.setType(DataSourceContextHolder.DATA_SOURCE_READ);
 }
 
 @Before("writeMethodPointcut()")
 public void switchWriteDataSource(){
  //System.out.println("=============切换到写数据源==========");
  DataSourceContextHolder.setType(DataSourceContextHolder.DATA_SOURCE_WRITE);
 }
 
}
Copy after login

Summary

Okay, the above is the entire content of this article. When accessing Mapper (this project uses MyBatis , which is equivalent to the query method in DAO) will switch to the reading data source, and the add, delete, and modify methods will switch to the writing data source. I hope the content of this article can be of some help to everyone's study or work. If you have any questions, you can leave a message to communicate.

For more related articles on how Spring configures dynamic data sources to achieve read-write separation, please pay attention to the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!