Мы часто сталкиваемся с проблемами с несколькими источниками данных в проектах, особенно таких проектах, как синхронизация данных или задачи времени. Самое неприятное в нескольких источниках данных - это не настройка нескольких источников данных, а о том, как переключать источники данных гибким и динамичным образом. Например, в проекте Spring и Hibernate Framework мы часто настраиваем дат данных в конфигурации пружины для подключения к базе данных, а затем связываем его с SessionFactory, а затем указываем SessionFactory в коде уровня DAO для выполнения операций базы данных.
Как показано на рисунке выше, каждый блок должен быть связан. Если это несколько источников данных, он может быть только таким же, как на рисунке ниже.
Можно видеть, что в коде уровня DAO было написано два сеансафакторию. Таким образом, если в будущем появится другой источник данных, вы должны изменить код и добавить SessionFactory. Очевидно, это не соответствует принципу открытия и закрытия.
Тогда правильный способ сделать это должен быть
Код заключается в следующем:
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://wwww.springframe.orschema. xmlns: jdbc = "http://www.springframework.org/schema/jdbc" xmlns: jee = "http://www.springframework.org/schema/jee" xmlns: jms = "http:/www.springfema.spramemema. xmlns: lang = "http://www.springframework.org/schema/lang" xmlns: mvc = "http://www.springframework.org/schema/mvc" xmlns: oxm = "http://wwww.spramefema/xmlns: oxm =" http://wwww.spramemema/xmlns: oxm = " xmlns: p = "http://www.springframework.org/schema/p" xmlns: task = "http://www.springframework.org/schema/task" xmlns: tx = "http://www.springframe.orschema. xmlns: util = "http://www.springframework.org/schema/util" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.spramework.org/schema/beans/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-cach-3.1.xsd http://www.springframework.org/schema/context/spring-3.1.x.x.x.x.x.x.x.x.x.xmsd http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/jdbc http://www.spramework.org/schema/jdbc/spring-jds.s.s.s.s.s.3. 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-3.1.xsd 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-x.x.xsd.1.xsd3. http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-t. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"> <context:annotation-config /> <context:component-scan base-package="com"></context:component-scan> <bean> <property name="locations"> <list> <value>classpath:com/resource/config.properties</value> </list> </property> </bean> <bean id = "dataSourceOne" Dressome-method = "close"> <name = "griverclass" value = "$ {dbone.jdbc.driverclass}"/> <property name = "jdbcurl" value = "$ {dbone.jdbc.Url}"/> <name = "stame =" user "" stame = "user" "stame =" user "" value = "$ {dbone.jdbc.user}" /> <name = "password" value = "$ {dbone.jdbc.password}" /> <name = "initialpoolsize" value = "$ {dbone.jdbc.initialpoolsize}" /> <proporting negine = "minpoolsize" value = "$ {dbone.jdbc.minpoolsize}" /> <name = "maxpoolsize" value = "$ {dbone.jdbc.maxpoolsize}" /> < /bean> <bean id = "dataSourcetwo" Dressome-method = "Закрыть"> <Pomy = "Driveclass" value = "$ {dbtwo.jdbc.driverclass}" /> <name = "jdbcurl" value = "$ {dbtwo.jdbc.url}" /> <name = "user" value = "$ {dbtwo.jdbc.user}" /> name = "password =" $ "$" name = "initialPoolsize" value = "$ {dbtwo.jdbc.initialpoolsize}" /> <name = "minpoolsize" value = "$ {dbtwo.jdbc.minpoolsize}" /> <property name = "maxpoolsize" value = "$ {dbtwo.jdbc.maxsize" /beansize " /> /> <bean id = "DynamicDataSource"> <property name = "targetDataSources"> <Map Key-type = "java.lang.string"> <vent Value-ref = "dataSourceOne" key = "dataSourceOne"> </intry-value-ref = "dataSourcetwo" key = "dataSourcetwo"/intry ref = "mapasourcetwo" name = "defaultTargetDataSource" ref = "dataSourceOne"> </property> </bean> <bean id = "sessionFactory"> <name = "dataSource" ref = "DynamicDataSource"/> <name = "hibernateProperties"> <props> <prop key = "hibernate.dialect"> org.hibernate.dialect.mysqlidialect </prop> <prop key = "hibernate.current_session_context_class"> org.springframework.orm.hibernate4.springsessionContext </prop> <prope = "hibernate.show_ssql" key = "hibernate.format_sql"> true </prop> <prop key = "hbm2ddl.auto"> create </prop> </props> </property> <property name = "packagestoscan"> <sist> <datter> com.po </value> </list> </propetion> </bean> <bean id = "transctionman"> negory namory "> </property> </bean> <bean id =" ref = "sessionFactory" /> < /bean> <aop: config> <aop: pointcut id = "transactionpointcut" Express = "execution (*com.dao ..*.*(..))" /> <aop: Advisor ref-ref = "txadvice" pointcut-ref = "transactionpointcut" /> < /aop: confice> <coptcut = "TransactionPointcut" /> < /aoP: ocportcut = "transaction Transaction-manager = "transactionManager"> <TX: атрибуты> <tx: method name = "add*" Propagation = "требуется" /> <tx: method name = "save*" Propagation = "требуется" /> <tx: method name = "update*" Propagation = "требуется" /> <tx: method name = "delete =" name = " /> <tx" /> <tx: "method =" delete = "" /> <tx " /> <tx" /> <tx: "delete". read-only = "true" /> < /tx: атрибуты> < /tx: Advice> <aop: config> <aop: аспект id = "dataSourCeaspepe" ref = "dataSourceIntercept"> <aop: pointcut id = "daoone" Expression = "Commancement (*com.dao.one.*(*(*(*(*com.dao.one. com.dao.two.*.*(..)) " /> <aop: перед pointcut-ref =" daoone "method =" setDataSourceOne " /> <aop: до pointcut-ref =" daotwo "method =" setDataSourcetwo " /> < /aop: apect> < /aop: config> < /bean 2. DynamicDataSource.class
пакет com.core; Импорт org.springframework.jdbc.datasource.lookup.abstractroutingDataSource; Общедоступный класс DynamicDatasource расширяет AbstractroutingDataSource {@Override Protected Object DegineCurrentLookupkey () {return databaseContextholder.getCustomerType (); }} 3. DatabaSecontextholder.class
пакет com.core; открытый класс 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
пакет com.core; Импорт 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 Entity
пакет com.po; Импорт javax.persistence.column; Импорт javax.persistence.entity; Импорт javax.persistence.id; Импорт javax.persistence.table; @Entity @Table (name = "btsf_brand", schema = "Hotel") открытый бренд класса {Private String Id; частные имена строк; частная строковая URL; @ID @Column (name = "id", уникальный = 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 (строки имена) {this.names = names; } @Column (name = "url", length = 200) public String geturl () {return this.url; } public void seturl (string url) {this.url = url; }} пакет com.po; Импорт javax.persistence.column; Импорт javax.persistence.entity; Импорт javax.persistence.id; Импорт javax.persistence.table; @Entity @Table (name = "city", schema = "car") public class City {private Integer id; Приватное название строки; @Id @column (name = "id", уникальный = 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
пакет com.dao.one; импортировать java.util.list; Импорт javax.annotation.resource; Импорт org.hibernate.query; Импорт org.hibernate.sessionFactory; Import org.springframework.sterotype.repository; Импорт com.po.brand; @Repository public class branddaoimpl реализует ibranddao {@resource protected sessionfactory sessionfactory; @Suppresswarnings ("unchecked") @override public list <drand> findall () {string hql = "от brand"; Query Query = sessionFactory.getCurrentSession (). CreateQuery (hql); return Query.list (); }} 7. CityDaoImpl.class
пакет com.dao.two; импортировать java.util.list; Импорт javax.annotation.resource; Импорт org.hibernate.query; Импорт org.hibernate.sessionFactory; Import org.springframework.sterotype.repository; Импорт com.po.city; @Repository public class citydaoimpl реализует icitydao {@resource private sessionfactory sessionfactory; @Suppresswarnings ("unchecked") @override public list <sity> find () {string hql = "из города"; Query Query = sessionFactory.getCurrentSession (). CreateQuery (hql); return Query.list (); }} 8. Daotest.class
пакет com.test; импортировать java.util.list; Импорт javax.annotation.resource; Импорт org.junit.test; Импорт org.junit.runner.runwith; Import org.springframework.test.context.contextConfiguration; Import org.springframework.test.context.junit4.springjunit4classrunner; Импорт org.springframework.test.context.transaction.transactionConfiguration; Импорт com.dao.one.ibranddao; импорт com.dao.two.icitydao; Импорт com.po.brand; Импорт com.po.city; @Runwith (springjunit4classrunner.class) @contextconfiguration (locations = "classpath: com/resource/applicationcontext.xml") @TransactionConfiguration (TransactionManager = "TransactionManager", DefaulTrotlback = false) открытый класс DaOtest {@Resource Private IbrandDao BrandDaO; @Resource private icitydao citydao; @Test public void testlist () {list <brand> brands = branddao.findall (); System.out.println (brands.size ()); Список <itys> Cities = cityDao.find (); System.out.println (cities.size ()); }} Используйте AOP, чтобы достичь цели динамического изменения источника данных. Когда нам нужно добавить источники данных, нам нужно только добавить конфигурацию AOP в файл конфигурации ApplicationContext и создать новый DataSourceInterceptor. Без изменения кода.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.