2 coffee141 coffee141 于 2014.02.17 20:56 提问

关于spring+hibernate配置多数据源的问题

我的项目是个webservice项目,使用了hibernate+spring框架,由于项目中要用到两个数据库(都是oracle数据库),我在网上查了一些资料,但是在我的项目中做数据源切换的时候总是切换不过去,也就是说只能连接默认的数据源,一下是我的spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
default-autowire="byName">

<context:annotation-config />

<!-- AXIS2通过该对象加载spring中的bean 固定配置 -->
<bean id="applicationContext"
    class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
<!-- end -->

<!-- AXIS2本地业务配置 -->
<bean id="PAPWebService" class="com.pap.ws.PAPWebService" />
<!-- end -->

<context:component-scan base-package="com.pap">
    <context:include-filter type="regex" expression=".dao.impl.*" />
    <context:include-filter type="regex" expression=".serviec.impl.*" />
    <context:include-filter type="regex" expression=".entity.*" />
</context:component-scan>

<bean id="tmsDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
    <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
    <property name="driverUrl" value="jdbc:oracle:thin:@172.17.30.80:1521:tms" />
    <property name="user" value="SELFSERVICE" />
    <property name="password" value="Password123" />
    <!-- 最大数据库连接数 -->
    <property name="maximumConnectionCount" value="100" />
    <!-- 最小数据库连接数 -->
    <property name="minimumConnectionCount" value="3" />
    <!-- 最少保持的空闲连接数(默认2个) -->
    <property name="prototypeCount" value="3" />
    <!-- 没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受 -->
    <!-- <property name="maximumNewConnections" value="20"/> -->
    <!-- 最大的并发连接数 -->
    <property name="simultaneousBuildThrottle" value="50" />
    <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒 -->
    <property name="houseKeepingSleepTime" value="10000" />
    <!-- 用于保持连接的测试语句 -->
    <property name="houseKeepingTestSql" value="select sysdate from dual" />
    <!-- 在使用之前测试 -->
    <property name="testBeforeUse" value="true" />
</bean>

<bean id="hisDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
    <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
    <property name="driverUrl" value="jdbc:oracle:thin:@172.17.1.252:1521:ORCL" />
    <property name="user" value="system" />
    <property name="password" value="aaaaaa" />
    <!-- 最大数据库连接数 -->
    <property name="maximumConnectionCount" value="100" />
    <!-- 最小数据库连接数 -->
    <property name="minimumConnectionCount" value="3" />
    <!-- 最少保持的空闲连接数(默认2个) -->
    <property name="prototypeCount" value="3" />
    <!-- 没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受 -->
    <!-- <property name="maximumNewConnections" value="20"/> -->
    <!-- 最大的并发连接数 -->
    <property name="simultaneousBuildThrottle" value="50" />
    <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒 -->
    <property name="houseKeepingSleepTime" value="10000" />
    <!-- 用于保持连接的测试语句 -->
    <property name="houseKeepingTestSql" value="select sysdate from dual" />
    <!-- 在使用之前测试 -->
    <property name="testBeforeUse" value="true" />
</bean>

<bean id="dynamicDataSource" class="com.pap.datasource.DynamicDataSource">
    <!-- 通过key-value的形式来关联数据源 -->
    <property name="targetDataSources">
        <map key-type="java.lang.String">
            <entry value-ref="tmsDataSource" key="tmsDataSource"></entry>
            <entry value-ref="hisDataSource" key="hisDataSource"></entry>
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="tmsDataSource">
    </property>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dynamicDataSource" />
    <property name="packagesToScan">
        <list>
            <value>com.pap.entity</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />


下面是我写的两个用于切换数据源的类:

DataSourceContextHolder.java
package com.pap.datasource;

public class DataSourceContextHolder {
public static final String DATA_SOURCE_TMS = "tmsDataSource";

public static final String DATA_SOURCE_HIS = "hisDataSource";

private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

public static void setDataSourceType(String customerType) {
    contextHolder.set(customerType);
}

public static String getDataSourceType() {
    return contextHolder.get();
}

public static void clearDataSourceType() {
    contextHolder.remove();
}

}

DynamicDataSource.java
package com.pap.datasource;

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

public class DynamicDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
    return DataSourceContextHolder.getDataSourceType();
}

}

dao层代码
package com.pap.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.pap.dao.BaseDao;

