A menudo encontramos problemas con múltiples fuentes de datos en proyectos, especialmente proyectos como la sincronización de datos o las tareas de tiempo. Lo más problemático de múltiples fuentes de datos no es configurar múltiples fuentes de datos, sino cómo cambiar las fuentes de datos de manera flexible y dinámica. Por ejemplo, en un proyecto de marco de Spring e Hibernate, a menudo configuramos una fuente de datos en la configuración de Spring para conectarse a la base de datos, y luego lo vinculamos a SessionFactory, y luego especificamos el SessionFactory en el código de capa DAO para realizar operaciones de la base de datos.
Como se muestra en la figura anterior, cada bloque está obligado a estar vinculado. Si son múltiples fuentes de datos, solo puede ser lo mismo que en la figura a continuación.
Se puede ver que dos SessionFactory se han escrito en el código de capa DAO. De esta manera, si hay otra fuente de datos en el futuro, debe cambiar el código y agregar una SessionFactory. Obviamente, esto no se ajusta al principio de apertura y cierre.
Entonces la forma correcta de hacerlo debería ser
El código es el siguiente:
1. ApplicationContext.xml
<? xml versión = "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.springframework.org/schema/contytt" " xmlns: jdbc = "http://www.springframework.org/schema/jdbc" xmlns: jee = "http://www.springframework.org/schema/Jee" xmlns: jms = "http://wwww.springframwork.org.org.org.orgshwork" xmlns: lang = "http://www.springframework.org/schema/lang" xmlns: mvc = "http://www.springframework.org/schema/mvc" xmlns: oxm = "http://wwww.springframe xmlns: p = "http://www.springframework.org/schema/p" xmlns: tarea = "http://www.springframework.org/schema/task" xmlns: tx = "http://www.springframework.org/schem xmlns: util = "http://www.springframework.org/schema/util" xsi: schemalocation = "http://www.springframework.org/schema/beans http:/www.springframework.org/schema/scoans/spring-beanss.xsping-beanss. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/ http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springfframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/sspring-jdbdbdbdbdbdbdbdbdbdbdbs http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd 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.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd http://www.springframework.org/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.xsd http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/Task--Task-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springfframework.org//util http://www.springframework.org/schema/util/spring-util-3.1.xsd "> <context: annotation-config/> <context: component-scan base-pankage =" com "> </context: componente-scan> <bean> <name de propiedad =" ubicaciones "> <lista> <value> classpath: com/resource/config.properties </value> </list> </property> </bean> <bean id = "dataSourceone" destruye-method = "cerrar"> <propiedad name = "conductorclass" valor = "$ {dBone.jdbc.driverClass}"/> <name de propiedad = "jdbcurl" value = "$ {dBone.JdBone.JDBone.JdBone.JDBone.JDBOn /> <propiedad name = "user" value = "$ {dbone.jdbc.user}" /> <propiedad name = "contraseña" value = "$ {dbone.jdbc.password}" /> <Property name = "inicialPoolSize" value = "$ {dbone.jdbc.initialpoolSize}" /> <name de propiedad = "minpoolSize" valor = "$ {dbone.jdbc.minpoolsize}" /> <propiedad name = "maxpoolSize" value = "$ {dbone.jdbc.maxpoolsize}" /> </ bean> <bean id = "dataSourCetwo" destruye-metod = "cero"> <nombre de propiedad = "controlador valor = "$ {dbtwo.jdbc.driverClass}" /> <propiedad name = "jdbcurl" value = "$ {dbtwo.jdbc.url}" /> <Property name = "user" value = "$ {dbtwo.jdbc.user}" /> <name de propiedad = "Value" Value = "$ {dbtwwwwo.jdbc. name = "inicialPoolSize" value = "$ {dbtwo.jdbc.initialPoolSize}" /> <Property name = "minpoolSize" value = "$ {dbtwo.jdbc.minpoolSize}" /> <Property name = "maxpoolSize" value = "$ {dbtwo.jdbc.maxpoolsize} /<r}" id = "DynamicDataSource"> <Property Name = "TargetDataSources"> <map key-Type = "java.lang.String"> <Entry Value-REF = "DataSourceone" Key = "DataSourceOne"> </Entry> <Entry Value-REF = "DataSourCetwo" Key = "DataSourCetwo"> </Interin name = "DefaultTargetDataSource" ref = "DataSourceone"> </property> </ Bean> <Bean ID = "SessionFactory"> <Property Name = "DataSource" ref = "DynamicDataSource"/> <Property Name = "HibernateProperties"> <props> <Prop> key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> <prop key="hibernate.show_sql">false</prop> <prop key = "Hibernate.Format_Sql"> true </prop> <prot key = "hbm2ddl.auto"> create </prop> </props> </propine> <Property name = "packagescan"> <sist> <son value> com.po </value> </list> </bean> <bean id = "transaccionManager"> <product name> session facting </list> </beLe> </ behor> <bean id = "transaccionManager"> <product name> session facting </list> </aL /> < /bean> <aop: config> <aop: pointCut id = "transaccionPointCut" Expression = "Ejecution (*com.dao ..*.*(..))" /> <aop: asesor-consejo-ref = "txadvice" point-ref = "transactionPointcut" /> < /aop: config> <tx: consejo id = "txadvice" Transaction-Manager = "TransactionManager"> <tx: atributes> <tx: método name = "add*" propagation = "requerido" /> <tx: método name = "salvar*" propagation = "requerido" /> <tx: name = "update*" propagation = "requerido" /> <tx: método name = "delete*" propagation = "requerido" /> <tx n. read Only = "true" /> < /tx: atributes> < /tx: consejo> <aop: config> <aop: aspecto id = "dataSourCeAspect" ref = "dataSourceIntercept"> <aop: puntos id = "daoone" expresión = "ejecutor (*com.dao.one.*.*(..))" /> <aop: punto id = "daoTwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowwowWo com.dao.two.*.*(..)) " /> <aop: antes de pointcut-ref =" daoone "método =" setDataSceone " /> <aop: antes de punto-ref =" daotwo "método =" setDataSourcetwo " /> </aop: aspecto> </aop: config> </ Beans> 2. DynamicDataSource.Class
paquete com.core; importar org.springframework.jdbc.dataSource.lookup.AbstracTroutingDataSource; Public Class DynamicDataSource extiende AbstrutingDataSource {@Override Object DetdinECRENTLOPLOPTOUPKEY () {return dataBASEContexTholder.getCustomerType (); }} 3. DataBaseContexTholder.Class
paquete com.core; public class dataBASEContexTholder {private static final ThreadLocal <String> cotexTholder = new ThreadLocal <String> (); public static void setCustomerType (String CustomerType) {cotexTholder.set (CustomerType); } public static string getCustomerType () {return cotexTholder.get (); } public static void clearCustomerType () {cotexTholder.remove (); }} 4. DataSourceinterceptor.class
paquete com.core; importar org.spectj.lang.joinpoint; importar org.springframework.stereotype.component; @Component public class dataSourceInterceptor {public void setDataSourceone (JoinPoint JP) {DataBASEContexTholder.SetCustomerType ("DataSourceone"); } public void setDataSourCetwo (unkenpoint jp) {dataBASEContexTholder.setCustomerType ("DataSourCetwo"); }} 5. Clase de entidad PO
paquete 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") Brand de clase pública {ID de cadena privada; nombres de cadenas privadas; URL de cadena privada; @Id @column (name = "id", unique = true, nullable = false, longitud = 10) public String getId () {return this.id; } public void setid (ID de cadena) {this.id = id; } @Column (name = "Names", Nullable = false, longitud = 50) Cadena pública getNames () {return this.names; } public void setNames (nombres de cadenas) {this.names = nombres; } @Column (name = "url", longitud = 200) public String getUrl () {return this.url; } public void seturl (url de cadena) {this.url = url; }} paquete 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 {ID de entero privado; nombre de cadena privada; @Id @column (name = "id", unique = true, nullable = false) public integer getId () {return id; } public void setid (ID de entero) {this.id = id; } @Column (name = "Names", Nullable = false, longitud = 50) cadena pública getName () {return name; } public void setName (nombre de cadena) {this.name = name; }} 6. BranddaoImpl.Class
paquete com.dao.one; import java.util.list; import javax.annotation.resource; importar org.hibernate.query; importar org.hibernate.sessionFactory; importar org.springframework.stereotype.repository; import com.po.brand; @Repository public class BranddaoImpl implementa Ibranddao {@Resource protegido sessionFactory sessionFactory; @SupessWarnings ("sin verificar") @Override Public List <Rand> findall () {String hql = "From Brand"; Query Query = SessionFactory.GetCurrentSession (). CreateQuery (HQL); return query.list (); }} 7. CitydaoImpl.Class
paquete com.dao.two; import java.util.list; import javax.annotation.resource; importar org.hibernate.query; importar org.hibernate.sessionFactory; importar org.springframework.stereotype.repository; import com.po.city; @Repository public class CityDaoImpl implementa IcityDao {@Resource privado sessionFactory sessionFactory; @SupplesSwarnings ("sin verificar") @Override Public List <city> find () {String hql = "From City"; Query Query = SessionFactory.GetCurrentSession (). CreateQuery (HQL); return query.list (); }} 8. Daotest.class
paquete com.test; import java.util.list; import javax.annotation.resource; importar org.junit.test; importar org.junit.runner.runwith; importar org.springframework.test.context.contextConfiguration; importar org.springframework.test.context.junit4.springjunit4classrunner; importar 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 (ubicaciones = "classpath: com/resource/applicationContext.xml") @TransactionConfiguration (transaccionManager = "TransActionManager", defaultrollback = false) public class Daotest {@Resource Private Ibrandda Branddao; @Resource Private Icitydao Citydao; @Test public void testList () {list <Rand> Brands = Branddao.findall (); System.out.println (brands.size ()); List <city> ciudad = citydao.find (); System.out.println (Cities.Size ()); }} Use AOP para lograr el propósito de cambiar dinámicamente la fuente de datos. Cuando necesitamos agregar fuentes de datos, solo necesitamos agregar la configuración de AOP en el archivo de configuración de ApplicationContext y crear un nuevo DataSourceInterceptor. Sin cambiar ningún código.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.