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。噹,收工!
---
---
---
沒有留言:
張貼留言