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

JPA

东神殿下 2021-09-16
523
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK5.0注解或xml描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Sun引入新的JAP ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发的工作;其二,Sun希望整合ORM技术,实现天下归一


优势
标准化

JPA是JCP组织发布的Java EE标准之一,因此任何声称符合JPA标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JAP开发的企业应用能够经过少量的修改就能够在不同JAP框架下运行。


容器级特性的支持

JPA框架中支持大数据集、事务、并发等容器级事务,这使得JPA超越了简单持久化框架的局限,在企业应用发挥更大的的作用。


简单方便

JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java类一样简单,没有任何的约束和限制,只需要使用javax.persistence.Entity进行注释,JAP的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易地掌握,JPA基于非侵入式原则设计,因此可以很容易地和其他框架或者容器集成。



JPA注解

@Entity:标注用于实体类声明语句之前,指出该Java类为实体类,将映射到指定的关系数据表。(类似的,使用@Document可以映射到mongodb)

应用了此注解后,将会自动将类名映射作为数据库表名、将类内的字段名映射为数据库表的列明。映射策略默认是按驼峰命名法拆分将类名和字段名拆分成多部分,然后以下划线连接,如StudentEntity ->student_entity、studentName -> student_name。若不按默认映射,则可通过@Table、@Column指定

@Table:当实体类与其映射的数据库表明不同名时需要使用@Table标注说明,该标注于@Entity标注并列使用

  • schema属性:指定数据库名

  • name属性:指定表明,不知道时 表明为类名


@Id:标注用于声明一个实体类的属性映射为数据库的一个主键列

@Id标注也可置于属性的getter方法之前。

指定联合主键,有@IdClass、@Embeddedld两种方法。

@IdClass:修饰在实体类上,指定联合主键。如:@IdClass(StudentExperimentEntityPK.class),主键类StudentExperimentEntityPK需要满足:

  1. 实现Serializable接口

  2. 有默认的public无参数的构造方法

重写equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。hashCode方法返回当前对象的哈希码




@Embeddedld:功能与@IdClass一样用于指定联合主键。不同的在于其是修饰实体内的一个主键类变量,且主键类应该被@Embeddable修饰。

此外在主键类内指定的字段在实体类内可以不再指定,若再指定则需为@Column加上insertable = false, updatable = false属性

@GeneratedValue:用于标注主键的生成策略,通过strategy属性指定。默认情况下,JPA自动选择一个最合适底层数据库的主键生成策略:SqlServer对应identity ,Mysql对应aotu increment

  • IDENTITY:采用数据库ID自增长的方式自增主键字段,Oracle不支持这种方式

  • AUTO:JPA自动选择合适的策略,是默认选项

  • TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。

  • SEQUENCE:通过序列产生主键,通过@SqquenceGenerator注解指定序列名,Mysql不支持这种方式


    @Basic:表示一个简单的属性到数据表的字段的映射,对于没有任何标注的getXxx()方法,默认为@Basic

    fetch表示属性的读取策略,有EAGER和LAZY两种,分别为立即加载和延迟加载

    optional表示该属性是否允许为null,默认为true


@Column:当实体的属性与其映射的数据库表的列不同名时需要使用@Column标注说明,其有属性name、unique、nullable、length等。类的字段名在数据库中对应的字段名可以通过此注解的name属性指定,不指定则默认为将属性名按驼峰命名法拆分并以下划线连接,如createTime对应create_time。注意:即使name的值中包含大写字母,对应到db后也会转成小写,如@Column(name="create_Time")在数据库中字段名仍为create_time。


@Transient:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性,如果一个属性并非数据库表的字段映射,就务必将其标识为@Transient,否则ORM框架默认为其注解@Basic,例如工具方法不需要映射


@Temporal:在JavaAPI中没有定义Date类型的精度,而在数据库中表示Date类型的数据类型有Date,Time,TimeStamp三种精度(日期,时间,两者兼具),进行属性映射的时候可以使用@Temporal注解调整精度。目前此注解只能用于修饰java.util.Date、java.util.Calandar类型的变量。


@MappedSuperClass:用来修饰一个类,类中声明了各Entity共有的字段,也即数据库中多表中共用的字段,如create_time、update_time、id等。

标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。

标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。

允许多级继承


@Inheritance:用于表结构复用。指定被该注解修饰的类被子类继承后子类和父类的表结构关系。通过stategy属性指定关系,有三种策略:

  1. SINGLE_TABLE:适用于共同字段多独有字段少的关联关系定义。子类和父类对应同一个表且所有字段在一个表中,还会自动生成(也可通过@DiscriminatorColumn指定)一个字段 varchar 'dtype' 用来表示一条数据是属于哪个实体的。为默认值(未使用@Inheritance或使用了但没指定strategy属性时默认采用此策略)。

  2. JOINED:子类和父类对应不同表,父类属性对应的列(除了主键)不会且无法再出现在子表中。子表自动产生与父表主键对应的外键与父表关联。同样地也可通过@DiscriminatorColumn为父类指定一个字段用于标识一条记录属于哪个子类。

  3. TABLE_PER_CLASS:子类和父类对应不同表且各类自己的所有字段(包括继承的)分别都出现在各自的表中;表间没有任何外键关联。此策略最终效果与@MappedSuperClass等同。




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

评论