spring(11)使用对象-关系映射持久化数据

【0】README
1)本文部分文字描述转自:“Spring In Action(中/英文版)”,旨在review  “spring(11)使用对象-关系映射持久化数据” 的相关知识;

【2】spring 与 java 持久化API
1)intro:JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
2)在spring中使用 JPA 第一步是要在 spring应用上下文中将 实体管理器工厂 按照bean 的形式来进行配置;(干货——引入了实体管理器工厂)

【2.1】配置实体管理器工厂        
1)intro:基于JPA的应用程序需要使用 EntityManagerFactory的实现类来获取 EntityManager实例。JPA 定义了 两种类型的实体管理器:
type1)应用程序管理类型:当应用程序向实体管理器工厂直接请求实体管理器时,工厂会创建一个实体管理器。在这种模式下,程序要负责打开或关闭实体管理器并在事务中对其进行控制。这种方式的实体管理器适合于不运行在 java ee 容器中的独立应用程序;
type2)容器管理类型:实体管理器由java ee 创建和管理。应用程序根本不与实体管理器工程打交道。相反,实体管理器直接通过注入或JNDI 来获取。容器负责配置实体管理器工厂。这种类型的实体管理器最适用于 java ee 容器,在这种case下 会希望在  persistence.xml 指定的 JPA 配置之外保持一些自己对 JPA的控制;(干货——容器管理类型的实体管理器最适用于 java ee 容器)
2)以上两种实体管理器实现了同一个接口 EntityManager。关键的区别在于  EntityManager 的创建和管理方式。 应用程序管理类型的 EntityManager由 EntityManagerFactory 创建的,EntityManagerFactory 是由 PersistenceProvider.createEntityManagerFactory() 方法得到的;而 容器管理类型的 EntityManagerFactorys 是通过 PersistenceProvider.createContainerEntityManagerFactory()方法得到的;(干货——应用程序管理类型和容器管理类型的实体管理器的关键区别在于  EntityManager 的创建和管理方式)

3)这两种实体管理器工厂分别由对应的 spring 工厂 bean 创建:
type1)LocalEntityManagerFactoryBean: 生成应用程序管理类型的 EntityManagerFactory;
type2)LocalContainerEntityManagerFactoryBean: 生成容器管理类型的 EntityManagerFactory;

Attention)应用程序管理类型和容器管理类型的实体管理器工厂间唯一值得关注的区别是:在 spring 应用上下文中如何进行配置;

【2.1.1】配置应用程序管理类型的JPA
1)intro:对于应用程序管理类型的实体管理器工厂来说,它绝大部分配置信息来源于一个 名为 persistence.xml 的配置文件,这个文件必须位于 类路径下的 META-INF 目录下;
2)下面是一个典型的 persistence.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"version="1.0"><persistence-unit name="spitterPU"><class>com.habuma.spittr.domain.Spitter</class><class>com.habuma.spittr.domain.Spittle</class><properties><property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver" /><property name="toplink.jdbc.url"value="jdbc:hsqldb:hsql://localhost/spitter/spitter" /><property name="toplink.jdbc.user" value="sa" /><property name="toplink.jdbc.password" value="" /></properties></persistence-unit>
</persistence>
3)可以通过如下的 @Bean注解方法在spring中声明 LocalEntityManagerFactoryBean:


【2.1.2】使用容器管理类型的JPA
1)intro:容器管理的JPA 采取了一个不同的方式。当运行在容器中时,可以使用容器提供的信息来生成 EntityManagerFactory;
2)你可以将 数据源信息配置在 spring应用上下文中,而不是在 persistence.xml 中了。如下的@Bean 注解方法声明了在 spring中如何使用 LocalContainerEntityManagerFactoryBean 来配置容器管理类型的 JPA:

对以上代码的分析(Analysis): 
A1)这里,我们使用了 spring配置的数据源来设置 datasource属性。任何 javax.sql.DataSource 的实现都是可以的;
A2)jpaVendorApapter属性:用于指明所使用的是哪一个厂商的JPA 实现,spring提供了多个 JPA 厂商适配器:
adapter1)EclipseLinkJpaVendorAdapter
adapter2)HibernateJpaVendorAdapter
adapter3)OpenJpaVendorAdapter
adapter4)TopLinkJpaVendorAdapter (deprecated in Spring 3.1)

