1、JPA理解及实现:
JPA(Java Persistence API)作为Java EE 5.0平台标准的ORM规范,将得到所有Java EE服务器的支持,是SUN在充分吸收现有ORM框架的基础上,得到了一个易于使用、伸缩性强的ORM规范。JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。
因为JPA是一个公开的规范,当前有不同的实现。Hibernate 3.2、TopLink 10.1.3以及OpenJpa都提供了对JPA的实现。
2. 具有ORM元数据的领域对象称为实体(Entity),按JPA的规范,实体具备以下的条件:
1)必须使用javax.persistence.Entity注解或者在XML映射文件中有对应的元素;
2)必须具有一个不带参的构造函数,类不能声明为final,方法和需要持久化的属性也不能声明为final;
3)如果游离状的实体对象需要以值的方式进行传递,如通Session bean的远程业务接口传递,则必须实现Serializable接口;
4)需要持久化的属性,其访问修饰符不能是public,它们必须通过实体类方法进行访问。
参看博文: https://www.xuebuyuan.com/3247788.html
3.常用注解:
1)@Entity:将领域对象标注为一个实体,表示需要保存到数据库中,默认情况下类名即为表名,通过name属性显式指定表名,如name = "T_TOPIC",表示Topic保存到T_TOPIC表中;
备注:该实体类必须实现Serializable接口
2)@Table,这里通过它来设定对应的数据库表名字是什么
3)@Id则表示对应表的主键。默认情况下,
4)@Column这个用来设定对应的数据库字段名
5)@GeneratedValue(strategy = GenerationType.IDENTITY) 它表示这个主键的值可以自动来生成,而后面的GenerationType.IDENTITY表明它的生成方式是自动增长,类似于auto increment。JPA自动选择一个最适合底层数据库的主键生成策略。
在javax.persistence.GenerationType中定义了以下几种可供选择的策略:
a. IDENTITY:表自增键字段,Oracle不支持这种方式;
b. AUTO: JPA自动选择合适的策略,是默认选项;
c. SEQUENCE:通过序列产生主键,通过@SequenceGenerator注解指定序列名,MySql不支持这种方式;
d. TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。
备注:不同的JPA实现商生成的表名是不同的:如 OpenJPA生成openjpa_sequence_table表Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表。这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT。
6)@Temporal(TemporalType.DATE):
如果属性是时间类型,因为数据表对时间类型有更严格的划分,所以必须指定具体时间类型。在javax.persistence.TemporalType枚举中定义了3种时间类型:
a. DATE :等于java.sql.Date
b. TIME :等于java.sql.Time
c. TIMESTAMP :等于java.sql.Timestamp
7)继承关系
Topic和PollTopic是父子类,JPA 采用多种方法来支持实体继承。在父类中必须声明继承实体的映射策略。对于继承的实体,在javax.persistence.InheritanceType定义了3种映射策略:
a.SINGLE_TABLE:父子类都保存到同一个表中,通过字段值进行区分。这是我们Topic实体所采用的策略,Topic和PollTopic都保存到同一张表中,通过TOPIC_TYPE字段进行区分,Topic在T_TOPIC表中对应TOPIC_TYPE= 1的记录,而PollTopic对应TOPIC_TYPE=2的记录(稍后在PollTopic实体中指定);区别的字段通过 @DiscriminatorColumn 说明,区分字段对应该实体的值通过@DiscriminatorValue 指定;
示列:
@DiscriminatorColumn(name = "TOPIC_TYPE", discriminatorType =DiscriminatorType.INTEGER, length = 1)
@DiscriminatorValue(value="1")
b.TABLE_PER_CLASS:每一个类对应自己的表,一般不推荐采用这种方式。父子类相同的部分保存在同一个表中,不同的部分分开存放,通过表连接获取完整数据
8)关联关系
JPA规范规定任何属性都默认映射到表中,所以虽然我们没有给multiple属性提供注解信息,但JPA将按照默认的规则对该字段进行映射:字段名和属性名相同,类型相同。如果我们不希望将某个属性持久化到数据表中,则可以通过 @Transient 注解显式指定: @Transient
a. 一对一级联关系:
@OneToOne 表示他们是一对一的关系;
cascade表示他们的级联关系
@JoinColumn里面指定了Employee表里引用到Address时关联的名字是什么。
Address对象只是设定为employee对象的一个属性。我们希望是employee对象被保存到数据库里的时候address对象也自动保存进去。那么我们就需要设定这个cascade的级联访问属性。
否则我们就需要显式的利用em.persist()来保存address对象。这也就是为什么我们要用一个cascade的属性。
示列:单独的映射 address_id字段
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="address_id")
private Address address;
映射整张表
@OneToOne(cascade=CascadeType.ALL)
@JoinTable(name="employee_address",[email protected](name="address_id"),[email protected](name="employee_id"))
private Address address;
c. 一对多的关联关系:@OneToMany的映射关系
d. 多对多的映射:@ManyToMany
9)Lob字段:在JPA中Lob类型类型的持久化很简单,仅需要通过特殊的Lob注解就可以达到目的。下面,我们对Post中的Lob属性类型进行标注:
Java代码 收藏代码
@Lob
@Basic(fetch = FetchType.EAGER)
@Column(name = "POST_TEXT", columnDefinition = "LONGTEXT NOT NULL")
private String postText;
postText属性对应T_POST表的POST_TEXT字段,该字段的类型是LONTTEXT,并且非空。
JPA 通过@Lob将属性标注为Lob类型,通过@Basic指定Lob类型数据的获取策略,FetchType.EAGER表示非延迟加载,而FetchType. LAZY表示延迟加载通过@Column的columnDefinition属性指定数据表对应的Lob字段类型
参看文章:
https://www.jianshu.com/p/38d247f02724
https://www.iteye.com/blog/shmilyaw-hotmail-com-1969190
https://cloud.tencent.com/developer/article/1028104
英文单词:Embedded 嵌入; embeddable 可嵌入的; discriminator 辨别者
原文地址:https://www.cnblogs.com/jiarui-zjb/p/12219227.html