深入理解spring多数据源配置

网友投稿 181 2023-06-19


深入理解spring多数据源配置

项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此。多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源。例如在一个spring和hibernate的框架的项目中,我们在spring配置中往往是配置一个dataSource来连接数据库,然后绑定给sessionFactory,在dao层代码中再指定sessionFactory来进行数据库操作。

正如上图所示,每一块都是指定绑死的,如果是多个数据源,也只能是下图中那种方式。

可看出在Dao层代码中写死了两个SessionFactory,这样日后如果再多一个数据源,还要改代码添加一个SessionFactory,显然这并不符合开闭原则。

那么正确的做法应该是

代码如下:

1. applicationContext.xml

xmlns:xsi="http://wwwhttp://.w3.org/2001/XMLSchema-instance" xmlns:aop="http://springframework.org/schema/aop"

xmlns:cache="http://springframework.org/schema/cache"

xmlns:context="http://springframework.org/schema/context"

xmlns:jdbc="http://springframework.org/schema/jdbc" xmlns:jee="http://springframework.org/schema/jee"

xmlns:jms="http://springframework.org/schema/jms" xmlns:lang="http://springframework.org/schema/lang"

xmlns:mvc="http://springframework.org/schema/mvc" xmlns:oxm="http://springframework.org/schema/oxm"

xmlns:p="http://springframework.org/schema/p" xmlns:task="http://springframework.org/schema/task"

xmlns:tx="http://springframework.org/schema/tx" xmlns:util="http://springframework.org/schema/util"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-3.1.xsd

http://springframework.org/schema/cache http://springframework.org/schema/cache/spring-cache-3.1.xsd

http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-3.1.xsd

http://springframework.org/schema/jdbc http://springframework.org/schema/jdbc/spring-jdbc-3.1.xsd

http://springframework.org/schema/jee http://springframework.org/schema/jee/spring-jee-3.1.xsd

http://springframework.org/schema/jms http://springframework.org/schema/jms/spring-jms-3.1.xsd

http://springframework.org/schema/lang http://springframework.org/schema/lang/spring-lang-3.1.xsd

http://springframework.org/schema/mvc http://springframework.org/schema/mvc/spring-mvc-3.1.xsd

http://springframework.org/schema/oxm http://springframework.org/schema/oxm/spring-oxm-3.1.xsd

http://springframework.org/schema/task http://springframework.org/schema/task/spring-task-3.1.xsd

http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-3.1.xsd

http://springframework.org/schema/util http://springframework.org/schema/util/spring-util-3.1.xsd">

destroy-method="close">

destroy-method="close">

org.hibernate.dialect.mysqlDialect

org.springframework.orm.hibernate4.SpringSessionContext

false

true

create

com.po

xmlns:xsi="http://wwwhttp://.w3.org/2001/XMLSchema-instance" xmlns:aop="http://springframework.org/schema/aop"

xmlns:cache="http://springframework.org/schema/cache"

xmlns:context="http://springframework.org/schema/context"

xmlns:jdbc="http://springframework.org/schema/jdbc" xmlns:jee="http://springframework.org/schema/jee"

xmlns:jms="http://springframework.org/schema/jms" xmlns:lang="http://springframework.org/schema/lang"

xmlns:mvc="http://springframework.org/schema/mvc" xmlns:oxm="http://springframework.org/schema/oxm"

xmlns:p="http://springframework.org/schema/p" xmlns:task="http://springframework.org/schema/task"

xmlns:tx="http://springframework.org/schema/tx" xmlns:util="http://springframework.org/schema/util"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop-3.1.xsd

http://springframework.org/schema/cache http://springframework.org/schema/cache/spring-cache-3.1.xsd

http://springframework.org/schema/context http://springframework.org/schema/context/spring-context-3.1.xsd

http://springframework.org/schema/jdbc http://springframework.org/schema/jdbc/spring-jdbc-3.1.xsd

http://springframework.org/schema/jee http://springframework.org/schema/jee/spring-jee-3.1.xsd

http://springframework.org/schema/jms http://springframework.org/schema/jms/spring-jms-3.1.xsd

http://springframework.org/schema/lang http://springframework.org/schema/lang/spring-lang-3.1.xsd

http://springframework.org/schema/mvc http://springframework.org/schema/mvc/spring-mvc-3.1.xsd

