暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

02-01使用ORM持久化数据

nullPoint水 2018-11-08
166

         JDBC可以很好的完成数据持久化工作,但随着应用变动复杂,持久化的需求也变的多样,我们需要对象的属性映射到数据库的列上,并且自动生成语句和查询,此外还需要一些更复杂的特性,如:延迟加载、预先抓取、级联等。

         一些框架提供了这样的服务,这些服务就是对象/关系映射(ORM)。在持久层使用ORM框架可以节省许多代码与开发时间。Spring对多个持久化框架都提供了支持,SpringORM框架的支持提供了与这些框架的集成点以及一些附加的服务:

  1. 支持集成Spring声明式事务

  2. 透明的异常处理

  3. 线程安全的、轻量级的模板类

  4. DAO支持类

  5. 资源管理

SpringJava持久化API

         Java持久化APIJPA)是java持久化标准。在Spring中使用JPA的第一步是在Spring应用上下文中将实体管理器工厂按照bean的形式来进行配置。

配置实体管理器工厂

         基于JPA的应用程序需要使用EntityManagerFactory的实现类来获取EntityManager实例。JPA定义了两种类型实体管理器:

  1. 应用程序管理类型:当应用程序向实体管理器工厂直接请求实体管理器时,工厂会创建一个实体管理器。

  2. 容器管理类型:实体管理器有JavaEE创建和管理。应用程序不与实体管理器工厂打交道。实体管理器直接通过注入或JNDI来获取。容器负责配置实体管理器工厂。

以上两种实体管理器实现了同一个EntityManager接口。区别不在EntityManager本身,而在于EntityManager的创建和管理方式。两种实体管理工厂分别由对应Spring工厂Bean创建:

  1. LocalEntityManagerFactoryBean生成应用程序管理类型的EntityManagerFactory

  2. LocalContainerEntityManagerFactoryBean生成容器管理类型的EntityManagerFactory

选择应用程序管理类型还是容器管理类型的EntityManagerFactory对于基于Spring的应用程序来说完全透明。

配置应用程序管理类型的JPA

         应用程序管理类型的实体管理工厂绝大部分配置信息在persistence.xml的配置文件中,这个文件必须位于类路径下的META-INF目录下。Persistence.xml用于定义一个或多个持久化单元。持久化单元是同一个数据源下的一个或多个持久化类。在persistence.xml文件包含大量的配置信息,所以Spring中只需使用@Bean注解在spring中声明LocalEntityManagerFactoryBean

使用容器管理类型的JPA

         容器管理的JPA才去了一个不同的方式。当运行在容器是,可以使用容器提供的信息来生产EntityManagerFactory。可以将数据源信息配置在Spring应用上下文中,而不是persistence.xml中。

public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){
   LocalContainerEntityManagerFactoryBean factoryBean =
new LocalContainerEntityManagerFactoryBean();
   
factoryBean.setDataSource(dataSource);
   
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
    return
factoryBean;
}

         这里使用Spring配置的数据源来设置dataSource属性,任何javax.sql.DataSource的实现都可以。

         JpaVenderAdapter属性用于指明所使用的是哪一个厂商的JPA实现,以下是Spring提供的JPA实现:

  1. EclipseLinkJpaVendorAdapter

  2. HibernateJpaVendorAdapter

  3. OpenJpaVendorAdapter

  4. TopLinkJpaVendorAdapter(废弃)

 

JNDI获取实体管理器工厂

         如果Spring应用程序部署在应用服务器中,EntityManagerFactory可能已经创建好并位于JNDI中等待查询使用,这种情况可以使用Spring jee命名空间下的<jee:jndi-lookup>元素来获取对EntityManagerFactory的引用。

编写基于JPARepository

         Repository中,使用@persistenceUnit注解将EntityManagerFactory注入到Repository中,有了EntityManagerFactory之后,jpaRepository的方法就能使用它来创建EntityManager,然后EntityManager可以针对数据库执行操作。

         EntityManager并不是线程安全的,一般来将不适合注入到想Repository这样共享单例bean中,可以借助@PersistentContext注解为JpaRepository设置EntityManager@PersistentContext并不会真正注入EntityManager。它没有将真正的EntityManager设置给Repository,而是给了一个EntityManager的代理。真正的EntityManager是与当前事务相关联的那个,如果不存在这样的EntityManager的话,就会新创建一个,这样就能始终以线程安全的方式使用实体管理器。

         @PersistenceUnit@PersistenceContext并不是Spring的注解,是由JPA规范提供的。为了让Spring理解这些注解,必须配置SpringPersistenceAnnotationBeanPostProcessor

借助Spring Data实现自动化JPA Repository

         为了通过SpringData创建Repository的实现,需要在Spring的配置中添加<jpa:repositories>元素。<jpa:repositories>元素需要指定一个要进行扫描的base-package<jpa:repositories>会扫描他的基础包来查找扩展自SpringData JPA Repository接口的所有接口。如果发现了扩展自Repository的接口,会自动生成这个接口的实现。如果要使用Java配置的话,就不需要<jpa:repositories>元素,而是要在Java配置类上添加@EnableJpaRepositories注解。当SpringData发现JpaRepository的接口或子接口后,就会创建该Repository的实现类,其中包含了继承自JpaRepositoryPagingAndSortingRepositoryCrudRepository18个方法。

         当创建Repository实现时,SpringData会检查Repository接口的所有方法,解析方法的名称,并基于被持久化的对象来视图推测方法的目的,本质上,Spring Data定义了一组小型的领域特定语言,持久化的细节都是通过Repository方法的签名来描述的。

         readUserByFirstnameOrLastnameOrderByLastname();

         read:查询动词

         User:主题

         FirstnameOrLastnameOrderByLastname:断言

         具体细节另写吧。SpringData是可以单写一章的。


文章转载自nullPoint水,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论