技术框架式springmvc + mybatis
一:路由主从库数据源实现(核心代码)
public class MasterSlaveRoutingDataSource extends AbstractRoutingDataSource { private static AtomicInteger counter = new AtomicInteger(0); private String[] readDataSourceKeys; @Override protected Object determineCurrentLookupKey() { counter.incrementAndGet(); String dataSourceKey = DataSourceContextHolder.WRITE; String type = DataSourceContextHolder.getDbType(); if(null != type && DataSourceContextHolder.READ.equals(type)) dataSourceKey = type; return dataSourceKey; /* if(DataSourceContextHolder.READ.equals(type)){ dataSourceKey = randomReadDataSourceKey(); } return dataSourceKey;*/ } public String randomReadDataSourceKey(){ if(readDataSourceKeys == null|| readDataSourceKeys.length == 0){ throw new RuntimeException("readDataSourceKeys is empty"); } return readDataSourceKeys[(int)(Math.random() * readDataSourceKeys.length)]; } public String[] getReadDataSourceKeys() { return readDataSourceKeys; } public void setReadDataSourceKeys(String[] readDataSourceKeys) { this.readDataSourceKeys = readDataSourceKeys; } }
二:选择主从数据源实现
public class DataSourceContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal (); public static final String READ = "READ"; public static final String WRITE = "WRITE"; public static void setCustomerType(String type) { //contextHolder.remove(); if(getDbType() == null){ contextHolder.set(type); } } /** * @param type */ public static void directSetCustomerType(String type) { contextHolder.remove(); contextHolder.set(type); } public static String getDbType() { return contextHolder.get(); } public static void clearType() { contextHolder.remove(); } }
三:在哪里选择数据源--切面实现(service层)
public class ReadWriteAspect { /** * @return * @throws Throwable */ public void selectReadWriteDataSource(final JoinPoint point) throws Throwable { DataSourceContextHolder.directSetCustomerType(DataSourceContextHolder.WRITE); if(null != point && null != point.getSignature() && null != point.getSignature().getName()){ String methodName = point.getSignature().getName(); String reg = "^get|^find|^select|^parse|^check"; Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(methodName); if(matcher.find()) DataSourceContextHolder.directSetCustomerType(DataSourceContextHolder.READ); } } /** * @throws Throwable */ public void clearReadWriteDataSource() throws Throwable { DataSourceContextHolder.clearType(); } }四:事物和选择数据源的顺序 实现 (service层)