如何在应用启动之后灵活切换数据源的关键点:

  将SessionFactory接口中的dataSource配置为AbstractRoutingDataSource的instance,sessionFactory在获取datasource的时候会执行AbstractRoutingDataSource的determineCurrentLookupKey()方法,
所以用户要想定制自己切换数据源方式就要继承AbstractRoutingDataSource,然后实现determineCurrentLookupKey()方法。废话不多说,我们马上看例子:

1.简单映射类:User.java

 1 package com.eg.model;
2
3 import javax.persistence.Column;
4 import javax.persistence.Entity;
5 import javax.persistence.Id;
6 import javax.persistence.Table;
7
8 @Entity
9 @Table(name = "user")
10 public class User implements Cloneable{
11 private String user_id;
12 private String name;
13 private String age;
14
15 public User() {
16 }
17
18 @Id
19 @Column(name = "user_id", unique = true, nullable = false, length = 36)
20 public String getUser_id() {
21 return user_id;
22 }
23
24 public void setUser_id(String user_id) {
25 this.user_id = user_id;
26 }
27
28 @Column(name = "name", length = 20)
29 public String getName() {
30 return name;
31 }
32
33 public void setName(String name) {
34 this.name = name;
35 }
36
37 @Column(name = "age", length = 20)
38 public String getAge() {
39 return age;
40 }
41
42 public void setAge(String age) {
43 this.age = age;
44 }
45
46 }

2.DAO层: UserDao.java

 1 package com.eg.dao;
2
3 import org.springframework.stereotype.Repository;
4
5 import com.eg.model.User;
6
7 @Repository
8 public class UsertDao extends BaseHibernateDao<User> {
9
10 }

3.Dao层基类: BaseHibernateDao.java

 1 package com.eg.dao;
2
3
4 import org.apache.commons.logging.Log;
5 import org.apache.commons.logging.LogFactory;
6 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
7
8 import java.util.List;
9
10 public class BaseHibernateDao<T> extends HibernateDaoSupport
11 {
12 /**
13 * 操作的领域对象的类型
14 */
15 protected Class<T> entityClass;
16
17 protected Log log = (Log) LogFactory.getLog(this.getClass());
18
19
20 /**
21 * 执行HQL查询
22 */
23 public List find(String hql)
24 {
25 return this.getHibernateTemplate().find(hql);
26 }
27
28 }

4.Service层: UserService.java

 1 package com.eg.service;
2
3 import java.util.List;
4
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.stereotype.Service;
7
8 import com.eg.dao.UsertDao;
9 import com.eg.model.User;
10
11 @Service("userService")
12 public class UserService {
13 private UsertDao userDao;
14 @Autowired
15 public UserService(UsertDao dao) {
16 this.userDao = dao;
17 }
18
19 public List<User> findAll() {
20 return userDao.find("from Test");
21 }
22 }

5.两个数据库的配置文件:jdbc.properties

#-----------------------------postgresql datasource1---------------------------------------------#
platform.driverClassName=org.postgresql.Driver
platform.url=jdbc:postgresql://localhost:5432/platform
platform.username=postgres
platform.password=root
platform.timeBetweenEvictionRunsMillis=3600000
platform.minEvictableIdleTimeMillis=21600000 #-----------------------------mysql datasource2--------------------------------------------------#
business.driverClassName=com.mysql.jdbc.Driver
business.url=jdbc:mysql://localhost:3306/platform
business.username=root
business.password= root
business.timeBetweenEvictionRunsMillis=3600000
business.minEvictableIdleTimeMillis=21600000 hiber.dialect=org.hibernate.dialect.MySQL5Dialect