【2.1.3】从JNDI 获取实体管理器工厂
1)intro:如果将spring应用程序部署在应用server中, 则 EntityManagerFactory 可能已经被创建好了,并且位于 JNDI 中等待查询使用;
2)在这种case下,可以使用 spring jee 命名空间下的 <jee: jndi-lookup>元素来获取对 EntityManagerFactory 的引用:
<jee:jndi-lookup id="emf" jndi-name="persistence/spitterPU" />
3)可以使用 java Config 来获取 EntityManagerFactory :
@Bean
public JndiObjectFactoryBean entityManagerFactory() {}JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean();jndiObjectFB.setJndiName("jdbc/SpittrDS");return jndiObjectFB;
}
对以上代码的分析(Analysis): 因为上述方法返回的 JndiObjectFactoryBean 是 FactoryBean 接口的实现,它能够创建 EntityManagerFactory;
Attention)自此,我们就得到了 EntityManagerFactory 对象了;

【2.2】编写基于 JPA 的 Repository
1)intro:spring 对 JPA 集成也提供了JpaTemplate 模板以及对应的支持类 JpaDaoSupport;
2)鉴于纯粹的JPA 方式远远胜于基于模板的 JPA,所以在本节中我们将会重点关注如何构建不依赖spring 的 JPA Repository。如下程序中的 JpaSpitterRepository 展现了 如何开发不使用 spring JpaTemplate 的 JPA Repository;
@Repository
@Transactional
public class JpaSpitterRepository implements SpitterRepository {@PersistenceUnitprivate EntityManagerFactory emf;public void addSpitter(Spitter spitter) {emf.createEntityManager().persist(spitter);}public Spitter getSpitterById(long id) {return emf.createEntityManager().find(Spitter.class, id);}public void saveSpitter(Spitter spitter) {emf.createEntityManager().merge(spitter);}...
}
对以上代码的分析(Analysis):
A1)@PersistenceUnit注解:spring会将 EntityManagerFactory 注入到 Repository中;(干货——注解@PersistenceUnit的作用
A2)有了 EntityManagerFactory之后,JpaSpitterRepository 的方法就能够使用它来创建 EntityManager了,然后 EntityManager 可以针对数据库执行操作;
A3)JpaSpitterRepository 唯一的问题:在于每个方法都会调用createEntityManager()方法;

3)下面的程序展现了 如何借助 @PersistenceContext注解为 JpaSpitterRepository 设置 EntityManager;
@Repository
@Transactional
public class JpaSpitterRepository implements SpitterRepository {@PersistenceContextprivate EntityManager em;public void addSpitter(Spitter spitter) {em.persist(spitter);}public Spitter getSpitterById(long id) {return em.find(Spitter.class, id);}public void saveSpitter(Spitter spitter) {em.merge(spitter);}...
}
对以上代码的分析(Analysis):
A0)@Transactional注解的作用: 表明这个 Repository中的持久化方法是在事务上下文中执行的;(干货——@Transactional注解的作用
A1)由于没有使用模板类来处理异常,所以我们需要为 Repository添加 @Repository 注解,这样PersistenceAnnotationBeanPostProcessor 就会知道要将这个bean 产生 的异常转换为 spring 的统一数据访问异常;
A2)在上面的JpaSpitterRepository 中,直接为其设置了 EntityManager ;这样的话,每个方法中就没有必须再通过 EntityManagerFactory 创建 EntityManager了;(尽管这种方式非常便利,但你可能会担心注入的EntityManager 会有 线程安全问题)
A3)这里的真相是:@PersistenceContext 并不会真正注入 EntityManager;它没有将真正的 EntityManager 设置给 Repository,而是给了它一个 EntityManager 的代理;真正的EntityManager 是与当前事务相关联的那一个,如果不存在这样的 EntityManager 的话,就会创建一个新的。这样的话,我们就能始终以 线程安全的方式提供实体管理器了;

