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

  将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. sql server数据库区分大小写设置

    数据库表中字段alter Table TableName 区分大小写 ALTER Column ColumnName VARCHAR(50) COLLATE Chinese_PRC_CS_AS不区分大 ...

  2. Hibernate 关联关系映射实例

    双向多对一/一对多(many-to-one/one-to-many) 例子,多个学生对应一个班级,一个班级对应多个学生: 班级类,Grade.java: public class Grade { pr ...

  3. NULL & nil & Nil & NSNULL的区别

    nil 是 OC 的,空对象,地址指向 空(0) 的对象 在 OC 中,可以给空对象发送任何消息,不会出现错误 NULL 是 C 的,空地址,地址的数值是 0,是一个长整数 表示地址是空 NSNull ...

  4. iOS获取文件路径

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px "PingFang SC"; color: #008400 } p.p2 ...

  5. 网易云数据结构- Maximum Subsequence Sum

    题目 题目地址 思路 显然是最大子列和的进化版,那就先思考下经典的最大子列和.这也是道思维题,啥算法也没用到,全是思维技巧,真心不知道考试遇到这种题该怎么办了. 存放答案的一个类,我把它看成一个袋子, ...

  6. SQL in Qt (一)

    Connecting to Databases To access a database with QSqlQuery or QSqlQueryModel, create and open one o ...

  7. Dubbo使用详解及环境搭建

    一:Dubbo简介 Dubbo是阿里巴巴提供的开源的SOA(面向服务的体系结构)服务化治理的技术框架,据说只是一部分开源的,但一些基本的需求已经可以满足的,而且可扩展性.是一种能取代PHRPC的服务调 ...

  8. 自己写的轻量级PHP框架trig与laravel5.1,yii2性能对比

    看了下当前最热门的php开发框架,想对比一下自己写的框架与这些框架的性能对比.先看下当前流行框架的投票情况. 看结果对比,每个测试脚本做了一个数据库的联表查询并进行print_r输出,查询的sql语句 ...

  9. python编辑器对比和推荐

    python编辑器对比和推荐   我先给一个初步的表格吧,大家如果有什么意见,或有补充,欢迎提出.有些我没有用过,先不写了.以下是我使用过的python IDE: 除了PythonWin, Visua ...

  10. cf459A Pashmak and Garden

    A. Pashmak and Garden time limit per test 1 second memory limit per test 256 megabytes input standar ...