1. 程式人生 > >Spring+hibernate 配置多資料來源

Spring+hibernate 配置多資料來源

專案中我們經常會遇到多資料來源的問題,尤其是資料同步或定時任務等專案更是如此。多資料來源讓人最頭痛的,不是配置多個數據源,而是如何能靈活動態的切換資料來源。例如在一個spring和hibernate的框架的專案中,我們在spring配置中往往是配置一個dataSource來連線資料庫,然後繫結給sessionFactory,在dao層程式碼中再指定sessionFactory來進行資料庫操作。

正如上圖所示,每一塊都是指定綁死的,如果是多個數據源,也只能是下圖中那種方式。

可看出在Dao層程式碼中寫死了兩個SessionFactory,這樣日後如果再多一個數據源,還要改程式碼新增一個SessionFactory,顯然這並不符合開閉原則。

那麼正確的做法應該是

1. applicationContext.xml如下

<span style="font-size:12px;"><?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       	   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       	   http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-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/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
           
    <context:annotation-config />
    <!-- 隱式地向 Spring 容器註冊
    AutowiredAnnotationBeanPostProcessor、
    CommonAnnotationBeanPostProcessor、
    PersistenceAnnotationBeanPostProcessor、
    RequiredAnnotationBeanPostProcessor  -->
	<context:component-scan base-package="com.saleSystem,com.interfaces" /><!-- 掃描包中的所有Bean,配置掃描包路徑選項 -->
	<tx:annotation-driven transaction-manager="txManager" /><
[email protected]
這個註解進行的驅動,這是基於註解的方式使用事務配置宣告 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:app/jdbc.properties</value> </property> </bean> <bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="initialSize" value="5" /> <property name="maxActive" value="50" /> <property name="maxIdle" value="50" /> <property name="minIdle" value="0" /> <property name="maxWait" value="6000" /> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <property name="minEvictableIdleTimeMillis" value="25200000" /> </bean> <bean id="adminDataSource" parent="parentDataSource"> <property name="url" value="${jdbc.url}" /> </bean> <bean id="logDataSource" parent="parentDataSource"> <property name="url" value="${log.url}" /> </bean> <bean id="dataSource" class="com.datasource.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="logDataSource" value-ref="logDataSource"/> </map> </property> <property name="defaultTargetDataSource" ref="adminDataSource"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- hibernate 方言 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="javax.persistence.validation.mode">none</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">validate</prop> </props> </property> <property name="mappingDirectoryLocations"> <list> <value> classpath:hibernate </value> </list> </property> </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 面向切面控制權限 --> <aop:config> <aop:pointcut expression="execution(public * com.saleSystem.services..*.* (..))" id="bussinessService" /> <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" /> </aop:config> <!-- 諫言 --> <!-- 事務 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" /><!--以get開頭的方法只能從資料庫中讀取資料 --> <tx:method name="find*" read-only="true" /> <tx:method name="query*" read-only="true"/> <tx:method name="load*" propagation="SUPPORTS" /> <tx:method name="search*" propagation="SUPPORTS" /> <tx:method name="datagrid*" propagation="SUPPORTS" /> <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/><!--以add開頭的方法能對資料庫進行查詢、新增、刪除、編輯1 --> <tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" /> <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="repair" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="deleteAndRepair" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="put*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="restart*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="stop*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="change*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="check*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="start*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="porkDiv" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="send*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="porkRej" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="porkPdtRej" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="loginTimeAdd" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="productSaleBySaleIdAndType" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="sale*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> </beans></span>

2. DynamicDataSource.java

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

public class DynamicDataSource extends AbstractRoutingDataSource {

	protected Object determineCurrentLookupKey() {
		return CustomerContextHolder.getCustomerType();
	}

}

3.CustomerContextHolder.java

public class CustomerContextHolder {
	private static final ThreadLocal contextHolder = new ThreadLocal();

	public static void setCustomerType(String customerType) {
		contextHolder.set(customerType);
	}

	public static String getCustomerType() {
		return (String) contextHolder.get();
	}

	public static void clearCustomerType() {
		contextHolder.remove();
	}

}

在《Hibernate 與 Spring 多資料來源的配置》中提到

 CustomerContextHolder.setCustomerType(DataSourceMap.Admin);//設定資料來源

但是實際運用中,無需再選擇資料來源,Spring會自動根據不同的Model找到相應的資料來源。

另外AbstractRoutingDataSource類也可以實現主從表讀寫分離,目前還未嘗試,但是通過AOP+Annotation即可。


相關推薦

Spring+Hibernate配置資料來源

配置說明          在實際應用中,經常會用到讀寫分離,這裡就這種情況進行Spring+Hibernate的多資料來源配置。此處的配置只是讓讀的方法操作一個數據庫,寫的方法操作另外一個數據庫。  

Spring+hibernate 配置資料來源

專案中我們經常會遇到多資料來源的問題,尤其是資料同步或定時任務等專案更是如此。多資料來源讓人最頭痛的,不是配置多個數據源,而是如何能靈活動態的切換資料來源。例如在一個spring和hibernate的框架的專案中,我們在spring配置中往往是配置一個dataSource來

spring boot 配置資料來源

