前段时间有个项目,sPRing+hibernate 的框架,这个项目是数据库传输相关的,会配置好几个数据库,就考虑能否把数据库配置放在 一个表里,程序启动时加载,这样会减少配置文件,清晰明了。
如果你的工程要操作多个数据库,而且都要集成到spring中,用spring 的配置文件配置是很常见的。配置多个xml然后import到主xml(applicationContext.xml),里面把datasource 和beanfactory ,扫描包等配置好即可,
不过动态加的话,就有所不同了。当然是先 百度/google一下了,发现有不少案例是 多数据源+动态切换,不过这和我们的程序还是有出入的.后来找到一个 动态加bean 的,类似:
DefaultListableBeanFactory dbf = (DefaultListableBeanFactory) appContext.getBeanFactory(); BeanDefinitionBuilder dataSourceBuider = BeanDefinitionBuilder.genericBeanDefinition(ComboPooledDataSource.class);有了这个ioc的入口,那就简单些了,至少在定义bean方面是没问题的。
文件一,beans.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:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd"></beans>文件二,ThirdImplTest.java (启动spring动态加载数据源)
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Properties;import javax.sql.DataSource;import org.apache.log4j.Logger;import org.junit.Before;import org.junit.Test;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.context.ApplicationContext;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.orm.hibernate4.LocalsessionFactoryBean;import com.mchange.v2.c3p0.ComboPooledDataSource;public class ThirdImplTest { static Logger log = Logger.getLogger(TgdUserServiceThirdImplTest.class); TgdUserServiceThirdImpl impl ; @Before public void beforeS() { ConfigurableApplicationContext appContext = new ClassPathXmlApplicationContext("classpath:beans.xml"); appContext = (ConfigurableApplicationContext) tooper(appContext); impl = (TgdUserServiceThirdImpl)appContext.getBean("tgdUserServiceThirdImpl"); } /** * 操作 代码注入 * @param dbf * @param appContext */ private ApplicationContext tooper(ConfigurableApplicationContext appContext){ String driverClass = "com.MySQL.jdbc.Driver"; String jdbcUrl = "jdbc:mysql://192.168.1.1:3306/xxx?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&pinGlobalTxToPhysicalConnection=true&autoReconnect=true&uSEOldAliasMetadataBehavior=true"; String user = "root"; String passWord = "xxxx"; DefaultListableBeanFactory dbf = (DefaultListableBeanFactory) appContext.getBeanFactory(); BeanDefinitionBuilder dataSourceBuider = BeanDefinitionBuilder .genericBeanDefinition(ComboPooledDataSource.class); dataSourceBuider.addPropertyValue("driverClass", driverClass); dataSourceBuider.addPropertyValue("jdbcUrl", jdbcUrl); dataSourceBuider.addPropertyValue("user",user); dataSourceBuider.addPropertyValue("password",password); dataSourceBuider.addPropertyValue("acquireIncrement","5"); dataSourceBuider.addPropertyValue("initialPoolSize","3"); dataSourceBuider.addPropertyValue("minPoolSize","3"); dataSourceBuider.addPropertyValue("maxPoolSize","10"); dataSourceBuider.addPropertyValue("maxIdleTime","600"); dataSourceBuider.addPropertyValue("idleConnectionTestPeriod","3600"); dataSourceBuider.addPropertyValue("maxStatements","100"); dataSourceBuider.addPropertyValue("numHelperThreads","10"); dataSourceBuider.addPropertyValue("testConnectionOnCheckout",false); dataSourceBuider.addPropertyValue("preferredTestQuery","SELECT 1 FROM DUAL"); dataSourceBuider.addPropertyValue("breakAfterAcquireFailure",false); dataSourceBuider.addPropertyValue("acquireRetryAttempts",30); dbf.registerBeanDefinition("third_dataSource", dataSourceBuider.getBeanDefinition()); // 配置 LocalSessionFactoryBean //LocalSessionFactoryBean注册,注册时候在获取结果不再是它本身而是sessionFactory BeanDefinitionBuilder llfb = BeanDefinitionBuilder .genericBeanDefinition(LocalSessionFactoryBean.class); //这里的属性对应配置文件或者LocalSessionFactoryBean源码中的属性来,自己去看看就晓得 llfb.addPropertyValue("dataSource", (DataSource)appContext.getBean("third_dataSource")); List<String> packagesToScanList = new ArrayList(); packagesToScanList.add("com.snm.third"); llfb.addPropertyValue("packagesToScan", packagesToScanList); Properties p = new Properties(); p.setProperty("hibernate.hbm2ddl.auto","none"); p.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect"); p.setProperty("hibernate.show_sql","true"); p.setProperty("hibernate.form_sql","true"); p.setProperty("hibernate.connection.username",user); p.setProperty("hibernate.connection.password",password); p.setProperty("hibernate.connection.url",jdbcUrl); p.setProperty("hibernate.default_batch_fetch_size","30"); p.setProperty("hibernate.cache.use_second_level_cache","false"); p.setProperty("hibernate.current_session_context_class","org.springframework.orm.hibernate4.SpringSessionContext");// p.setProperty("hibernate.current_session_context_class","thread"); llfb.addPropertyValue("hibernateProperties",p); dbf.registerBeanDefinition("third_sessionFactory", llfb.getBeanDefinition()); // 本来想看看集成spring 事务怎么搞的, 不过搞不定,这几行貌似没什么用 // construct an appropriate transaction manager // DataSourceTransactionManager txManager = new DataSourceTransactionManager((DataSource)appContext.getBean("third_dataSource"));// // configure the AnnotationTransactionaspect to use it; this must be done before executing any transactional methods// AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(); annotationConfigApplicationContext.setParent(appContext); annotationConfigApplicationContext.scan("com.xxx.xxx"); annotationConfigApplicationContext.refresh(); return annotationConfigApplicationContext; } @Test public void testgetAllList() throws Exception { log.info(DJsonUtil.getJsonFromObect(impl.getAllList1(new HashMap(), null))); }}文件三 TUserServiceThirdImpl
import java.util.List;import java.util.Map;import org.hibernate.SQLQuery;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.apache.util.Sort;import com.snm.third.model.equpt.TgdUser;@Servicepublic class TUserServiceThirdImpl{ @Autowired private SessionFactory sessionFactory; public List getAllList1(Map<String, String> params, Sort sorts) { Session session = null; List list = null; try { session = sessionFactory.openSession(); SQLQuery query = session.createSQLQuery("select * from tuser"); list = query.list(); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } return list; }}上面三个文件,即可以使用了.
所以@Transactional 的使用暂时还没有。。如果要多数据源的事务,只能 begin后rollback
数据源的相互引用 平时使用spring的bean,都是直接@Resource,@Autowire 引进来,但多数据源的相互引用不行,数据源是一个个加载的,如果加A的过程中,有B的Autowire,则会依赖报错 。
spring cloud ? 貌似有spring搭建配置中心 的说法,不过还没了解过.
新闻热点
疑难解答