Spring专题学习

19.Spring中ORM关系对象映射持久化数据

2018-09-18  本文已影响0人  Lee_java

说到持久化或者ORM关系对象映射的框架,我们可能会首先想到Hibernate,随之又出现了IBatis,MyBatis等等ORM的框架。其中Spring也对多个持久化的框架提供了支持,Hibernate,IBATIS,MYBATIS,JPA,JDO等等。
Spring对ORM框架的支持提供了与这些框架的集成点以及一些附加的服务:
(1)支持集成Spring声明式服务
(2)透明的异常处理
(3)线程安全的,轻量级的模板类
(4)DAO支持类
(5)资源管理
1.Hibernate
使用Hibernate所需要的主要接口是org.hibernate.Session。该接口提供了基本的数据访问功能。通过该接口,应用程序的Repository能够满足所有的持久化需求。获取Hiberante Session对象的标准方式是借助Hibernate SessionFactory接口的实现类。SessionFactory主要负责Hibernate Session的打开,关闭和管理。该接口定义如下:


package org.hibernate;

import java.io.Serializable;
import java.sql.Connection;

import org.hibernate.jdbc.Work;
import org.hibernate.stat.SessionStatistics;

public interface Session extends Serializable {

    public EntityMode getEntityMode();

    public Session getSession(EntityMode entityMode);

    public void flush() throws HibernateException;

    public void setFlushMode(FlushMode flushMode);

    public FlushMode getFlushMode();

    public void setCacheMode(CacheMode cacheMode);

    public CacheMode getCacheMode();

    public SessionFactory getSessionFactory();

    public Connection connection() throws HibernateException;

    public Connection close() throws HibernateException;

    public void cancelQuery() throws HibernateException;

    public boolean isOpen();

    public boolean isConnected();

    public boolean isDirty() throws HibernateException;

    public Serializable getIdentifier(Object object) throws HibernateException;

    public boolean contains(Object object);

    public void evict(Object object) throws HibernateException;

    public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException;

    public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException;

    public Object load(Class theClass, Serializable id) throws HibernateException;

    public Object load(String entityName, Serializable id) throws HibernateException;

    public void load(Object object, Serializable id) throws HibernateException;

    public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException;

    public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException;

    public Serializable save(Object object) throws HibernateException;

    public Serializable save(String entityName, Object object) throws HibernateException;

    public void saveOrUpdate(Object object) throws HibernateException;

    public void saveOrUpdate(String entityName, Object object) throws HibernateException;

    public void update(Object object) throws HibernateException;

    public void update(String entityName, Object object) throws HibernateException;

    public Object merge(Object object) throws HibernateException;

    public Object merge(String entityName, Object object) throws HibernateException;

    public void persist(Object object) throws HibernateException;

    public void persist(String entityName, Object object) throws HibernateException;

    public void delete(Object object) throws HibernateException;

    public void delete(String entityName, Object object) throws HibernateException;

    public void lock(Object object, LockMode lockMode) throws HibernateException;

    public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException;

    public void refresh(Object object) throws HibernateException;

    public void refresh(Object object, LockMode lockMode) throws HibernateException;

    public LockMode getCurrentLockMode(Object object) throws HibernateException;

    public Transaction beginTransaction() throws HibernateException;

    public Transaction getTransaction();

    public Criteria createCriteria(Class persistentClass);

    public Criteria createCriteria(Class persistentClass, String alias);

    public Criteria createCriteria(String entityName);

    public Criteria createCriteria(String entityName, String alias);

    public Query createQuery(String queryString) throws HibernateException;

    public SQLQuery createSQLQuery(String queryString) throws HibernateException;

    public Query createFilter(Object collection, String queryString) throws HibernateException;

    public Query getNamedQuery(String queryName) throws HibernateException;

    public void clear();

    public Object get(Class clazz, Serializable id) throws HibernateException;

    public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException;

    public Object get(String entityName, Serializable id) throws HibernateException;

    public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException;

    public String getEntityName(Object object) throws HibernateException;

    public Filter enableFilter(String filterName);

    public Filter getEnabledFilter(String filterName);

    public void disableFilter(String filterName);
    
    public SessionStatistics getStatistics();

    public void setReadOnly(Object entity, boolean readOnly);

    public void doWork(Work work) throws HibernateException;

    Connection disconnect() throws HibernateException;