4)需要了解 @PersistenceUnit and @PersistenceContext 并不是spring 的注解,而是 JPA规范提供的。
4.1)为了让spring理解 这些注解,并注入 EntityManagerFactory or EntityManager,我们必须要配置 spring 的 PersistenceAnnotationBeanPostProcessor ;
4.2)如果你已经使用了 <context:annotation-config> or <context:component-scan>,那么你不必担心了,因为这些配置元素会自动注册 PersistenceAnnotationBeanPostProcessor bean;否则的话,我们就要显示地注入这个 bean;
@Bean
public PersistenceAnnotationBeanPostProcessor paPostProcessor() {return new PersistenceAnnotationBeanPostProcessor();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漫画:什么是数据仓库

转载自 玻璃猫 算法与数据结构一个故事 在很久很久以前&#xff0c;世界上生活着许多种族&#xff0c;有人类&#xff0c;有矮人&#xff0c;有精灵......他们有着不同的信仰&#xff0c;不同的文化&#xff0c;彼此相安无事。可是&#xff0c;有一个猥琐男却偏偏想要统治整个世…

SpringMVC_初级总结

1.SpringMVC的工作原理 浏览器发出一个http请求给服务器&#xff0c;如果匹配DispatcherServlet的请求映射路径&#xff08;在web.xml中指定&#xff09;&#xff0c;服务器将请求转交给DispatcherServlet.DipatcherServlet接收到这个请求之后&#xff0c;根据请求的路径&#…

tomcat中配置jndi数据源以便spring获取

【0】README0&#xff09;intro to jndi&#xff0c; plase visit intro to jndi&#xff1b;1&#xff09;本文译自 Configuring Spring MVC JdbcTemplate with JNDI Data Source in Tomcat&#xff1b;2&#xff09;本文旨在分析如何通过springmvc 获取 JNDI 数据源 以连接到…

Machine Learning:十大机器学习算法

转载自 Machine Learning&#xff1a;十大机器学习算法摘要: - 机器学习算法分类&#xff1a;监督学习、无监督学习、强化学习 - 基本的机器学习算法&#xff1a;线性回归、支持向量机(SVM)、最近邻居(KNN)、逻辑回归、决策树、k平均、随机森林、朴素贝叶斯、降维、梯度增强 机…

Java的值传递解析

值传递与引用传递 最近学基础的时候&#xff0c;老师讲了值传递和引用传递&#xff0c;这个问题一直不太明白&#xff0c;上网查了很多资料&#xff0c;按照自己的理解整理了一遍&#xff0c;发现之前不太明白的地方基本上想明白了&#xff0c;如有不正确的地方&#xff0c;欢…

spring(13)缓存数据

【0】README1&#xff09;本文部分文字描述转自&#xff1a;“Spring In Action&#xff08;中/英文版&#xff09;”&#xff0c;旨在review “spring(13)缓存数据” 的相关知识&#xff1b;2&#xff09;缓存&#xff1a;缓存可以存储经常会用到的信息&#xff0c;这样每次需…

漫画:什么是分布式事务

转载自 漫画&#xff1a;什么是分布式事务&#xff1f;————— 第二天 —————————————————假如没有分布式事务 在一系列微服务系统当中&#xff0c;假如不存在分布式事务&#xff0c;会发生什么呢&#xff1f;让我们以互联网中常用的交易业务为例子&#…

Spring4.2.6+SpringMVC4.2.6+MyBatis3.4.0 整合

【0】README0&#xff09;本文旨在 review Spring4.2.6SpringMVC4.2.6MyBatis3.4.0 整合过程&#xff1b;1&#xff09;项目整合所涉及的源代码&#xff0c;please visit https://github.com/pacosonTang/MyBatis/tree/master/spring4mvc_mybatis32&#xff09;由于晚辈我还不…

ibatis(0)ibatis 与 mybatis 简述

【0】README:1&#xff09;本文旨在给出 ibatis 与 mybatis 简述&#xff0c;简述内容转自 如下链接&#xff1b;【1】main contents1&#xff09;apache offical declarationhttp://ibatis.apache.org/.apache ibatis is retired at the apache software foundation (2010/06/…

Java面试大纲

转载自 金三银四跳槽季&#xff0c;Java面试大纲跳槽时时刻刻都在发生&#xff0c;但是我建议大家跳槽之前&#xff0c;先想清楚为什么要跳槽。切不可跟风&#xff0c;看到同事一个个都走了&#xff0c;自己也盲目的面试起来&#xff08;期间也没有准备充分&#xff09;&#x…

ibatis(1)ibatis的理念

【0】README1&#xff09;本文部分内容转自 “ibatis in action”&#xff0c;旨在 review “ibatis的理念” 的相关知识&#xff1b;【1】结合所有优秀思想的混合型解决方案在现实世界中&#xff0c;混合型解决方案随处可见。将两个看上去相悖的思想在中间处巧妙结合&#xff…

究竟啥才是互联网架构“高并发”

转载自 究竟啥才是互联网架构“高并发”一、什么是高并发 高并发&#xff08;High Concurrency&#xff09;是互联网分布式系统架构设计中必须考虑的因素之一&#xff0c;它通常是指&#xff0c;通过设计保证系统能够同时并行处理很多请求。高并发相关常用的一些指标有响应时间…

ibatis(2)ibatis是什么

【0】README1&#xff09;本文部分内容转自 “ibatis in action”&#xff0c;旨在 review “ibatis是什么” 的相关知识&#xff1b;2&#xff09;intro to ibatis&#xff1a; ibatis 就是数据映射器&#xff0c;Martin Fowler在《企业应用架构模式》中&#xff0c;对 data m…

究竟啥才是互联网架构“高可用”

转载自 究竟啥才是互联网架构“高可用”一、什么是高可用 高可用HA&#xff08;High Availability&#xff09;是分布式系统架构设计中必须考虑的因素之一&#xff0c;它通常是指&#xff0c;通过设计减少系统不能提供服务的时间。 假设系统一直能够提供服务&#xff0c;我们说…

maven(3)maven3.3.9使用入门

【0】README1&#xff09;maven 安装step1&#xff09;检查 jdk 是否安装且 环境变量 JAVA_HOME 是否设置&#xff1b;step2&#xff09;download maven&#xff1a; https://maven.apache.org/download.cgi?Preferredftp://mirror.reverse.net/pub/apache/step3&#xff09;…

TCP接入层的负载均衡、高可用、扩展性架构

转载自 TCP接入层的负载均衡、高可用、扩展性架构 一、web-server的负载均衡 互联网架构中&#xff0c;web-server接入一般使用nginx来做反向代理&#xff0c;实施负载均衡。整个架构分三层&#xff1a; 上游调用层&#xff0c;一般是browser或者APP 中间反向代理层&#xff…

使用poi统计工作职责

1 创建一个新的sheet工作页 Sheet job workbook.createSheet("工作职责统计"); 2 查询工作职责问题选项列表&#xff0c;并设置第一行倒出时间 List<Syslistconfig> listconfigs syslistconfigDao.listConfig(29); //工作职责问题选项列表job.createRow(0)…

漫画:什么是字典序算法

转载自 漫画&#xff1a;什么是字典序算法&#xff1f;算法题目&#xff1a; 给定一个正整数&#xff0c;实现一个方法来求出离该整数最近的大于自身的“换位数”。 什么是换位数呢&#xff1f;就是把一个整数各个数位的数字进行全排列&#xff0c;从而得到新的整数。例如53241…

mybatis_user_guide(2)mybatis3.4.0快速入门

【0】README0&#xff09;以下部分内容转自&#xff1a;“mybatis v.3.4.0 User Guide”&#xff1b;1&#xff09;本文旨在梳理 如何 构建 mybatis 环境&#xff0c;与 db 连接&#xff0c;且采用 JUnit 搭建其测试用例&#xff1b;2&#xff09;本文的环境配置都是基于纯 my…

jQuery中的几个案例:隔行变色、复选框全选和全不选

1 表格隔行变色 1 技术分析&#xff1a; 1 &#xff09;基本过滤选择器&#xff1a; odd: even: 2 &#xff09;jq添加和移除样式&#xff1a; addClass(); removeClass(); 2 代码实现 <script src"js/jquery1.11.3/jquery.min.js" type"text/javasc…