// For Hibernate
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>com/lzy/forum/domain/User.hbm.xml</value>
<value>com/lzy/forum/domain/Article.hbm.xml</value>
<value>com/lzy/forum/domain/Board.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
// For DAO
<bean id="userDAO"
class="com.lzy.forum.dao.impl.UserDAOHibernate">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="boardDAO"
class="com.lzy.forum.dao.impl.BoardDAOHibernate">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="articleDAO"
class="com.lzy.forum.dao.impl.ArticleDAOHibernate">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
//For Struts Action
<bean name="/regist" class="com.lzy.forum.action.RegistAction"
singleton="false">
<property name="userDAO">
<ref local="userDAO" />
</property>
</bean>
<bean name="/login" class="com.lzy.forum.action.LoginAction"
singleton="false">
<property name="userDAO">
<ref local="userDAO" />
</property>
</bean>
<bean name="/boardManage"
class="com.lzy.forum.action.BoardManageAction" singleton="false">
<property name="userDAO">
<ref local="userDAO" />
</property>
<property name="boardDAO">
<ref local="boardDAO" />
</property>
</bean>
<bean name="/boardNavigate"
class="com.lzy.forum.action.BoardNavigateAction" singleton="false">
<property name="boardDAO">
<ref local="boardDAO" />
</property>
</bean>
<bean name="/boardDisplay"
class="com.lzy.forum.action.BoardDisplayAction" singleton="false">
<property name="boardDAO">
<ref local="boardDAO" />
</property>
</bean>
<bean name="/articleManage"
class="com.lzy.forum.action.ArticleManageAction" singleton="false">
<property name="userDAO">
<ref local="userDAO" />
</property>
<property name="boardDAO">
<ref local="boardDAO" />
</property>
<property name="articleDAO">
<ref local="articleDAO" />
</property>
</bean>
</beans>
经过这样的配置之后,Hibernate事务交由Spring管理,sessionFactory从Spring容器获得。下面通过其中的一个DAO实例来看看这样做带来的方便。
//BoardDAO.java
package com.lzy.forum.dao;
import java.util.ArrayList;
import com.lzy.forum.domain.Board;
public interface BoardDAO {
public boolean isBoardExist(String name);
public void addBoard(Board board);
public void deleteBoard(Board board);
public Board loadBoard(int id);
public Board loadBoard(String name);
public Board loadBoardWithArticles(int id);
public ArrayList getRootBoardsList();
}
//BoardDAOHibernate.java
package com.lzy.forum.dao.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Set;
import org.hibernate.Hibernate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.lzy.forum.dao.BoardDAO;
import com.lzy.forum.domain.Board;
public class BoardDAOHibernate extends HibernateDaoSupport implements BoardDAO {
public void deleteBoard(Board board) {
// TODO Auto-generated method stub
this.getHibernateTemplate().delete(board);
}
public void addBoard(Board board) {
// TODO Auto-generated method stub
this.getHibernateTemplate().saveOrUpdate(board);
}
public boolean isBoardExist(String name) {
// TODO Auto-generated method stub
ArrayList list = (ArrayList) this.getHibernateTemplate().find(
"from Board where name = ? ", new Object[] { name });
if (list.size() > 0) {
// System.out.println("find it");
return true;
}
return false;
}
public Board loadBoard(int id) {
// TODO Auto-generated method stub
ArrayList list = (ArrayList) this.getHibernateTemplate().find(
"from Board where id = ? ", new Object[] { id });
Board b = null;
if (list.size() > 0) {
b = (Board) list.get(0);
}
return b;
}
public Board loadBoard(String name) {
// TODO Auto-generated method stub
ArrayList list = (ArrayList) this.getHibernateTemplate().find(
"from Board where name = ? ", new Object[] { name });
Board b = null;
if (list.size() > 0) {
b = (Board) list.get(0);
}
return b;
}
public ArrayList getRootBoardsList() {
// TODO Auto-generated method stub
ArrayList list = (ArrayList) this.getHibernateTemplate().find(
"from Board b left join fetch b.ChildBoards where b.Parent = null order by b.id");
System.out.println(list.size() + " root boards found ");
ListIterator index = list.listIterator();
while (index.hasNext()) {
Board s = (Board) index.next();
//this.getSession(true);
//Hibernate.initialize(s.getChildBoards());
///*
Set children = (Set) s.getChildBoards();
Iterator it = children.iterator();
while(it.hasNext()){
Board b = (Board)it.next();
//Hibernate.initialize(b);
System.out.println(b.getName());
}
//*/
//System.out.println(children.size() + "child(ren) found ");
//s.setChildBoards(s.getChildBoards());
}
return list;
}
public Board loadBoardWithArticles(int id) {
// TODO Auto-generated method stub
ArrayList list = (ArrayList) this.getHibernateTemplate().find(
"from Board b left join fetch b.Articles where b.Id = ? ", new Object[] { id });
Board b = null;
if (list.size() > 0) {
b = (Board) list.get(0);
}
return b;
}
}
BoardDAOHibernate继承 HibernateDaoSupport后,通过getHibernateTemplate()得到一个HibernateTemplate实例,然后执行CRUD操作,非常简单。需要注意的是,由于执行一次CRUD操作后,Hibernate session关闭,如果有使用延迟加载策略的对象没有加载,在后面的Web层很容易出现如下错误:
failed to lazily initialize a collection of role
从网上搜到的解决方法是Open Session In View,
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
我试了试,还是有一些问题,所以后来还是放弃了这种方法,所有在Web层中需要的对象都必须在Business层中加载完成。如下面的代码所示:
ArrayList list = (ArrayList) this.getHibernateTemplate().find(
"from Board b left join fetch b.Articles where b.Id = ? ", new Object[] { id });
这样Hibernate和Spring的结合也算完成了。其他的一些DAO类和实现代码我没有给出,但是大同小异,和Board的实现类似。
最后将是Struts 和Spring的结合,将在下一篇给出。(未完待续)