您的位置 首页 java

spring data jpa 100 steps 3rd:实体定义

前面第一篇介绍了常见 orm 框架,第二篇介绍了 spring-jpa 概念和配置,本文会介绍具体 jpa 的使用。

定义实体类

我们先定义实体类 Customer

Customer 类添加的 @Entity 标注表明 Customer 对象将会成为被 JPA 管理的实体;id 属性上的 @Id 和 @GeneratedValue(strategy=GenerationType.AUTO) 标注表明 id 是一个自增的 主键

通过定义的实体,jpa 就能够自动生成创建 Schema 的 DDL,它们将会在应用启动时初始化数据库,这个可以通过配置 spring.jpa.generate-ddl = false 来关闭,关于 spring.jpa 的配置,更过的可以看 JpaProperties 类:

然后在 JpaBaseConfiguration 中会去使用这些个配置:

我们可以看到 spring.jpa.generate-ddl 的配置是在 JpaVendorAdapter 中使用,那 JpaVendorAdapter 作用是什么呢?

jpaVendorAdapter:用于设置 JPA 实现厂商的特定属性,如设置 hibernate 的是否自动生成 DDL 的属性 generateDdl,这些属性是厂商特定的,因此最好在这里设置。目前 spring 提供 Hibernate JpaVendorAdapter,OpenJpaVendorAdapter,EclipseJpaVendorAdapter,TopLinkJpaVenderAdapter 四个实现。其中最主要的属性是 “database”,用来指定使用的数据库类型。从而根据数据库类型决定如何将数据库特定异常转换为 Spring 一致性异常。目前支持以下数据库:DB2,DERBY,H2,H sql , INFORMIX , MySQL ,ORACLE,POSTGRESQL,SQL_SERVER,SYBASE.

如果使用 Hibernate 作为 JPA 的实现,spring.jpa.hibernate.ddl-auto 给出了一种更加细粒度的配置方式,其中包括以下几种取值:

  • none:如果是非内嵌数据库,默认为 none,即做任何 DDL 操作

  • validate:验证数据库 Schema 是否和实体类一致

  • update:更新数据库 Schema

  • create:创建数据库 Schema

  • create-drop:如果是内嵌数据库(hsqldb、h2 和 derby),则会默认设置为这个选项;应用结束后会删除 Schema

在实际生产环境中,一般不会使用内嵌数据库,因此不用专门配置,即默认为 none 即可。数据库 DDL 通常是通过类似 Mybatis Migration 和 Flyway 等数据库版本管理工具来维护的。

下面介绍一些常用的注释。

@Entity 和 @Table

@Entity 标注用于实体类,表明该 Java 类为实体类,将映射到指定的数据库表。

当实体类与其映射的数据库表名不同名时,需要使用 @Table 标注说明。@Table 标注与 @Entity 标注一同使用,置于实体类声明语句之前。

@Table 标注的常用属性是 name,用于指明数据库的表名。

@Id 和 @GeneratedValue

@Id 标注应用于实体类的属性或者属性对应的 getter 方法,表示该属性映射为数据库表的主键。

@GeneratedValue 与 @Id 一同使用,表示主键的生成策略,通过 strategy 属性指定。

在 javax.persistence.GenerationType 中定义了以下几种可供选择的策略:

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

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

  • SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 标注指定序列名,MySQL 不支持这种方式。

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

@Basic

@Basic 表示属性到数据库表的字段的映射。一个 @Entity 标注的实体类中的属性,如果没有任何标注,默认即为 @Basic,比如 Customer 类中的 firstName 和 lastName 属性。

@Basic 有两个常用属性:

  • fetch: 表示实体类对应属性的读取策略,有 EAGER 和 LAZY 两种取值,分别表示主动抓取和延迟加载,默认值为 EAGER。

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

比如 customer 表的 lastName 字段不能为空,可以如下设置:

@Column

当实体类的属性与其映射的数据库表的列名称不同时,可以使用 @Colunm 标注。该标注描述了数据库表中该字段的详细定义,包含以下属性:

  • name:表示数据库表中该字段的名称,默认情形属性名称一致。

  • nullable:表示该字段是否允许为 null,默认为 true。

  • unique:表示该字段是否是唯一标识,默认为 false。

  • length:表示该字段的大小,仅对 String 类型的字段有效。

  • insertable:表示在 ORM 框架执行插入操作时,该字段是否应出现 INSETRT 语句中,默认为 true。

  • updateable:表示在 ORM 框架执行更新操作时,该字段是否应该出现在 UPDATE 语句中,默认为 true。对于一经创建就不能更改的字段,该属性非常有用,比如 email 属性。

  • columnDefinition:表示该字段在数据库中的实际类型。通常 ORM 框架可以根据属性类型自动判断数据库中字段的类型,但是依然有些例外:

  • Date 类型无法确定数据库中字段类型究竟是 DATE、TIME 还是 TIMESTAMP

  • String 的默认映射类型为 VARCHAR,如果希望将 String 类型映射到特定数据库的 Blob 或 TEXT 字段类型,则需要进行设置

@Transient

@Transient 表示该属性并非一个到数据库表的字段的映射,JPA 将忽略该属性。

如果一个属性并非数据库表的字段映射,就务必将其标注为 @Transient,否则 JPA 默认其注解为 @Basic。

@Temporal

在数据库中,表示时间类型的数据有 DATE,TIME,和 TIMESTAMP 三种精度 (即单纯的日期,时间,或者两者兼备)。 可使用 @Temporal 来设置 Date 类型的属性映射到对应精度的字段。

  • @Temporal(TemporalType.DATE) 映射为日期 // date (只有日期)

  • @Temporal(TemporalType.TIME) 映射为日期 // time (是有时间)

  • @Temporal(TemporalType.TIMESTAMP) 映射为日期 // date time (日期 + 时间)

@Lob

@Lob 标注表示将属性映射成数据库支持的大对象类型,Clob 或者 Blog。其中:

  • Clob(Character Large Ojects)类型是长字符串类型,java.sql.Clob、Character[]、char[] 和 String 将被映射为 Clob 类型。

  • Blob(Binary Large Objects)类型是字节类型,java.sql.Blob、Byte[]、byte[] 和 实现了 Serializable 接口的类型将被映射为 Blob 类型。

    因为这两种类型的数据一般占用的内存空间比较大,所以通常使用延迟加载的方式,与 @Basic 标注同时使用,设置加载方式为 FetchType.LAZY。

一般情况下并不需要太多的设置,其默认行为足以处理大部分场景,这也是约定大于配置的原则。

可置于属性的标注都能置于对应的 getter,一般情况下应该在整个项目中使用其中一种方式,而不能混用。

更多 Entity 的标注,参考 Hibernate 文档

参考自 Spring Data JPA 实战入门训练。

这是 jpa 的第三篇,你的鼓励是我继续写下去的动力,期待我们共同进步。

文章来源:智云一二三科技

文章标题:spring data jpa 100 steps 3rd:实体定义

文章地址:https://www.zhihuclub.com/177148.shtml

关于作者: 智云科技

热门文章

网站地图