1.application.yml配置 server: port: 8088 spring: http: multipart: max-file-size: 50Mb max-request-size: 50Mb enabl

spring-mybatis配置資料來源

單資料來源,就是建立一個連線池,然後在建立mybatis的SqlSessionFactoryBean時,指定這個資料來源。 多資料來源:建立多個連線池,將這多個連線池統一起來管理,通過key-value方式,我們在使用時指定哪個key,則使用哪個資料來源,我們只需要繼承spring幫我們寫好的這

Spring Boot配置資料來源並實現Druid自動切換

SpringBoot多資料來源切換,先上配置檔案: 1.pom: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"

spring cloud配置資料來源

配置多個DataSourceConfig與MybatisBossConfig相對應DataSourceConfig:MybatisBossConfig:如果有兩個資料庫,配置兩個即可,同時在application資料庫中配置資料庫連線配置,分為多個數據庫

spring+ibatis配置資料來源

經過上一步對spring配置檔案的配置,接下來我們新建一個介面檔案: public interface IBaseSqlMapClientDaoSupport {     public void choseSqlClient(String name); } 同時也新建一個實現類: public class B

spring+mybatis配置資料來源總結,重點是動態載入資料來源,支援動態切換

最近在做一款遊戲的GM管理平臺,需要連線遊戲的資料庫去查詢資料;由於遊戲的每個服的資料是獨立的,所以就有了連線多個數據庫的問題;經過一番查詢,好在mybatis的學習資源還少,很快找到了配置多資料來源的方法;感謝以下大牛分享的學習資源: http://lvdong5830

Spring動態配置資料來源--mysql從庫

一直做了網際網路的小專案,感覺小公司的效能瓶頸主要在資料庫端。大公司沒去過,不清楚~ 一般用mysql資料庫做主從,讀寫分離,減少主庫的壓力。假設1主4從。4個從庫每次的訪問是隨機,壓力平攤。 先把搜來的貼出來。先記錄下,再去code實驗~ 採用spring的Abstr

spring-hibernate配置個mysql連線池

<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns

springboot配置資料來源Spring Date JPA

多資料來源在專案開發中是經常遇到的,如果同一個專案的不同模組使用的是不同資料庫,就需要多資料來源的處理。現在先寫之前使用JPA的時候遇到多資料來源的配置,後續可能再來個關於mybatis的多資料來源配置。 現在有這樣的需求,專案中有兩個模組,分別是flow與imap,flow需要使用預設資料

Spring Boot +Mybatis 資料來源配置和使用

1、在application.properties中新增資料庫連線配置     mybatis.type-aliases-package=com.yc.edusys.bean     mybatis.mapper-locations=cla

Spring Boot Jpa資料來源配置

前言隨著業務量發展,我們通常會進行資料庫拆分或是引入其他資料庫,從而我們需要配置多個數據源,如:user一個庫,business一個庫。那麼接下來我們就要考慮怎麼去在spring boot中實現多個數據源的配置。 ××× 實現建表首先是建表語句,我們要建立兩個資料庫,並各庫內新建一張表user表mysql

談一談Spring-Mybatis在資料來源配置上的坑

蘇格團隊 作者:JayceKon 交流QQ群:855833773 歡迎加入我們的團隊,微信聯絡方式:foreverpx_cjl 概述 先聊一聊業務背景,隨著系統服務的不斷開發,我們的系統會充斥著各種個樣的業務.這種時候,我們應該要開始考慮一下如何將系統的粒度細化.

談一談 Spring-Mybatis 在資料來源配置上的坑

團隊部落格: https://juejin.im/post/5bfb607f6fb9a04a08215920 概述 先聊一聊業務背景,隨著系統服務的不斷開發,我們的系統會充斥著各種個樣的業務.這種時候,我們應該要開始考慮一下如何將系統的粒度細化.舉個常見的例子: 電商系統可以拆分為 商品模組,訂單模組,地

spring boot 註解方式配置資料來源與使用

1、首先看一下application-dev.yml 配置 spring:     datasource:         type: com.alibaba.druid.pool.Dru

Spring Boot使用資料來源配置JdbcTemplate.md

多資料來源配置 建立一個Spring配置類,定義兩個DataSource用來讀取application.properties中的不同配置。如下例子中,主資料來源配置為spring.datasource.primary開頭的配置,第二資

Spring Boot + MyBatis + Druid環境下配置資料來源

專案中採用Spring Boot + MyBatis + Druid的架構,在原資料來源的基礎上需要新增一個新的資料來源。 除錯期間,發現添加了SqlSessionFactoryBean後,原資料來源有一部分欄位無法取值,後發現是application.yml中的配置失效,

spring 整合mybatis——資料來源切換(附帶定時器的配置,儲存過程連線,資料多於50條,分批進行操作)

新建com.millery.utils包在其下新建DataSourceContextHolder類 package com.millery.utils; public class DataSourceContextHolder { private

Spring boot配置個Redis資料來源操作例項

原文:https://www.jianshu.com/p/c79b65b253fa     Spring boot配置多個Redis資料來源操作例項 在SpringBoot是專案中整合了兩個Redis的操作例項,可以增加多個; 一般在一個微服務生態群中是不會出現多