    void reconnect() throws HibernateException;
 
    void reconnect(Connection connection) throws HibernateException;
}

在Spring中,我们要通过Spring的某一个Hibernate Session工厂Bean来获取Hibernate SessionFactory。3.1开始,Spring提供了三个Session工厂bean供我们选择:

(1)org.springframework.orm.hibernate3.LocalSessionFactoryBean
(2)org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
(3)org.springframework.orm.hibernate4.LocalSessionFactoryBean

上述三种Bean都是Spring FactoryBean的实现。它们会产生一个Hibernate SessionFactoryBean,能够装配进任何SessionFactory类型的属性中。
FactoryBean接口的定义:

package org.springframework.beans.factory;

public interface FactoryBean<T> {
    T getObject() throws Exception;//返回一个对象
    Class<?> getObjectType();//返回对象的类型
    boolean isSingleton();//是否为单例
}


类可以通过注解的方式表明要使用Hibernate进行持久化,这些类可以使用的注解包括JPA的@Entity或者@MappedSuperclass以及Hibernate的@Entity注解。
HibernateTemplate能够保证每个事务使用同一个Session,但是这种方式的缺点是我们的Repository的实现会直接与Spring耦合。
推荐使用上下文Session,通过上下文Session的方式,会直接将Hibernate SessionFactory装配到Repository中,并且用它来获取Session


@Repository注解
是Spring的另外一种构造注解,它能够像其他注解一样被Spring的组件扫描到。


2.JPA
(1)JPA也叫做Java Persostence API,Spring中使用JPA的第一步是要在Spring应用的上下文中将实体管理器工厂按照bean的形式来进行配置。
(2)基于JPA的应用程序需要使用EntityManagerFactory的实现类来获取EntityManager实例,其中JPA定义了两种类型的实体管理器:
A.应用程序管理类型:
当应用程序向实体管理器工厂直接请求实体管理器时,工厂会创建一个实体管理器。在这种模式下,程序要负责打开或关闭实体管理器并在事务中对其进行控制。这种方式的实体管理器适合于不运行在JavaEE容器中的独立应用程序。
B.容器管理类型:
实体管理器由JavaEE创建和管理。应用程序根本不会与实体管理器工厂打交道。相反,实体管理器直接通过注入或者JNDI来获取。容器负责配置实体管理器工厂。这种类型的实体管理器最适用于JavaEE容器,在这种情况下会希望再persistence.xml指定的JPA配置之外保持一些自己对JPA的控制。
上述两种的区别在于EntityManager的创建和管理方式。应用程序管理类型的EntityManager是由EntityManagerFactory创建的,容器管理类型是通过PersistenceProvider的createEntityManagerFactory方法得到的。
(3)Spring提供了两种工厂Bean来创建上述的两种实体管理类型:

LocalEntityManagerFactoryBean//生成应用程序管理类型的EntityManagerFactory
LocalContainerEntityFactoryBean//生成容器管理类型的EntityManagerFactory

(4)persistence.xml文件
a、必须位于类路劲META-INF目录下。
b、用于定义一个或者多个持久化单元,持久化单元是同一个数据源下的一个或者多个持久化类,识别持久化单元中的实体类。
(5)jpaVendorAdapter属性
a.用来指明所使用的是哪一个厂商的JPA实现
b.Spring提供了多个JPA厂商的适配器:

EclipseLinkJpaVendorAdapter
HibernateJpaVendorAdapter
OpenJpaVendorAdapter
Hibernate的JPA适配器支持多种数据库.jpg

(5)从JNDI获取实体管理器工厂

<jee:jndi-lookup id="id" jndi-name="persistence/aaa"/>

Java形式:

JndiObjectFactoryBean jndi = new JndiObjectFactoryBean();
jndi.setJndiName("jdbc/aaa");
return jndi;

它的返回结果是一个EntityFactory bean。
(6)@PersistenceContext注解
该注解并不会真正注入EntityManager.它没有将真正的EntityManager设置给Repository,而是给了它一个EntityManager的代理。真正的EntityManager是与事务相关联的那个,如果不存在这样的EntityManager,就会创建一个新的。此时,就能始终以线程安全的方式使用实体管理器。
(7)@Transactional
该注解表示这个Repository中的持久化方法是在事务上下文中执行的。

上一篇下一篇

猜你喜欢

热点阅读