6.容器bean注册文件: bean.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
6
7
8 <context:component-scan base-package="com.eg.*"></context:component-scan>
9
10 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
11 <property name="locations">
12 <list>
13 <value>classpath:jdbc.properties</value>
14 </list>
15 </property>
16 </bean>
17
18 <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
19 <property name="url" value="${platform.url}"/>
20 <property name="driverClassName" value="${platform.driverClassName}"/>
21 <property name="username" value="${platform.username}"/>
22 <property name="password" value="${platform.password}"/>
23 <property name="timeBetweenEvictionRunsMillis" value="${platform.timeBetweenEvictionRunsMillis}"></property>
24 <property name="minEvictableIdleTimeMillis" value="${platform.minEvictableIdleTimeMillis}"></property>
25
26 </bean>
27 <bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
28 <property name="url" value="${business.url}"/>
29 <property name="driverClassName" value="${business.driverClassName}"/>
30 <property name="username" value="${business.username}"/>
31 <property name="password" value="${business.password}"/>
32 <property name="timeBetweenEvictionRunsMillis" value="${business.timeBetweenEvictionRunsMillis}"></property>
33 <property name="minEvictableIdleTimeMillis" value="${business.minEvictableIdleTimeMillis}"></property>
34 </bean>
35
36 <bean id="dataSource" class="com.eg.dbsource.DynamicDataSource">
37 <!-- 默认数据库 -->
38 <property name="defaultTargetDataSource" ref="dataSource1"/>
39 <property name="targetDataSources" >
40 <!-- 将多个数据源配在这里,我们将通过改变key值来控制切换 -->
41 <map key-type="java.lang.String">
42 <entry key="db1" value-ref="dataSource1"/>
43 <entry key="db2" value-ref="dataSource2"/>
44 </map>
45 </property>
46 </bean>
47
48 <!-- Hibernate Session工厂 -->
49 <bean id="sessionFactory"
50 class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
51 <property name="dataSource" ref="dataSource"/>
52 <property name="packagesToScan">
53 <list>
54 <value>com.eg.model</value>s
55 </list>
56 </property>
57 <property name="hibernateProperties">
58 <props>
59 <prop key="hibernate.dialect">
60 ${hiber.dialect}
61 <!--org.hibernate.dialect.Oracle10gDialect-->
62 </prop>
63 <prop key="hibernate.show_sql">true</prop>
64 <prop key="hibernate.jdbc.batch_size">50</prop>
65 <prop key="hibernate.cache.use_query_cache">false</prop>
66 </props>
67 </property>
68 </bean>
69
70 <!-- Hibernate 模板 -->
71 <bean id="hibernateTemplate"
72 class="org.springframework.orm.hibernate3.HibernateTemplate">
73 <property name="sessionFactory" ref="sessionFactory"/>
74 </bean>
75
76 </beans>

7.继承AbstractRoutingDataSource,并实现其determineCurrentLookupKey方法:DynamicDataSource.java

 1 package com.eg.dbsource;
2
3
4 import java.sql.SQLFeatureNotSupportedException;
5 import java.util.logging.Logger;
6
7 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
8
9 public class DynamicDataSource extends AbstractRoutingDataSource
10 {
11 protected Object determineCurrentLookupKey() {
12 String type = CustomerContextHolder.getCustomerType();
13 return type;
14 }
15
16 public Logger getParentLogger() throws SQLFeatureNotSupportedException {
17 return null;
18 }
19
20 }

8. 数据源控制器:CustomerContextHolder.java

 1 package com.eg.dbsource;
2
3 public class CustomerContextHolder
4 {
5 private static final ThreadLocal contextHolder = new ThreadLocal();
6
7 public static void setCustomerType(String customerType)
8 {
9 contextHolder.set(customerType);
10 }
11
12 public static String getCustomerType()
13 {
14 return (String) contextHolder.get();
15 }
16
17 public static void clearCustomerType()
18 {
19 contextHolder.remove();
20 }
21 }

9.来测试一下吧:ContextSimulation.java

 1 package com.eg.spring.simulation;
2
3 import java.util.List;
4
5 import org.springframework.context.ApplicationContext;
6 import org.springframework.context.support.ClassPathXmlApplicationContext;
7
8 import com.eg.dbsource.CustomerContextHolder;
9 import com.eg.model.User;
10 import com.eg.service.UserService;
11
12 public class ContextSimulation {
13 public static void main(String[] args) {
14 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
15 UserService testService = (UserService)context.getBean("testService");
16
17 CustomerContextHolder.setCustomerType("db1");
18 List<User> l = testService.findAll();
19
20 CustomerContextHolder.setCustomerType("db2");
21 l = testService.findAll();
22 System.out.println(l.size() +" "+ l.get(0).getName() + " " + l.get(0).getAge());
23 }
24 }

