SSM配置多資料來源
阿新 • • 發佈:2018-12-21
第一種方法:使用工具類
配置properties檔案
#-----------------oracle 第一個資料來源------------- datesources.driverClass=oracle.jdbc.driver.OracleDriver datesources.jdbcUrl=jdbc\:oracle\:thin\:@localhost\:1521\:orcl datesources.user=test datesources.password=test #-----------------oracle 第二個資料來源------------- datesources2.driverClass=oracle.jdbc.driver.OracleDriver datesources2.jdbcUrl=jdbc\:oracle\:thin\:@localhost\:1521\:orcl datesources2.user=tjsfjd datesources2.password=tjsfjd
配置applicationContext.xml檔案
<!--dbcp是apache的連結池--> <!--org.springframework.jdbc.datasource.DriverManagerDataSource使用傳統的jdbc連結方式--> <!--第一個資料來源--> <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${datesources.driverClass}"></property> <property name="url" value="${datesources.jdbcUrl}"></property> <property name="username" value="${datesources.user}"></property> <property name="password" value="${datesources.password}"></property> </bean> <!--第二個資料來源--> <bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${datesources2.driverClass}"></property> <property name="url" value="${datesources2.jdbcUrl}"></property> <property name="username" value="${datesources2.user}"></property> <property name="password" value="${datesources2.password}"></property> </bean> <!--com.my.ssmmaven.util.DataSources 為獲取獲取資料來源類--> <bean id="dataSource" class="com.my.ssmmaven.util.DataSources"> <property name="targetDataSources"> <map key-type="java.lang.String"> <!-- 指定lookupKey和與之對應的資料來源 --> <entry key="dataSource1" value-ref="dataSource1"></entry> <entry key="dataSource2" value-ref="dataSource2"></entry> </map> </property> <!-- 這裡可以指定預設的資料來源 --> <property name="defaultTargetDataSource" ref="dataSource1" /> </bean>
編碼工具類
1.DataSources
2.DynamicDataSourceHolder
package com.my.ssmmaven.util; /** * @author zhoujq * @version 1.0 * @description * @date 2018/7/12 19:55 * @modified */ public class DynamicDataSourceHolder { /** * 注意:資料來源標識儲存線上程變數中,避免多執行緒操作資料來源時互相干擾 */ private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>(); public static String getDataSource() { return THREAD_DATA_SOURCE.get(); } /** * 切換資料來源 * @param dataSource 資料來源 */ public static void setDataSource(String dataSource) { THREAD_DATA_SOURCE.set(dataSource); } public static void clearDataSource() { THREAD_DATA_SOURCE.remove(); } }
package com.my.ssmmaven.util;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @author zhoujq
* @version 1.0
* @description ssm配置多個數據源
* @date 2018/7/12 19:43
* @modified
*/
public class DataSources extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 從自定義的位置獲取資料來源標識
return DynamicDataSourceHolder.getDataSource();
}
}
service層呼叫
package com.my.ssmmaven.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.my.ssmmaven.mapper.IGetTestListMapper;
import com.my.ssmmaven.service.IGetTestListService;
import com.my.ssmmaven.util.DataSources.DataSourcesMenu;
import com.my.ssmmaven.util.DataSources.DynamicDataSourceHolder;
import com.my.ssmmaven.util.TurnPage;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author zhoujq
* @version 1.0
* @description
* @date 2018/7/6 10:52
* @modified
*/
@Service
public class GetTestListServerImpl implements IGetTestListService{
@Resource
IGetTestListMapper getTestListMapper;
/**
* 使用預設資料來源
* @param params
* @return
*/
@Override
public JSONObject getTestList(JSONObject params) {
JSONObject result = new JSONObject();
List<JSONObject> list= getTestListMapper.getTestList(params);
result.put("list",list);
return result;
}
/**
* 使用第二個資料來源
* @return
*/
@Override
public JSONObject getOrgList() {
DynamicDataSourceHolder.setDataSource(DataSourcesMenu.TJSFJD.getValue());
JSONObject result = new JSONObject();
List<JSONObject> list= getTestListMapper.getOrgList();
result.put("list",list.get(0));
return result;
}
}
第二種方法:使用註解
配置pom.xml,引入依賴
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
配置applicationContext.xml
1.配置資料來源 (省略)
2.配置註解攔截器,aop注入
<!--配置註解aop及攔截器 class 全類名 -->
<bean id="dataSourceAspect" class="com.my.ssmmaven.util.AnoDataSources.DataSourceAspect"/>
<aop:config>
<aop:aspect ref="dataSourceAspect">
<!-- 攔截所有service方法 -->
<aop:pointcut id="dataSourcePointcut" expression="execution(* com.my.ssmmaven.service.*.*(..))"/>
<aop:before pointcut-ref="dataSourcePointcut" method="intercept"/>
</aop:aspect>
</aop:config>
編寫工具類
1.DataSource
2.DataSourceAspect
package com.my.ssmmaven.util.AnoDataSources;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
public @interface DataSource {
String value();
}
package com.my.ssmmaven.util.AnoDataSources;
import com.my.ssmmaven.util.DataSources.DynamicDataSourceHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;
/**
* @author zhoujq
* @version .
* @description
* @date // :
* @modified
*/
public class DataSourceAspect {
/**
* 攔截目標方法,獲取由@DataSource指定的資料來源標識,設定到執行緒儲存中以便切換資料來源
*
* @param point
* @throws Exception
*/
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 預設使用目標型別的註解,如果沒有則使用其實現介面的註解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}
/**
* 提取目標物件方法註解和型別註解中的資料來源標識
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 預設使用型別註解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
// 方法註解可以覆蓋型別註解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
} catch (Exception e) {
System.out.println(clazz + ":" + e.getMessage());
}
}
}
service層呼叫,可在方法名或者類名上使用註解
package com.my.ssmmaven.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.my.ssmmaven.mapper.IGetTestListMapper;
import com.my.ssmmaven.service.IGetTestListService;
import com.my.ssmmaven.util.AnoDataSources.DataSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* @author zhoujq
* @version 1.0
* @description
* @date 2018/7/6 10:52
* @modified
*/
@Service
public class GetTestListServerImpl implements IGetTestListService{
@Resource
IGetTestListMapper getTestListMapper;
/**
* 使用預設資料來源
* @param params
* @return
*/
@Override
@Transactional
public JSONObject getTestList(JSONObject params) {
JSONObject result = new JSONObject();
List<JSONObject> list= getTestListMapper.getTestList(params);
result.put("list",list);
return result;
}
/**
* 使用第二個資料來源
* @return
*/
@Override
@DataSource("dataSource2")
public JSONObject getOrgList() {
JSONObject result = new JSONObject();
List<JSONObject> list= getTestListMapper.getOrgList();
result.put("list",list.get(0));
return result;
}
}