经典JavaEE课程段鹏松第10章Java持久化API(JPA)理解ORM的基本概念理解实体的基本概念掌握实体的基本映射掌握实体的关联关系映射掌握实体的生命周期规律课程目标概述•J2EE时代,使用EntityBean规范来解决应用程序的持久化问题;•JavaEE5规范使用JPA作为持久化解决方案;•Sun公司的JPA以Entity为核心,它将实体映射到底层数据表,然后通过在应用程序中使用EntityManager来操作Entity,而JPA实现则会将这种操作转换为对底层数据表的操作。•JPA只是一种规范,其自身并不提供实现,开发者需指定JPA的实现。目录•实体介绍•实体入门•理解实体•实体的基本映射•关联关系映射•继承关系映射•使用抽象实体和非实体父类•实体的生命周期和监听器ORM的概念•ORM:Object/RelationMapping,对象关系映射。•ORM的基本思想:完成面向对象的编程语言到关系数据库的映射(一般是双向的)。•ORM出现的原因:解决面向对象编程语言和关系型数据库操作时的不匹配问题。•ORM的未来:随着面向对象数据库的出现,ORM工具会自动消亡,但短期内不会。ORM的概念JPA概述•JPA实现作用:把对实体的操作,转换成对数据库的操作。•JPA规范本质上就是一种ORM规范。但JPA并未提供ORM实现,它只是指定了一些规范,提供了一些编程的API,具体实现由应用服务器厂商来提供。JPA概述数据库HibernateTopLink其他ORM框架...应用程序JPA规范JPA实现JPA的映射规则•数据表映射实体类–把表结构映射为实体类类型•数据表的行映射实体类对象–把数据表的行记录映射到实体对象•数据表的列映射实体的属性–字段映射为实体类的属性JPA规范简介•JPA并不属于EJB3的范畴,它是一套完全独立的规范。JPA不仅可以在JavaEE中使用,也可以在JavaSE中使用。•JPA的常用组件:–实体–EntityManager•类似Hibernate中的session–JPQL•类似HQL目录•实体介绍•实体入门•理解实体•实体的基本映射•关联关系映射•继承关系映射•使用抽象实体和非实体父类•实体的生命周期和监听器开发实体•JPA管理的实体类就是一个POJO类,再在实体类上添加一些Annotation。Annotation定义了POJO类和底层数据表之间的映射关系。@+=POJOannotationEntityJPA的实现•目前主流的JPA实现有如下几种:–HibernateJPA实现–TopLinkJPA实现–OpenJPA实现•不同的JPA实现主要通过persistence.xml文件的配置信息来区分在JavaSE环境下使用HibernateJPA实现•为了在JavaSE应用程序中使用HibernateJPA实现,必须先下载和安装HibernateJPA实现。•实际操作演示在JavaSE环境下使用TopLinkJPA实现•JavaEE5、GlassFish应用服务器都已经内置了TopLinkJPA实现。•实际操作演示在JavaSE环境下使用EntityManager•使用EntityManager的情形:–在EJB中使用EntityManager–在Servlet、JSF的托管Bean中使用EntityManager–在JavaSE应用中使用EntityManager在JavaSE环境下使用EntityManager•创建EntityManager的步骤:–使用javax.persistence.Persistence工厂类提供的静态方法createEntityManagerFactory()–使用EntityManagerFactory的createEntityManager()或createEntityManager(Mapmap)•实际操作演示运行结果Hibernate和JPA的关系•JPA是一个规范,Hibernate是对JPA规范的一种实现;•JPA也可以用其他的实现,如TopLink等•Hibernate也有自己的实现类。•JPA出现原因–简化现有JavaEE和JavaSE应用的对象持久化的开发工作–Sun希望整合对ORM技术,实现持久化领域的统一EntityManager的方法•persist():保存实体到数据库•merger():合并实体•remove():删除实体•find(...):查找实体•flush():同步数据库•refresh():刷新实体•others...JAP的配置方式•JPA的配置方式–anntotation–xml•推荐使用annotation•实际操作演示目录•实体介绍•实体入门•理解实体•实体的基本映射•关联关系映射•继承关系映射•使用抽象实体和非实体父类•实体的生命周期和监听器持久化上下文和持久化单元•持久化上下文是一组处于托管状态下实体所组成的集合,它处于EntityManager的管理之下。•应用程序可以通过EntityManager与持久化上下文交互。•持久化单元由persistence.xml文件定义,使用persistence-uint标签定义。•不论任何类型的应用程序(JavaSE、EJB、WAR等),perisistence.xml文件都应该放在META-INF文件夹下面。实体类的要求•提供一个无参数的构造器•提供一个标识属性•为实体类的每个属性提供setter和getter方法•使用非final的类•重写equals()和hashCode()方法实体的状态•新建(new)–在new操作之后•托管(managed)–被EntityManager所管理,和数据库操作同步•脱管(detached)–与之管理的EntityManager关闭,断开和数据库的连接•被删除(removed)–调用EntityManager的remove()方法之后实体的状态新建托管脱管被删除结束开始new垃圾回收remove()垃圾回收persist()close()clear()find()getReference()管理实体的方法•持久化实体–使用persist()方法•根据逐渐加载实体–使用find()方法•更新实体–使用实体类的setXXX()方法–在提交事务之前•实际操作演示管理实体的方法•合并实体–使用merge()方法•删除实体–使用remove()方法•刷新实体–使用refresh()方法•实际操作演示目录•实体介绍•实体入门•理解实体•实体的基本映射•关联关系映射•继承关系映射•使用抽象实体和非实体父类•实体的生命周期和监听器映射实体类•对于各JPA实体类而言,通常可以采用如下两个annotation来修饰它–@Entity–@Table•catalog•name•schema•uniqueConstraint映射实体类的属性•@Column:映射属性到数据库,其支持的属性有:–inertbale–length–name–nullable–table–unique–updatable•@Transient:该属性不会映射到数据库•实际操作演示映射实体类的属性•@Enumerated:映射枚举类型的属性–EnumType•STRING:值•ORDINAL:编号•@Lob:修饰大数据类型–@Basic:可以指定延迟加载•fetch•optional•实际操作演示映射实体类的属性•@Temporal:修饰日期类型的属性–TemporalType•DATE•TIME•TIMESTAMP•实际操作演示将实体映射到多个表•如果一个实体的属性较多,可以把这个实体映射到多个数据库表中。•@Table•@SecondaryTable•@SecondaryTables•实际操作演示映射复合类型的属性•@Embedded:映射复合类型属性•@Embeddable:修饰作为复合类型的自定义类•实际操作演示映射实体类的主键•数据库的主键一般设置为自增长的,可以是数字类型,也可以是字符类型,或者是复合类型。•JPA中的单一主键使用@Id修饰。@Id的属性有:•strategy•generator•JPA的复合主键使用@IdClass和多个@Id等来修饰。•实际操作演示目录•实体介绍•实体入门•理解实体•实体的基本映射•关联关系映射•继承关系映射•使用抽象实体和非实体父类•实体的生命周期和监听器关联关系概述•关联关系的概念:实例之间的互相关联•关联关系的分类–单向关联•单向1-1,单向1-N,单向N-1,单向N-N–双向关联•双向1-1,双向1-N,双向N-N单向N-1关联•只能从N的一端访问1的一端–通过在N的一端引用1的一端来实现–需要在N的一端定义1的一端的setter和getter•使用的annotation:–@ManyToOne•cascade,fetch,optional,targetEntity–@JoinColumn•columnDefinition,name等•实际操作演示单向1-1关联•只能从1的一端访问另一端的1–通过在1的一端引用1的一端来实现–需要在1的一端定义1的另一端的setter和getter•使用的annotation:–@OneToOne•cascade,fetch,mappedBy,optional,targetEntity–@JoinColumn•columnDefinition,name等•实际操作演示单向1-N关联•只能从1的一端访问N的一端–通过在1的一端引用N端来实现–需要在1的一端定义N端的setter和getter–N端在1端以通常以Set类型出现•使用的annotation:–@OneToMany•cascade,fetch,mappedBy,optional,targetEntity–@JoinColumn•columnDefinition,name等•实际操作演示单向N-N关联•只能从N的一端访问另一端的N–需要在N的一端定义N的另一端的setter和getter–控制端需要添加一个Set集合属性,该Set集合记录了当前实体的所有关联实体•使用的annotation:–@ManyToMany•cascade,fetch,mappedBy,targetEntity–@JoinTable•name,catalog,schema等•实际操作演示双向1-1关联•可以从任意端访问对端–需要让两端都增加对方的引用–需要让两端都定义对端的setter和getter–底层数据库可以在任意一端增加外键•使用的annotation:–@OneToOne•cascade,fetch,targetEntity–@JoinColumn•name,nullable,schema等•实际操作演示双向1-N关联•可以从任意端访问对端–需要让两端都增加对方的引用–需要让两端都定义对端的setter和getter–实际项目中尽量使用双向1-N•使用的annotation:–@OneToMany(1端)–@ManyToOne(N端)–@JoinColumn(N端)•实际操作演示双向N-N关联•可以从任意端访问对端–需要让两端都增加对方的引用–需要让两端都定义对端的setter和getter–实际项目中尽量避免使用双向N-N•使用的annotation:–@ManyToMany•cascade,fetch,targetEntity–@JoinTable•name,nullable,schema等•实际操作演示使用Map集合记录关联实体•JPA允许使用Map集合来记录关联实体。•当使用Map集合来记录关联实体时,Map集合的Key类型通常是关联实体的主键类型。•使用的annotation:–@OneToMany–@MapKey•实际操作演示对关联实体进行排序•使用的annotation:–@OrderBy•指定排序规则•例如:@OrderBy(“属性名ASC”)–通常和@OneToMany,@ManytoMany结合使用•实际操作演示目录