Nous rencontrons souvent des problèmes avec plusieurs sources de données dans des projets, en particulier des projets tels que la synchronisation des données ou les tâches de synchronisation. La chose la plus gênante à propos de plusieurs sources de données n'est pas de configurer plusieurs sources de données, mais comment changer les sources de données de manière flexible et dynamique. Par exemple, dans un projet de framework Spring and Hibernate, nous configurons souvent une source de données dans la configuration de Spring pour nous connecter à la base de données, puis la lions à la SessionFactory, puis spécifions le SessionFactory dans le code de couche DAO pour effectuer des opérations de base de données.
Comme indiqué dans la figure ci-dessus, chaque bloc est forcément lié. S'il s'agit de plusieurs sources de données, cela ne peut être le même que dans la figure ci-dessous.
On peut voir que deux SessionFactory ont été écrites dans le code de couche DAO. De cette façon, s'il existe une autre source de données à l'avenir, vous devez modifier le code et ajouter un SessionFactory. De toute évidence, cela ne est pas conforme au principe de l'ouverture et de la fermeture.
Alors la bonne façon de le faire devrait être
Le code est le suivant:
1. ApplicationContext.xml
<? 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: aop = "http://www.springframework.org/schema/aop" xmlns: cache = "http://www.springframework.org/schema/cache" xmlns: context = "http://www.springframeworkwork.org/schema/context" xmlns: jdbc = "http://www.springframework.org/schema/jdbc" xmlns: jee = "http://www.springframework.org/schema/jee" xmlns: jms = "http://www.springfrrawworks.org/sche/jms/jms" xmlns: lang = "http://www.springframework.org/schema/lang" xmlns: mvc = "http://www.springframework.org/schema/mvc" xmlns: oxm = "http://www.springfrrame xmlns: p = "http://www.springframework.org/schema/p" xmlns: task = "http://www.springframework.org/schema/task" xmlns: tx = "http://www.springframeworkwork.org/schema/tx" xmlns: util = "http://www.springframework.org/schema/util" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/bans/www.spring http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/context/spring-context-3.1.xsdd http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.xsddbc/jdbc/spring-jdbc-3.xsddd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsdd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd http://www.springframework.org/schema/jms/spring-jms-3.1.xsdd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsdd http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsdd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/utilil http://www.springframework.org/schema/util/spring-util-3.1.xsd "> <context: annotation-config /> <context: Component-San Base-Package =" com "> </ context: Component-Scan> <an Bean> <propriété name =" Locations "> <liste> <value> CLASSPATH: com / ressource / config.properties </value> </sist> </ propriété> </ bean> <bean id = "dataSourceOne" destrement-méthod = "close"> <propriété name = "DriverClass" value = "$ {dbone.jdbc.DriverClass}" /> <propriété name = "jdbcurl" value = "$ {dbone.jdbc.url}" /> <propriété name = "user" value = "$ {dbone.jdbc.user}" /> <propriété name = "mot de passe" value = "$ {dbone.jdbc.password}" /> <propriété name = "initialSize" value = "$ {dbone.jdbc.initialpools" /> <propriété name = "minpoolSize" value = "$ {dbone.jdbc.minpoolSize}" /> <propriété name = "maxpoolSize" value = "$ {dbone.jdbc.maxpoolSize}" /> </ bean> <bean id = "datasourcetwo" destrust-method = "close"> <propriété = "dilyerclass" Value = "$ {dbtwo.jdbc.DriverClass}" /> <propriété name = "jdbcUrl" value = "$ {dbtwo.jdbc.url}" /> <propriété name = "user" value = "$ {dbtwo.jdbc.User}" /> <propriété name = "mot de passe" value = "$ {dbtwo.jdbc.password}" /> <propriété name = "initialPoolSize" value = "$ {dbtwo.jdbc.InitialPoolSize}" /> <propriété name = "MinpoolSize" value = "$ {dbtwo.jdbc.minpoolSize}" /> <Propriété = "MAXPOLISE value = "$ {dbtwo.jdbc.maxpoolSize}" /> </ank> <bean id = "dynamicDataSource"> <propriété name = "TargetDatasources"> <map key-type = "java.lang.string"> <entrée valeur-ref = "datasourceOne" key = "datasource"> </ grenoue> value-ref = "datasourcetwo" key = "datasourcetwo"> </ntry> </aph> </ propriété> <propriété name = "defaultTargetDataSource" ref = "dataSourceOne"> </ propriété> </ank> <bean id = "sessionfactory"> <propriété name = "dataSource" ref = "dynamicdata name = "HiberNateProperties"> <props> <prop key = "hibernate.dialect"> org.hibernate.dialect.mysqldialect </prop> <prop key = "hibernate.current_session_context_class"> org.springframework.hibernate4 key = "hibernate.show_sql"> false </ prop> <prop key = "hibernate.format_sql"> true </ prop> <prop Key = "hbm2ddl.auto"> Créer </ prop> </props> </ propriété> <propriété name = "packageStoscan"> <list> <value> com.po </value> id = "TransactionManager"> <propriété name = "sessionfactory" ref = "sessionfactory" /> </-bean> <aop: config> <aop: Pointcut id = "transactionpointcut" expression = "EXECUTION (* com.dao .. *. * (..))" /> <aop: conseiller conseil " <tx: conseil id = "txadvice" transaction-manager = "transactionManager"> <tx: attributes> <tx: méthode name = "add *" propagation = "requis" /> <tx: méthode name = "enregistrer *" propagation = "requise" /> <tx: méthode name = "update *" propagation = "requis" /> <tx: méthode name = "delete *" propagation = "requise" /> <tx: méthode name = "delete *" propagation = "requis" /> <tx: méthode name = "Delete *" Pro propagation = "requise" /> <tx: méthode nom = "Delete *" Pro propagation = "requise" /> <tx: méthode Nom = "Delete *" Propagation = "require <tx: méthode name = "*" read-only = "true" /> </ tx: attributes> </ tx: conseils> <aop: config> <aop: aspect id = "dataSourCeaspect" ref = "dataSourceIntercept"> <aop: Pointcut id = "daoone" expression = "exécution (* com.dao.one. *. *. id = "daotwo" expression = "exécution (* com.dao.two. *. * (..))" /> <aop: avant Pointcut-ref = "daoone" method = "setDataSourceOne" /> <aop: avant Pointcut-ref = "daotwo" méthode = "setDatasourcetwo" /> </aop: 2. DynamicDatasource.class
package com.core; import org.springframework.jdbc.datasource.lookup.abstractroutingDataSource; La classe publique DynamicDataSource étend AbstratTroutingDataSource {@Override Protected Object DeterMectionCurrentLookUpkey () {return databaseContexTholder.getCustomerType (); }} 3. DatabaseContexTholder.class
package com.core; classe publique DatabaseContexTholder {private static final threadLocal <string> contexTholder = new ThreadLocal <string> (); 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.sterereotype.Component; @Component public classe publique DataSourceInterceptor {public void setDataSourceOne (joinpoint jp) {databasEcontexTholder.setCustomerType ("dataSourceOne"); } public void setDataSourcetwo (joinpoint jp) {databaseContexTholder.setCustomerType ("dataSourCetwo"); }} 5. Classe d'entité 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 = "hôtel") classe publique de classe {ID de chaîne privée; noms de chaînes privées; URL de chaîne privée; @Id @Column (name = "id", unique = true, nullable = false, longueur = 10) public String getID () {return this.id; } public void setid (String id) {this.id = id; } @Column (name = "noms", nullable = false, longueur = 50) public string getNames () {return this.Names; } public void setNames (names de chaîne) {this.Names = noms; } @Column (name = "url", longueur = 200) String public 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") Classe publique City {ID entier privé; nom de chaîne privé; @Id @Column (name = "id", unique = true, nullable = false) public Integer getID () {return id; } public void setid (INGER ID) {this.id = id; } @Column (name = "noms", nullable = false, longueur = 50) public string getName () {return name; } public void setName (string name) {this.name = name; }} 6. Branddaoimpl.class
package com.dao.one; Importer java.util.list; import javax.annotation.resource; import org.hibernate.query; import org.hibernate.SessionFactory; import org.springframework.sterreotype.repository; import com.po.brand; @Repository Public Class BrandDaoimpl implémente iBranddao {@Resource Protected SessionFactory SessionFactory; @SuppressWarnings ("Unchecked") @Override Public List <brand> findall () {String hql = "From Brand"; Query query = sessionfactory.getCurrentession (). CreateQuery (HQL); return query.list (); }} 7. Citydaoimpl.class
package com.dao.two; Importer java.util.list; import javax.annotation.resource; import org.hibernate.query; import org.hibernate.SessionFactory; import org.springframework.sterreotype.repository; import com.po.city; @Repository public class CityDaoIMPl implémente iCityDao {@Resource Private SessionFactory SessionFactory; @SuppressWarnings ("Unchecked") @Override public list <gity> find () {String hql = "From City"; Query query = sessionfactory.getCurrentession (). CreateQuery (HQL); return query.list (); }} 8. DaOtest.class
package com.test; Importer 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.cicitydao; import com.po.brand; import com.po.city; @Runwith (springjunit4classrunner.class) @contextconfiguration (locations = "classpath: com / ressource / applicationContext.xml") @transactionConfiguration (transactionManager = "TransactionManager", Defaultrollback = false) public class daOtest {@Resource private ibranddao branddao; @Resource Private iCitydao Citydao; @Test Public Void TestList () {list <brand> marques = branddao.findall (); System.out.println (Brands.size ()); Liste <gity> Cities = Citydao.Find (); System.out.println (Cities.Size ()); }} Utilisez AOP pour atteindre le but de modifier dynamiquement la source de données. Lorsque nous devons ajouter des sources de données, nous devons seulement ajouter une configuration AOP dans le fichier de configuration ApplicationContext et créer un nouveau DataSourceInterceptor. Sans changer de code.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.