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

  将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. 判断Table表中是否含有某一列

    if (row.Table.Columns.Contains("DealRecord_GiftCost")) {     if (row["DealRecord_Gift ...

  2. Android图片编译报错

    一. AAPT err(1118615418): ERROR: 9-patch image icon_item_bottom_line.9.png malformed No marked region ...

  3. Oracle数据库游标的类型

    游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.Oracle数据库的Cursor类型包含三种: 静态游标:分为显式(explicit)游标 ...

  4. tomcat中的URL参数为中文,servlet接收后显示乱码

    URL中参数的值为中文时,servlet接收后显示为乱码,如下图: 这时候需要修改tomcat的中的server.xml文件.该文件路径为 tomcat安装目录下的conf文件夹.   为修改前的se ...

  5. MySQL基础之 path环境变量的作用 (科普)

    在谈mysql配置环境变量之前,先谈一下windows环境变量的作用,有时候在windows cmd窗口运行命令时,经常会出现“XXX不是内部或外部命令的提示” 原因是系统没有找到执行相应命令的文件( ...

  6. VB.NET Shared(共享)和 Static(静态)关键字的区别

    共享成员(Shared): VB.NET现在是支持真正的面向对象编程,可以继承.使用多态.共享成员 和静态成员. 共享成员就是在所有类和所定义派生类的实例之间共享的方法.属 性.字段和事件.所有使用类 ...

  7. android的数据存储方式

    数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 ...

  8. strace排除Linux服务器故障

    strace是一个有用的小工具 – 大多数Linux系统默认已经安装 – 可以通过跟踪系统调用来让你知道一个程序在后台所做的事情.Strace是一个基础的调试工具;但是即便你不是在跟踪一个问题的时候它 ...

  9. 自学nodejs系列

    好久没有搞nodejs了.nodejs也是更新的很快!!当初翻译的文档

  10. 阿里云 配置apache+python+django 环境 适合菜鸟

    云服务器环境:阿里云服务:20G+1M带宽+centos+512M 一.python安装: 刚开始没有好好利用centos 的yum方法.采用wget从python官网上下载的2.7.5版本.解压安装 ...