Spring 与 Hibernate DAO 层?

Posted

技术标签:

【中文标题】Spring 与 Hibernate DAO 层?【英文标题】:Spring with Hibernate DAO layer? 【发布时间】:2012-02-14 13:46:10 【问题描述】:

我在我的 Web 应用程序中使用 Spring 和 Hibernate,我倾向于使用 HibernateDaoSupport,因为它会自动打开会话和关闭会话。我有两个实体Route(route_id, source, destination)Stop(stop_id, latitude, longitude)。这两个表之间的关系是多对多的。一条路线可以包含多个站点,而一个站点可以包含多个路线。

Route.hbm.xml:

<set name="stops" table="route_stop" cascade="all" lazy="false" order-by="stop_id asc">
    <key column="route_id" />
  <many-to-many column="stop_id"  class="com.trackingsystem.model.Stop" />

</set>

Stop.hbm.xml:

<set name="routes" table="route_stop" cascade="all" lazy="false" inverse = "false">
            <key column="stop_id" />
          <many-to-many column="route_id"  class="com.trackingsystem.model.Route" />
        </set>

这是 DAO 类:

public class HibernateRouteStopsDAO extends HibernateDaoSupport implements RouteStopsDAO

    public Set<Stop> getStops(Route route)

        return route.getStops();

    
    public Route getRoute(int routeId)

        return (Route)getSession().get(Route.class, routeId);

    
    public Route getRoute(String source, String destination)
        Session session = null;
        Route route = null;
        try
            session = getSession();
            route = (Route)session.createCriteria(Route.class)
                    .add(Restrictions.eq("source", source))
                    .add(Restrictions.eq("destination", destination)).list().get(0);
        catch (Exception e) 
            System.out.println("RouteStopsDAO "+e);
        finally

        

        return route;

    
    @Override
    public void persistRoute(Route route) 
        Session session = null;
        try
            session = getSession();
            session.save(route);
        catch (Exception e) 
            System.out.println("RouteStopsDAO "+e);
        
    
    @Override
    public void addStops(Route route, Stop stop) 
        Session session = null;

        try
            session = getSession();
            route.getStops().add(stop);
            stop.getRoutes().add(route);
            session.update(route);
            session.update(stop);
        catch (Exception e) 
            System.out.println("RouteStopsDAO "+e);
        finally
        
    
    @Override
    public List<Route> getAllRoutes() 
        // TODO Auto-generated method stub
        Session session = null;
        List<Route> listOfRoutes = new ArrayList<Route>(0);

        try
            session = getSession();
            listOfRoutes = session.createCriteria(Route.class).list();
            return listOfRoutes;

        catch (Exception e) 

            System.out.println("RouteStopsDAO "+e);
            return listOfRoutes;
        finally

        
    
    @Override
    public void updateRoute(Route route) 
        Session session = null;
        try
            session = getSession();
            session.update(route);
            session.flush();
        catch (Exception e) 
            System.out.println("RouteStopsDAO "+e);
        finally

        
    
    @Override
    public void deleteAllStops(Route route) 
        // TODO Auto-generated method stub

        Session session = null;

        try
            session = getSession();
            session.delete(route);

        catch (Exception e) 

            System.out.println("RouteStopsDAO "+e);
        finally
            //session.close();
        

    
    @Override
    public Stop getStop(int stopId) 
        // TODO Auto-generated method stub
        return (Stop) getSession().get(Stop.class, stopId);
    
    @Override
    public List<Route> getRoutes(String stopName) 
        // TODO Auto-generated method stub
        List<Route> routes = new ArrayList<Route>();
        List<Stop> stops = getSession().createCriteria(Stop.class)
        .add(Restrictions.eq("stopName", stopName)).list();

        for(Stop stop : stops)
            routes.addAll(stop.getRoutes());
        

        return routes;
    
    @Override
    public List<Stop> getStops(String stopName) 
        // TODO Auto-generated method stub 
        List<Stop> stops = new ArrayList<Stop>();
        for(Route route : getRoutes(stopName))
            stops.addAll(route.getStops());
        
        return stops;
    
    @Override
    public Stop getStop(String stopName) 
        // TODO Auto-generated method stu
        List<Stop> stops =  getSession().createCriteria(Stop.class)
                .add(Restrictions.eq("stopName", stopName)).list();
        if(stops.size()>0)
            return (Stop)stops.get(0);
        else return null;
    


这里没看懂,是需要启动事务还是HibernateDaoSupport自动启动一个?请更新我的 DAO 类。

【问题讨论】:

【参考方案1】:

不,您必须开始交易。但是使用HibernateDaoSupport 有点过时了。您最好使用 JPA EntityManager 而不是原始休眠。那么你就不需要在你的 DAO 中扩展任何类了。

事务可以通过 spring 提供的declarative transaction management 支持启动。阅读链接的文档,但简而言之 - 您使用 @Transactional 注释一个方法,它会启动一个事务。除此之外,它还会打开一个新会话。

【讨论】:

【参考方案2】:

这真的取决于你想做什么。由于您使用的是 Spring,因此您可以让它为您管理事务。 Spring 的伟大之处在于您可以添加事务支持,而对您的代码影响很小。

你需要

1) 在您的配置中设置 TransactionManager 2) 决定如何划分交易。 3) 删除代码中的所有 try/catch 块。如果您将它们留在其中,您的事务将不会回滚——Spring 管理的事务通常会在出现异常时回滚,除非您以编程方式管理事务。

Here is the Spring documentation on Transactions. 它包含有关如何配置事务管理器以及如何配置声明式事务管理(让容器为您完成大部分工作)的示例。

顺便说一句,不再推荐使用 Spring 事务模板。 See this as for why.

【讨论】:

以上是关于Spring 与 Hibernate DAO 层?的主要内容,如果未能解决你的问题,请参考以下文章

基于Spring4+Hibernate4的通用数据访问层+业务逻辑层(Dao层+Service层)设计与实现!

基于Spring4+Hibernate4的通用数据访问层+业务逻辑层(Dao层+Service层)设计与实现!

基于Spring4+Hibernate4的通用数据访问层+业务逻辑层(Dao层+Service层)设计与实现!

在 Spring Boot 中使用 Hibernate 为 DAO 层配置单元测试

在DAO,服务层架构中使用spring MVC和Hibernate的正确方法是啥

java web项目DAO层通用接口BaseDao与实现类BaseDaoImpl