Spring配置多数据源的更多相关文章

  1. Spring配置c3p0数据源时出错报:java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

    今天在使用Spring配置c3p0数据源时,使用的数据库是mysql,服务器是tomcat,运行时报了一个 java.lang.NoClassDefFoundError: com/mchange/v2 ...

  2. Spring配置动态数据源-读写分离和多数据源

    在现在互联网系统中,随着用户量的增长,单数据源通常无法满足系统的负载要求.因此为了解决用户量增长带来的压力,在数据库层面会采用读写分离技术和数据库拆分等技术.读写分离就是就是一个Master数据库,多 ...

  3. Spring配置多数据源错误总结

    由于系统需要调用多个数据源包含mysql,sqlServe和Oracle,所以要在Spring的xml文件中配置多数据源,一下是配置过程中常见的错误: 1.配置的是mysql的数据源,却报oracle ...

  4. Spring配置DataSource数据源

    在Spring框架中有例如以下3种获得DataSource对象的方法: 1.从JNDI获得DataSource. 2.从第三方的连接池获得DataSource. 3.使用DriverManagerDa ...

  5. 使用Spring配置动态数据源实现读写分离

    最近搭建的一个项目需要实现数据源的读写分离,在这里将代码进行分享,以供参考.关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!-- ...

  6. spring配置多数据源——mybatis

    这篇文章是配置mybatis多数据源文章,如果是hibernate的话也是没什么影响,配置都是差不多的. 在这家公司上班差不多一星期了,不小心点开配置文件一看这项目配置了两个数据源,蒙了. 之后上网查 ...

  7. Spring 配置JNDI数据源

    1.Spring 提供的JNDI调用类. 2.使用weblogic进行部署项目,所以使用WebLogicNativeJdbcExtrator类进行配置. 3.配置完数据源后配置sessionFacto ...

  8. 使用 Spring 配置动态数据源实现读写分离

    关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!--读数据源配置--><bean id="readData ...

  9. 阿里P7教你如何使用 Spring 配置动态数据源实现读写分离

    最近搭建的一个项目需要实现数据源的读写分离,在这里将代码进行分享,以供参考. 关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!- ...

  10. jpa+spring配置多数据源

    property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test?useU ...

随机推荐

  1. 导出Eclipse环境配置

    第一种方法: Eclipse的 File -> Export(导出), 在窗口中展开 General(常规) -> Perferences(首选项)-->Export all(全部导 ...

  2. First Bad Version

    You are a product manager and currently leading a team to develop a new product. Unfortunately, the ...

  3. Java通过axis调用WebService

    上午头给了我一个任务,让我对接别的公司的webservice接口,各种百度,看的头晕脑花的,终于通了,记录一下吧. jar包奉上,http://pan.baidu.com/s/1jSchC 包含:ax ...

  4. Windows Server 2008企业64位版防火墙添加端口的方法

    原始地址:http://www.veryhuo.com/a/view/48280.html 什么是防火墙的入站规则和出站规则 简单的说 出站就是你访问外网 入站就是外网访问你 记得在两年前写过一篇教程 ...

  5. 求绝对值,hdu-2003

    求绝对值 Problem Description 求实数的绝对值.   Input 输入数据有多组,每组占一行,每行包含一个实数.   Output 对于每组输入数据,输出它的绝对值,要求每组数据输出 ...

  6. SQL Server 提高创建索引速度的 2 个方法

    方法 1. 使用tempdb来提速 create index index_name on table_name (column_list) with(sort_in_tempdb = on); 方法 ...

  7. 如何实现Linux下的U盘(USB Mass Storage)驱动

    如何实现Linux下的U盘(USB Mass Storage)驱动 版本:v0.7 How to Write Linux USB MSC (Mass Storage Class) Driver Cri ...

  8. TCP和HTTP

    TCP和HTTP 2013-11-01 11:29 6564人阅读 评论(2) 收藏 举报 分类: 计算机—杂七杂八(15) 1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议, ...

  9. 只有勇敢的人、鲁莽的人和绝望的人才会追求大的变革 – D.J. Anderson

    只有勇敢的人.鲁莽的人和绝望的人才会追求大的变革 – D.J. Anderson http://www.cnblogs.com/lchrennew/p/Why-The-Future-Of-Agile- ...

  10. CSS美化页面滚动条

    文章来自:http://www.webhek.com/scrollbar 本文将会告诉你如何用CSS修改/美化浏览器页面上出现的滚动条.改变它们的颜色,调整它们的外形,适配你对页面UI设计.我们首先将 ...