はじめに
最近、仕事の都合上、構築するプロジェクトでデータソースの読み書きを分離する必要があるので、ここでコードを共有します。必要な友人はそれを参照して学ぶことができます。
最初はデータソースを設定することです
<!--读数据源配置--> <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>
データソースを切り替えるにはどうすればよいですか?動的データ ソースの構成を通じて、キーを介して切り替えが実行されることがわかります。ここでは、独自の動的データ ソース クラス DynamicDataSource を作成して継承する必要があります。
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getType(); } }
キー DataSourceContextHolder を保存する場所も必要です。 切り替え中のスレッドの安全性を確保するために、ThreadLocal を使用してキーを保存します。
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(); } }
さて、DataSourceContextHolder を操作することでデータソースを動的に切り替えることができます。友人は、メソッドを呼び出すたびに切り替えるデータ ソースの種類を手動で選択する必要があるのかと尋ねるかもしれません。もちろんそうではありません。Spring AOP が登場します。
@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); } }
概要
さて、上記がこの記事の全内容です。Mapper (このプロジェクトでは DAO に相当する MyBatis を使用しています) でクエリ メソッドにアクセスすると、読み取りデータ ソースに切り替わります。追加、削除、および変更メソッドは、データ ソースの書き込みに切り替わります。この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。ご不明な点がございましたら、メッセージを残してご連絡ください。
読み取りと書き込みの分離を実現するために Spring で動的データ ソースを構成する方法に関するその他の記事については、PHP 中国語 Web サイトに注目してください。