http://springframework.org/schema/oxm http://springframework.org/schema/oxm/spring-oxm-3.1.xsd

http://springframework.org/schema/task http://springframework.org/schema/task/spring-task-3.1.xsd

http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx-3.1.xsd

http://springframework.org/schema/util http://springframework.org/schema/util/spring-util-3.1.xsd">

destroy-method="close">

destroy-method="close">

destroy-method="close">

destroy-method="close">

org.hibernate.dialect.mysqlDialect

org.springframework.orm.hibernate4.SpringSessionContext

false

true

create

com.po

2. DynamicDataSource.class

package com.core;

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

public class DynamicDataSource extends AbstractRoutingDataSource{

@Override

protected Object determineCurrentLookupKey() {

return DatabaseContextHolder.getCustomerType();

}

}

3. DatabaseContextHolder.class

package com.core;

public class DatabaseContextHolder {

private static final ThreadLocal contextHolder = new ThreadLocal();

public static void setCustomerType(String customerType) {

contextHolder.set(customerType);

}

public static String getCustomerType() {

return contextHolder.get();

}

public static void clearCustomerType() {

contextHolder.remove();

}

}

4. DataSourceInterceptor.class

package com.core;

import org.aspectj.lang.JoinPoint;

import org.springframework.stereotype.Component;

@Component

public class DataSourceInterceptor {

public void setdataSourceOne(JoinPoint jp) {

DatabaseContextHolder.setCustomerType("dataSourceOne");

}

public void setdataSourceTwo(JoinPoint jp) {

DatabaseContextHolder.setCustomerType("dataSourceTwo");

}

}

5. po实体类

package com.po;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

@Entity

@Table(name = "BTSF_BRAND", schema = "hotel")

public class Brand {

private String id;

private String names;

private String url;

@Id

@Column(name = "ID", unique = true, nullable = false, length = 10)

public String getId() {

return this.id;

}

public void setId(String id) {

this.id = id;

}

@Column(name = "NAMES", nullable = false, length = 50)

public String getNames() {

return this.names;

}

public void setNames(String names) {

this.names = names;

}

@Column(name = "URL", length = 200)

public String getUrl() {

return this.url;

}

public void setUrl(String url) {

this.url = url;

}

}

package com.po;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

@Entity

@Table(name = "CITY", schema = "car")

public class City {

private Integer id;

private String name;

@Id

@Column(name = "ID", unique = true, nullable = false)

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

@Column(name = "NAMES", nullable = false, length = 50)

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

6. BrandDaoImpl.class

package com.dao.one;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;

import org.hibernate.SessionFactory;

import org.springframework.stereotype.Repository;

import com.po.Brand;

@Repository

public class BrandDaoImpl implements IBrandDao {

@Resource

protected SessionFactory sessionFactory;

@SuppressWarnings("unchecked")

@Override

public List findAll() {

String hql = "from Brand";

Query query = sessionFactory.getCurrentSession().createQuery(hql);

return query.list();

}

}

7. CityDaoImpl.class

package com.dao.two;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;

import org.hibernate.SessionFactory;

import org.springframework.stereotype.Repository;

import com.po.City;

@Repository

public class CityDaoImpl implements ICityDao {

@Resource

private SessionFactory sessionFactory;

@SuppressWarnings("unchecked")

@Override

public List find() {

String hql = "from City";

Query query = sessionFactory.getCurrentSession().createQuery(hql);

return query.list();

}

}

8. DaoTest.class

package com.test;

import java.util.List;

import javax.annotation.Resource;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import org.springframework.test.context.transaction.TransactionConfiguration;

import com.dao.one.IBrandDao;

import com.dao.two.ICityDao;

import com.po.Brand;

import com.po.City;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = "classpath:com/resource/applicationContext.xml")

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)

public class DaoTest {

@Resource

private IBrandDao brandDao;

@Resource

private ICityDao cityDao;

@Test

public void testList() {

List brands = brandDao.findAll();

System.out.println(brands.size());

List cities = cityDao.find();

System.out.println(cities.size());

}

}

利用aop,达到动态更改数据源的目的。当需要增加数据源的时候,我们只需要在applicationContext配置文件中添加aop配置,新建个DataSourceInterceptor即可。而不需要更改任何代码。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java设计模式之外观模式(Facade)
下一篇:spring MVC搭建及配置详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~