前段時間有個項目,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搭建配置中心 的說法,不過還沒了解過.
|
新聞熱點
疑難解答