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軟件工程師的基礎知識點



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章