0 0

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

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

</beans>

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

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){
	}
}

问题补充:我这个项目是axis2的webservice项目,下面是我的axis2的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<serviceGroup>
<service name="PAPWebService" scope="transportsession">
<Description>Please Type your service description here</Description>

<!-- messageReceivers是配置方法的返回值的,如果无返回值会取RPCInOnlyMessageReceiver,否则取RPCMessageReceiver -->
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
<!-- end -->

<!-- ServiceObjectSupplier是整合spring的必要配置 -->
<parameter name="ServiceObjectSupplier">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
<!-- end -->

<!-- applicationContext.xml中配置的实现类名称 -->
<parameter name="SpringBeanName">PAPWebService</parameter>
<!-- end -->

<!-- 实现类的接口 -->
<parameter name="ServiceClass" locked="false">com.pap.ws.PAPWebService</parameter>
<!-- end -->
</service>
</serviceGroup>

问题补充:经过我的测试发现,如果不涉及到AXIS2,那么数据源切换是没有问题的,但是加上AXIS2就会切换不过去,不知道是jar包冲突还是其他什么问题
2014年2月17日 20:44

4个答案 按时间排序 按投票排序

1 0

spring里面怎么配置了?如果两个库完全一致,最省事的方式还是在spring里面配置两个datasource,2个hibernatetemplate分别注入相应的datasource,把hibernatetemplate注入service,需要哪个库的时候调用哪个hibernatetemplate

2014年2月18日 10:30
0 0

如果把

 @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;  
    }  

改为
 @Override  
    public List<ClinicForRegist> queryClinicForRegist(java.sql.Date clinicDate, Object[] timeDesc, int firstResult, int maxResults) throws Exception {  
        DataSourceContextHolder.setDataSourceType("hisDataSource");  
        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;  
    }  

试试呢?看看是不是因为key获取不到对应的Datasource

2014年2月19日 18:06
0 0

proxool配置多数据源必须为每一个数据源bean配置属性alias,也就是取个别名,当然每个datasourse别名是不同的,那么该问题中的配置可为:
tmsDataSource
<property name="alias" value="proxool.tms" />
hisDataSource
<property name="alias" value="proxool.his" />

2014年2月19日 13:42
0 0

你可以调试看下每次这个方法是否是你自己设置的数据库名称
public static String getDataSourceType() { 
        return contextHolder.get(); 
   }

2014年2月18日 11:09

