2.[精通Hibernate笔记]整合Spring

Spring3.0已不再支持Hibernate2.x,仅为Hibernate3.x提供支持,且要求Hibernate必须在3.2版本以上。

配置SessionFactory

使用Hibernate框架的第一个工作是编写Hibernate配置文件,如何使用配置文件实例化SessionFactory,Spring为创建SessionFactory提供了一个好用的FactoryBean工厂类:org.springframework.orm.hibernate3.LocalSessionFactoryBean,通过配置一些必要的属性,可以获取一个SessionFactory的Bean。

Hibernate API创建爱你SessionFactory

Configuration config = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = config.buildSessionFactory();

Hibernate.cfg.xml配置文件提供Hibernate基础所需的配置信息。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
            "http://hiberante.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>"
        <property name="connection.url">jdbc:mysql://localhost:3306/SAMPLEDB</property>"
        <property name="connection.username">root</property>"
        <property name="connection.password">1234</property>"
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>"
        <property name="shwo_sql">true</property>"
        <property name="format_sql">true</property>"
        <property name="current_session_context_class">thread</property>"
    </session-factory>
</hibernate-configuration>

这个配置文件定义了三个信息:数据源、对象映射文件以及Hibernate控制属性信息。

在Spring中,通过制定一个Hibernate配置文件,利用LocalsessionFactory来实现。

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:configLocation="classpath:hibernate.cfg.xml" />

Spring风格的配置

Spring对ORM技术的支持是提供统一的数据源管理机制,即在Spring容器中定义数据源、指定映射文件、设置Hibernate控制属性信息,完成集成组装的工作,完全抛开hibernate.cfg.xml配置文件。

<?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:p="http://www.springfreamework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
                           http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                           http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassname="${jdbc.driverClassName}"
        p:url="${jdbc.url}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}" />
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:dataSource-ref="dataSource">
        <property name="mappingLocations">
            <list>
                <value>cms.com.system.domain.User</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>
</beans>

由于这种配置方式将所有的配置信息都统一到Spring中,给管理、维护和调整都带来的方便,因此称为被广泛接受的配置方式。

HibernateTemplate

基于模板类使用Hibernate是最简单的方式,按照Spring的风格,提供了使用模板的支持类HibernateDaoSupport,并通过getHibernateTemplate()方法项子类开放模板类实例的调用。

为了能够使用竹节配置的功能先编写一个BaseDao:

import javax.annotation.Resource;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;
@Component
public class BaseDao {
    private HibernateTemplate hibernateTemplate;
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    @Resource
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
}
@Component("userDao")
public class UserDao extends BaseDao {
    public void save(User user) {
        this.getHibernateTemplate().save(user);
    }
    public void delete(User user) {
        this.getHibernateTemplate().delete(user);
    }
    public void update(User user) {
        this.getHibernateTemplate().update(user);
    }
    public List<User> findUsers() {
        return this.getHibernateTemplate().find("from User user");
    }
}

HibernateTemplate代理了Hibernate Session的大多数持久化操作,并以一种更简洁的方式提供调用。

常见API方法

Serializable save(Object entity):保存实体对象,并返回主键值

void update(Object entity):更新实体对象

void saveOrUpdate(Object entity):保存或更新一个实体

void delete(Ojbect entity):删除一个实体

List find(String queryString):根据HQL查询实体

List findByNamedQuery(String queryName):执行命令查询

在Spring配置DAO

<?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:p="http://www.springfreamework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
                           http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                           http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    <!-- 扫描类包已启动注解驱动的Bean -->
    <context:component-scan base-package="cms.com" />
    <context:property-placeholder location="classpath:jdbc.properties" />
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassname="${jdbc.driverClassName}"
        p:url="${jdbc.url}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}" />
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:dataSource-ref="dataSource" p:mappingDirecotryLocations="cms.com.system.domain.User">
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    <!-- 配置HibernateTemplate Bean -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" p:sessionFacotry-ref="sessionFactory" />
    <!-- 配置Hibernate的事务管理器 -->
    <bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory" />
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>

在Spring配置问加你中,配置一个HibernateTemplate Bean,它基于SessionFactory工作,使用<context:component-scan>扫描特定的类包已启动注解驱动的Bean。

使用原生HibernateAPI

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
    @Autowired
    private SessionFactory sessionFactory;
    public void add(User user) {
        this.sessionFactory.getCurrentSession().save(user);
    }
    public void udpate(User user) {
        this.sessionFactory.getCurrentSession().update(user);
    }
}

使用原生Hibernate API所抛出的异常是Hibernate异常,即DAO的调用者智能以普通的错误来处理这些异常,而无法在声明式事务中使用通用的SpringDAO的异常体系集成回滚配置。

使用注释配置

Hibernate不但可以使用XML提供的ORM配置信息,也可以直接在领域对象中通过注解定义ORM映射信息。

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Column;
@Entity
@Table(name = "users")
public class User implements Serializable {
    @Id
    @Column(name = "id")
    private Integer id;
    public User() {
        super();
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
}

Hibernate通过AnnotationConfiguration的addAnnotatedClass()或addPackage()方法加载使用JPA注解的实体类,获取映射的元素数据信息,并在此基础上创建SessionFactory实例。

Spring提供AnnotationSessionFactoryBean,用于创建爱你基于JPA注解的SessionFactory。

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource-ref="dataSource">
    <property name="annotatedClasses">
        <list>
            <value>cms.com.system.domain.User</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>

AnnotationSessionFactoryBean扩展了LocalSessionFactoryBean类,增强的功能是:可以根据实体类的注解获取ORM的配置信息。也允许混合使用XML配置和注解配置对象关系映射,Hibernate内部自动将这些元素信息整合,不会产生冲突。

事务处理

Spring的通用事务管理模型对Hibernate完全使用,包括编程式事务、基于TransactionProxyFactoryBean、基于aop/tx以及基于@Transaction注解的事务管理。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
}

在Spring配置文件中配置Hibernate事务管理器,并启动注解驱动事务:

<!-- 配置HibernateTemplate Bean -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" p:sessionFacotry-ref="sessionFactory" />
<!-- 配置Hibernate的事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven transaction-manager="transactionManager" />

Hibernate的事务管理器需要注意个SessionFactory实例,命名“transactionMamanger“后,在<tx:annotation-drivern/>中无需通过annotation-manager默认显式指定。



说明:笔记内容摘自《精通Hibernate:Java对象持久化技术详解》

关联:整理了一些Java软件工程师的基础知识点



你可能感兴趣的:(学习笔记)