Spring 設定檔。
<context:component-scan base-package="idv.neil.model,idv.neil.service,idv.neil.dao" /> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven />先用 context:component-scan 告訴 Spring 所有的 Annotation 在哪些 package 裡。
然後建立 Hibernate SessionFactory,這是給 Dao 用的。
再建立 TransactionManager,這是給 Service 用的。
最後用 tx:annotation-driven 將全部串起來。
Dao 裡怎麼用?
@Repository("newDao") @SuppressWarnings("serial") public class NewDaoImpl implements NewDao, Serializable { private Logger log = LoggerFactory.getLogger(this.getClass()); private SessionFactory sessionFactory; @Inject public NewDaoImpl(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } private Session getSession() { return this.sessionFactory.getCurrentSession(); } // ... }@Repository 是給 context:component-scan 用的。
@Inject 則是將 SessionFactory 塞進來,Dao 就活起來了。
Service 裡怎麼做?
@Service("newService") @SuppressWarnings("serial") public class NewServiceImpl implements NewService, Serializable { private Logger log = LoggerFactory.getLogger(this.getClass()); private NewDao newDao; @Inject public NewServiceImpl(NewDao newDao) { this.newDao = newDao; } @Override @Transactional public List<Entity> list(QueryVO queryVO) { return this.newDao.list(queryVO); } }@Service 是給 context:component-scan 用的。
@Inject 則是將 Dao 塞進來。
最後在每個需要交易或者說是 Hibernate Session 的 method 加上 @Transactional。
這樣就是一個使用單一資料庫的系統。
哪怎麼加入第二個資料庫呢?
將以上所有的設定複製一份?不夠!還要加上 qualifier 才行。
Spring 設定檔。
<bean id="oldSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.old.cfg.xml" /> <qualifier value="old" /> </bean> <bean id="oldTransactionManager" name="oldTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="oldSessionFactory" /> <qualifier value="old" /> </bean> <tx:annotation-driven transaction-manager="oldTransactionManager" />複製一份 SessionFactory,指向不同的 hibernate.cfg.xml 檔,還要加上 qualifier,供稍後 Dao 指名使用。
複製一份 TransactionManager,指向剛的 SessionFactory,一樣要加上 qualifier,也是供稍後的 Service 指名使用。
複製一份 tx:annotaion-driven,將全部串起來,但這次要指明使用哪個 transaction-manager。
再看一次 Dao 怎麼用?
@Repository("oldDao") @SuppressWarnings("serial") public class OldDaoImpl implements OldDao, Serializable { private Logger log = LoggerFactory.getLogger(this.getClass()); private SessionFactory sessionFactory; @Inject public OldDaoImpl(@Qualifier("old") SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } private Session getSession() { return this.sessionFactory.getCurrentSession(); } // ... }唯一的差別就是在 @Inject method 的傳入參數裡加上 @Qualifier,並指明 old。
Service 也是一樣的方式。
@Service("oldService") @SuppressWarnings("serial") public class OldServiceImpl implements OldService, Serializable { private Logger log = LoggerFactory.getLogger(this.getClass()); private OldDao oldDao; @Inject public OldServiceImpl(OldDao oldDao) { this.oldDao = oldDao; } @Override @Transactional("old") public List<Entity> list(QueryVO queryVO) { return this.oldDao.list(queryVO); } }只是在 @Transactional 裡加上參數,也就是 old。
噹,收工!
---
---
---
沒有留言:
張貼留言