相关推荐

    spring3+springmvc+jpa+hibernate多数据源

    "spring3+springmvc+jpa+hibernate多数据源"是一个示例项目,它演示了如何在一个应用中集成Spring 3、Spring MVC、JPA 2.0以及Hibernate,以实现对多个数据源的支持。下面将详细介绍这些技术及其集成的关键点。 **...

    spring+hibernate解决多数据源问题3.pdf

    本文主要介绍在Spring与Hibernate框架下解决多数据源配置的问题。在企业级应用开发中,因为业务需求的不同,往往需要同时操作多个数据库,这就需要配置多数据源来满足这样的需求。 知识点一:数据源与会话工厂 在...

    Spring+Hibernate多数据源

    接着,描述中的"Spring+Hibernate多数据源的整合实现demo"意味着这是一个实际操作的示例,它可能包含了一个或多个配置文件和Java代码,展示了如何在Spring Boot或者传统的Spring环境下配置和使用多数据源。在Spring ...

    springmvc+spring+hibernate

    3. **配置Spring**:在src/main/resources下创建applicationContext.xml文件,配置Spring的核心容器,包括Bean定义、数据源、事务管理器等。例如,使用DataSource来连接Oracle数据库,使用...

    jsp+Spring+hibernate 博客系统

    通过结合JSP的视图呈现、Spring的控制层管理和Hibernate的数据持久化,开发者能够快速、高效地开发出具有复杂业务逻辑的博客平台。如果你希望深入了解这个系统的实现细节,需要深入研究源代码和配置文件,理解它们...

    gwt+spring+hibernate

    - **Hibernate配置**: 配置Hibernate实体类,映射到数据库表,并设置数据源、SessionFactory等。 - **MyEclipse集成**: MyEclipse是一款强大的Java EE集成开发环境,支持GWT插件,使得开发者可以直接在IDE中调试和...

    idea工具创建的Spring+SpringMVC+Hibernate+maven项目

    - `src/main/java`:存放Java源代码的地方,通常会看到Spring配置类、服务层接口和实现、DAO层接口和实现等。 - `src/main/resources`:存放配置文件的地方,比如Spring的XML配置、Hibernate的实体映射文件(hbm.xml...

    flex+Spring+Hibernate整合配置详解

    右键点击项目,选择"MyEclipse" -&gt; "Add Spring Capabilities",然后选择所需的Spring库,注意处理与Hibernate的jar包冲突问题,可能需要删除冲突的jar,例如"asm-2.2.3.jar"。推荐将所有依赖的jar包复制到`webRoot/...

    Spring+hibernate整合源代码

    你需要在 Spring 配置文件中定义数据源 Bean,如使用 DriverManagerDataSource 或者 DataSourceProxy,提供连接数据库所需的 JDBC 配置信息。 4. **SessionFactory 创建**:使用 Spring 的 LocalSessionFactoryBean...

    spring+hibernate+atomikos多数据源

    在多数据源环境中,Hibernate可以通过SessionFactory配置多个数据源,每个数据源对应一个SessionFactory。 3. **Atomikos**: Atomikos是一个开源的JTA(Java Transaction API)实现,提供分布式事务管理服务。在...

    图书管理系统spring+struts+hibernate

    《图书管理系统spring+struts+hibernate》是一款基于Java技术栈开发的图书管理软件,其核心框架包括Spring、Struts和Hibernate。该系统利用MySQL作为数据库存储数据,提供了完整的数据库备份,确保了数据的安全性与...

    spring mvc + spring + hibernate 全注解整合开发视频教程 04

    Spring还提供了数据源配置、事务配置以及对Hibernate SessionFactory的管理,通过`@EnableTransactionManagement`开启事务管理。 在实际开发中,我们还会用到Spring的其他功能,比如Spring MVC的拦截器...

    用Maven搭建Spring+Spring MVC+Hibernate框架

    在IT行业中,构建大型、模块化的Java应用时,通常会采用一些成熟的框架组合,例如Spring、Spring MVC和Hibernate。这些框架协同工作,可以提供强大的后端功能,包括依赖注入、模型-视图-控制器(MVC)架构以及对象...

    spring3+hibernate4+maven+junit 多库多数据源实现

    "Spring3+Hibernate4+Maven+JUnit 多库多数据源实现"是一个典型的Java Web项目配置,它涉及了多个核心技术来处理复杂的数据管理需求。下面将详细阐述这些技术以及如何协同工作以实现多库多数据源。 首先,Spring...

    struts+spring+hibernate实现图书修改和删除

    在本项目中,Hibernate被用来执行图书数据的CRUD(创建、读取、更新、删除)操作,通过配置文件定义实体类与数据库表的映射,然后通过SessionFactory和Session对象进行数据交互。 **整合SSH** SSH整合的关键在于...

    strut+spring+hibernate注册登录系统

    Struts、Spring和Hibernate是Java开发中的三大主流框架,它们的整合使用在企业级应用开发中非常常见。这个"Strut+Spring+Hibernate注册登录系统"是一个基础的Web应用程序,旨在帮助初学者理解如何将这三个框架集成并...

    seam+spring+hibernate+richfaces配置

    2. **配置Seam**:在seam.properties文件中指定Hibernate配置,如数据源、实体扫描路径等。 3. **配置Spring**:创建Spring的bean配置文件,定义需要的bean,如DataSource、SessionFactory、TransactionManager等,...

    struts+spring+hibernate三大框架整合

    Spring管理SessionFactory,通常在ApplicationContext.xml中配置,通过`&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"&gt;`指定数据源、映射文件、hibernate配置等。...

    Spring+hibernate+struts2整合配置详解

    - 创建Hibernate配置文件`hibernate.cfg.xml`,定义数据源、实体类映射等信息。 - 配置Spring以管理SessionFactory,使用`LocalSessionFactoryBean`,并将其bean注入到需要使用SessionFactory的地方。 5. **整合...

    ssh(struts+spring+hibernate)教务管理信息系统(全部代码) 可以直接运行

    它还能与Hibernate进行无缝集成,简化数据访问层的配置。此外,Spring MVC是Spring的一部分,可以替代Struts作为前端控制器,提供更灵活的架构。 **Hibernate框架**: Hibernate是一个对象关系映射(ORM)工具,它...

Global site tag (gtag.js) - Google Analytics