mybatis +spring 分库

<context:component-scan base-package="com.snailteam.crawler"	scoped-proxy="targetClass" />
	<bean id="crawlerDataSource1" parent="parentDataSource">
	
		<property name="driverClassName" value="${crawler.jdbc.driver}" />
		<property name="url" value="${crawler.jdbc.url}" />
		<property name="username" value="${crawler.jdbc.username}" />
		<property name="password" value="${crawler.jdbc.password}" />
		<property name="connectionProperties"
			value="autoReconnect=true;roundRobinLoadBalance=true" />
		<property name="interName" value="1" />	
			
	</bean>



	<bean id="crawlerDataSource2" parent="parentDataSource">
		<property name="driverClassName" value="${crawler.jdbc.driver}" />
		<property name="url" value="${crawler.jdbc.url}" />
		<property name="username" value="${crawler.jdbc.username}" />
		<property name="password" value="${crawler.jdbc.password}" />
		<property name="connectionProperties"
			value="autoReconnect=true;roundRobinLoadBalance=true" />
			<property name="interName" value="2" />	
	</bean>

	<bean id="crawlerDataSource3" parent="parentDataSource">
		<property name="driverClassName" value="${crawler.jdbc.driver}" />
		<property name="url" value="${crawler.jdbc.url}" />
		<property name="username" value="${crawler.jdbc.username}" />
		<property name="password" value="${crawler.jdbc.password}" />
		<property name="connectionProperties"
			value="autoReconnect=true;roundRobinLoadBalance=true" />
			<property name="interName" value="3" />	
	</bean>



	<bean id="dynamicDataSource" class="org.springframework.jdbc.datasource.DynamicDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry key="1" value-ref="crawlerDataSource1" />
				<entry key="2" value-ref="crawlerDataSource2" />
				<entry key="3" value-ref="crawlerDataSource3" />
			</map>
		</property>

		<property name="defaultTargetDataSource" ref="crawlerDataSource1"></property>
	</bean>



	<bean id="crawlerSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="configLocation" value="classpath:mybatis-configuration.xml" />
		<property name="dataSource" ref="dynamicDataSource" />
		<property name="plugins">
			<list>
				<bean class="com.snailteam.core.plugins.ShardDBRouterPlugin">
					<description>主辅数据库路由插件</description>
				</bean>
				<bean class="com.snailteam.core.plugins.TableRouterPlugin">
					<description>主辅数据库路由插件</description>
				</bean>
			</list>
		</property>
		<property name="typeAliasesPackage" value="com.snailteam.crawler.model" />
		<property name="transactionFactory">
			<bean
				class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
		</property>
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="sqlSessionFactoryBeanName" value="crawlerSessionFactory" />
		<property name="basePackage" value="com.snailteam.crawler.dao" />
		<property name="markerInterface" value="com.snailteam.core.base.BaseDAO" />
	</bean>

	<bean id="crawlerTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dynamicDataSource" />
	</bean>


 

 

package org.springframework.jdbc.datasource;

import java.util.Map;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.jdbc.datasource.support.DynamicDataSourceHolder;

/** 
 * @author xiaofancn@gmail.com
 * @version 创建时间:2015-4-30 上午9:54:49 
 * 类说明 
 */

public class DynamicDataSource extends AbstractRoutingDataSource {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override  
    public void setTargetDataSources(Map targetDataSources) {  
        super.setTargetDataSources(targetDataSources);  
        super.afterPropertiesSet();
	}  
  
    @Override  
    protected Object determineCurrentLookupKey() {
    	System.out.println(DynamicDataSourceHolder.getDataSourceName());
        return DynamicDataSourceHolder.getDataSourceName();  
    }  

}


 

package org.springframework.jdbc.datasource.support;

/**
 * @author xiaofancn@gmail.com
 * @version 创建时间:2015-4-30 上午9:56:09 类说明
 */

public class DynamicDataSourceHolder {
	private static final ThreadLocal<String> holder = new ThreadLocal<String>();

	public static void putDataSourceName(String name) {
		holder.set(name);
	}

	public static String getDataSourceName() {
		return holder.get();
	}
}


 

 

package com.snailteam.core.plugins;

import java.lang.annotation.Annotation;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
import org.springframework.jdbc.datasource.support.DynamicDataSourceHolder;

import com.snailteam.core.annotation.Shard;
import com.snailteam.core.utils.ReflectUtils;

@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }), })
public class ShardDBRouterPlugin implements Interceptor {

	private static Logger logger = Logger.getLogger(ShardDBRouterPlugin.class);

	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
		invocation.getTarget();
//		ReflectUtils.getFieldValue(statement, "delegate");
		Object obj = invocation.getArgs()[1];
		BoundSql boundSql = mappedStatement.getBoundSql(obj);
		if(boundSql.getParameterObject()!=null){
			Object paramVal = obtainParam(boundSql.getParameterObject(), "side_id",mappedStatement.getConfiguration().isMapUnderscoreToCamelCase());
			int sideID = Integer.valueOf(paramVal.toString()).intValue();
			System.out.println((sideID%3)+"");
			DynamicDataSourceHolder.putDataSourceName((sideID%3)+"");
		}
		Object o = invocation.proceed();
		return o;
	}

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	public void setProperties(Properties properties) {
	}
	
	private Object obtainParam(Object params, String column,boolean isCamelCase){
		Object paramVal = null;
		if(params instanceof String || params instanceof Integer || params instanceof Byte || params instanceof Date){
			paramVal = params;
		}else if(params instanceof Map){
			paramVal = ((Map<String,Object>)params).get(camelCaseConvert(column));
		}else{
			boolean isShard = false;
			Annotation[] annotations = params.getClass().getDeclaredAnnotations();
			if(annotations!=null && annotations.length >0){
				for(Annotation annotation : annotations){
					if(annotation instanceof Shard){
						isShard = true;
						break;
					}
				}
			}
			if(isShard){
				paramVal = ReflectUtils.getFieldValue(params, camelCaseConvert(column));
			}
		}
		return paramVal;
	}
	public static String camelCaseConvert(String column){
		logger.debug("===============列-属性映射处理======================");
		String[] arr = column.split("_");
		if(arr.length == 1){ 
			return column;
		} else if(arr.length > 1) {
			StringBuilder sb = new StringBuilder();
			for(String s:arr){
				sb.append(s.substring(0,1).toUpperCase()).append(s.substring(1));
			}
			String prop = sb.toString();
			return prop.substring(0, 1).toLowerCase() + prop.substring(1);
		}else{
			return null;
		}
	}

}

 

 

 

 

你可能感兴趣的:(mybatis)