@Repository("baseDao")
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao{

@Override
public <T> Serializable save(T entity) throws Exception {
    Serializable s = this.getHibernateTemplate().save(entity);
    return s;
}

@Override
public <T> void update(T entity) throws Exception {
    this.getHibernateTemplate().update(entity);
}

@SuppressWarnings("unchecked")
@Override
public <T> List<T> query(String hql,Object[] values) throws Exception {
    return this.getHibernateTemplate().find(hql, values);
}

@Override
public <T> List<T> query(String hql, Object value) throws Exception {
    return query(hql, new Object[]{value});
}

@Override
public <T>T getEntity(Class<T> entityClass, Serializable id) throws Exception {
    return this.getHibernateTemplate().get(entityClass, id);
}

@SuppressWarnings("unchecked")
@Override
public <T> List<T> find(DetachedCriteria detachedCriteria, int firstResult, int maxResults) throws Exception {
    return getHibernateTemplate().findByCriteria(detachedCriteria, firstResult, maxResults);
}

@Override
@SuppressWarnings("unchecked")
public <T> List<T> find(DetachedCriteria criteria) throws Exception {
    return getHibernateTemplate().findByCriteria(criteria);
}

}

service层代码,我是在这里做的数据源切换
package com.pap.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.pap.dao.BaseDao;
import com.pap.datasource.DataSourceContextHolder;
import com.pap.entity.ChargeTypeDict;
import com.pap.entity.ClinicForRegist;
import com.pap.entity.MedicalCard;
import com.pap.entity.Patient;
import com.pap.entity.SelfTerminal;
import com.pap.entity.TransactionRecord;
import com.pap.entity.User;
import com.pap.service.BaseService;

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class BaseServiceImpl implements BaseService {
@Resource
private BaseDao baseDao;

/**
 * 查询排号信息
 */
@Override
public List<ClinicForRegist> queryClinicForRegist(java.sql.Date clinicDate, Object[] timeDesc, int firstResult, int maxResults) throws Exception {
    DataSourceContextHolder.setDataSourceType(DataSourceContextHolder.DATA_SOURCE_HIS);
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(ClinicForRegist.class);
    detachedCriteria.add(Restrictions.eq("clinicDate", clinicDate));
    detachedCriteria.add(Restrictions.in("timeDesc", timeDesc));
    List<ClinicForRegist> list = baseDao.find(detachedCriteria, firstResult, maxResults);
    DataSourceContextHolder.clearDataSourceType();
    return list;
}

}

webservice接口类
package com.pap.ws;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;

import com.pap.entity.ChargeTypeDict;
import com.pap.entity.ClinicForRegist;
import com.pap.entity.ClinicIndex;
import com.pap.entity.DeptDict;
import com.pap.entity.MedicalCard;
import com.pap.entity.Patient;
import com.pap.entity.Privileges;
import com.pap.entity.Response;
import com.pap.entity.SelfTerminal;
import com.pap.entity.TransactionRecord;
import com.pap.entity.User;
import com.pap.service.BaseService;
import com.pap.util.MD5Util;

public class PAPWebService {
@Resource
BaseService baseService;

/**
 * 查询可挂号信息
 * @param firstResult 起始条数
 * @param maxResults 最大条数
 * @return
 */
public Response queryClinicRegist(int firstResult, int maxResults) {
    Response response = new Response();
    try {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        String[] timeDesc = null;
        if (8 < hour && hour < 12) {
            timeDesc = new String[] { "白天", "上午", "下午", "昼夜" };
        } else if (hour > 11 && hour < 18) {
            timeDesc = new String[] { "白天", "下午", "昼夜" };
        } else {
            timeDesc = new String[] {"昼夜" };
        }
        List<ClinicForRegist> list = baseService.queryClinicForRegist(new java.sql.Date(calendar.getTimeInMillis()), timeDesc, firstResult, maxResults);
        if(list.size() > 0){
            response.setResult("S");
            response.setArrayData(list);
        }else{
            response.setResult("F");
            response.setResult("没有查询到记录");
        }

    } catch (Exception e) {
        e.printStackTrace();
        response.setResult("F");
        response.setErrorInfo(e.getMessage());
    }
    return response;
}

public void setClinicForRegist(ClinicForRegist clinicForRegist){
}

public void setClinicIndex(ClinicIndex clinicIndex){
}

public void setDeptDict(DeptDict deptDict){
}

}

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!