技术框架式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层)