【问题标题】:How to manage persistence using Spring and Hibernate如何使用 Spring 和 Hibernate 管理持久性
【发布时间】:2015-01-13 12:36:40
【问题描述】:

我刚刚在 Spring 中使用 Hibernate 启动了一个 Web 应用程序,这就是我想的方式(在找到了几种方法之后):

通用DAO

public interface GenericDAO<T extends DomainModel> {
     public T getById(Integer id);
     public List<T> getAll();
     public void saveEntity(T object);
     public void deleteEntity(T object);
}

通用DAOImpl

public class GenericDAOImpl<T extends DomainModel> implements GenericDAO<T> {

    private Class<T> type;    
    @Autowired
    protected SessionFactory sessionFactory;    
    public void setSessionFactory(SessionFactory sessionFactory){
        this.sessionFactory = sessionFactory;
    }        
    public Session getCurrentSession(){
        return sessionFactory.getCurrentSession();
    }    
    public GenericDAOImpl(Class<T> type) {
        super();
        this.type = type;
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    @Override
    public T getById(Integer id) {
        if( id == null){
            return null;
        } else {
            return (T) getCurrentSession().get(type, id);
        }        
    }
    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    @Override
    public List<T> getAll() {        
        return getCurrentSession().createQuery("select o from " + type.getName() + " o").list();
    }


    @Transactional(readOnly = true)
    @Override
    public void saveEntity(T object) {
        getCurrentSession().persist(object);        
    }
    @Transactional(readOnly =  true)
    @Override
    public void deleteEntity(T object) {
        getCurrentSession().delete(object);        
    }
}

用户服务

public interface UserService {
     public void addUser(User user);
     public List<User> getUsers();
     public User get(Integer id);
     public void delete(User user);
}

用户服务实现

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private GenericDAO<User> userDAO;

    @Override
    public void addUser(User user) {
        userDAO.saveEntity(user);        
    }

    @Override
    public User get(Integer id) {
        return userDAO.getById(id);
    }

    @Override
    public void delete(User user) {
        userDAO.deleteEntity(user);        
    }

    @Override
    public List<User> getUsers() {
       return userDAO.getAll();
    }
}

用户控制器

@Controller
public class UserController {

     @Autowired
     private UserService userService;

     @RequestMapping(value = "test", method = RequestMethod.GET)
     public String test(){

          User u1 = userService.get(1);        
          return "test";
     }
}

配置休眠

<?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:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/online_auction" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>

    <!-- Hibernate 4 SessionFactory Bean definition -->
    <bean id="mySessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan" value="online_auction.domain_model" />
        <property name="hibernateProperties">
            <props>
                <!-- SQL dialect depends on which database you connect to -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            </props>
        </property>
    </bean>


    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"></property>
        </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />
    <mvc:annotation-driven/>
</beans>

配置弹簧

<?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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">


    <import resource="classpath:dataSource.xml"/>

    <mvc:annotation-driven />

    <context:component-scan base-package="online_auction"/>

    <mvc:resources location="css" mapping="/css/**" />
    <mvc:resources location="images" mapping="/images/**" />

    <!-- Tiles configuration -->

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass">
            <value>
                org.springframework.web.servlet.view.tiles2.TilesView
            </value>
        </property>
    </bean>
    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean>
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>    
</beans>

我的问题是:

  1. 如何管理数据库连接?每个会话
    网络请求?数据库连接何时打开和关闭?
  2. 我是否应该在服务中创建会话并将其作为参数传递给存储库构造函数。我是否还应该操纵会话方法,例如:打开会话、开始事务、提交、关闭会话。
  3. 由于是我第一个使用 Repository 和 Service 的分层应用程序,因此欢迎任何有关如何管理数据库连接/会话/事务的建议。提前致谢!

【问题讨论】:

  • 1.这取决于,默认是每个事务的会话。 2.不,不,不(我是不是这样)。我建议阅读(非常出色的恕我直言)Spring 参考指南的 Hibernate 和 Transaction 部分。

标签: java spring hibernate spring-mvc


【解决方案1】:

您的一些查询的指针 - 考虑使用 Spring 的 OpenSessionInViewInterceptor,它将 Hibernate Session 绑定到线程以完成请求的整个处理。您可以将其 bean 定义为:

<bean name="openSessionInViewInterceptor"
    class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>

并在 Spring 的 context.xml 中 SimpleUrlHandlerMapping bean 的“拦截器”属性中引用。

更多关于OpenSessionInViewInterceptorhere的细节。

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 2016-08-14
    • 2012-12-19
    • 2011-07-03
    • 2011-05-10
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多