Spring Boot --- Spring Data: Spring Data JPA-ORM


Java Persistence API(JPA)定义了一种规范,可以将常规的普通Java类(有时被称作POJO)映射到数据库.这些Java类被称作Entity Bean.
除了是用Java Persistence元数据将其映射到数据库外,Entity Bean与其他Java类没有任何区别:创建一个Entity Bean对象相当于数据库新建一条记录;删除一个Entity Bean会同时从数据库中删除对应记录;修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步。
而POJO与数据库表之间的映射,称为ORM(Object Relational Mapping, 对象关系映射)

注解

@Entity

@Entity声明这个类是Entity Bean,并且使用默认的ORM规则,即class名即数据库表中表名,class字段名即表中的字段名.
映射规则:
1. 映射的表名为: @Table.name > @Entity.name > Class类名
2. 必须使用@Id来注解一个主键
3. 必须拥有一个publich或者protected的无参构造函数
4. 实体类必须是一个顶级类(top-level class),枚举(enum)或接口(interface)不能注解为实体类
5. 实体类不能是final,也不能有final方法
6. 实体类需要用传值的方式调用(例如远程调用),则这个实体类必须实现 java.io.Serializable接口

@Table

@Table@Entity标注的类进行详细设定.
属性:

属性名 作用
name 表名,默认”“时值为@Entity.name,若@Entity.name也为”“,则为Class类名
catalog 数据库catalog
schema 数据库schema
uniqueConstraints 定义一个UniqueConstraint数组,指定需要建立唯一约束的列
indexes 建立索引

- uniqueConstraints

@Entity
@Table(uniqueConstraints={
        @UniqueConstraint(name="uq_name", columnNames="name"),
        @UniqueConstraint(name="uq_nick_name", columnNames="nickName")
})
public class User extends AbstractEntity  {
    private static final long serialVersionUID = 1L;
    @Column
    private String name;    
    @Column
    private String nickName;
}

建立了两个唯一约束,等同于

alter table user add constraint uq_name unique (name)
alter table user add constraint uq_nick_name unique (nick_name)

也可以建立多列组合唯一约束

@Table(uniqueConstraints={
    @UniqueConstraint(name="uq_name", columnNames={"name","nickName"})
})

等同于

alter table user add constraint uq_name unique (name, nick_name)
  • indexes
@Entity
@Table(indexes={
    @Index(name="index1",unique=true,columnList="name")
})
public class User extends AbstractEntity  {
    ....
}
alter table user add constraint index1 unique (name)

@Id

声明Entity Bean的主键

@GeneratedValue

设置主键的生成策略

属性名 作用
strategy 主键生成策略

strategy

可选值 说明
TABLE
SEQUENCE
IDENTITY 以id自增序列增长,主要用于mysql,oracle无法使用
AUTO 默认值

@Column

设置字段与列的映射

属性:

属性名 作用
name (可选) 列名,默认为属性名或字段名
unique (可选)该列是否为唯一值.当与@Table的uniqueConstraint注解了同一个字段时,该注解的优先级更高
nullable (可选)该列是否可空
insertable (可选) 该列是否可作为sql的insert语句
updatable (可选)该列是否可作为sql的update语句
columnDefinition 该列为生成DDL时使用的SQL片段 默认为生成的sql创建一个推断类型的列
table 包含该列的表的名称,如果没有该列,则假定该列位于主表中
length 列的长度(只有使用了字符串类型的列才应用该属性)
precision 小数(精确数字)列的精度(仅使用小数列时才适用).在生成DDL时,必须由开发人员设置值
scale 十进(精确数字)制列的精度(仅使用小数列时才适用)

@OrderBy

@OneToOne

一对一映射策略, 用于实体类中的对象属性
属性:

属性名 作用 类型
cascade 指定级联操作的行为(可多选)
fetch 懒加载
optional
mappedBy
orphanRemoval
targetEntity

cascade

指定级联操作的行为(可多选)

  • CascadeType.PERSIST 级联新增(又称级联保存)
    获取A对象里也同时也重新获取最新的B时的对象。即会重新查询数据库里的最新数据,并且,只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态),对应EntityManager的presist方法,调用JPA规范中的persist(),不适用于Hibernate的save()方法

  • CascadeType.MERGE 级联合并(又称级联更新)
    指A类新增或者变化,会级联B对象(新增或者变化) ,对应EntityManager的merge方法,调用JPA规范中merge()时,不适用于Hibernate的update()方法

  • CascadeType.REMOVE 级联删除
    只有A类删除时,会级联删除B类,即在设置的那一端进行删除时,另一端才会级联删除,对应EntityManager的remove方法,调用JPA规范中的remove()时,适用于Hibernate的delete()方法

  • CascadeType.REFRESH 级联刷新
    获取order(一或多)对象里也同时也重新获取最新的items(多)的对象,对应EntityManager的refresh(object),调用JPA规范中的refresh()时,适用于Hibernate的flush()方法

  • CascadeType.ALL
    包含所有持久化方法

fetch

指定数据加载方式(是否懒加载)

  • FetchType.LAZY 懒加载
    默认不加载关联的对象,当使用时才生成语句进行查询(需要保证使用时仍处于DataSource Session周期中)

  • FetchType.EAGER 积极加载
    直接进行外键关联加载数据

optional

mappedBy

orphanRemoval

targetEntity

@ManyToOne

多对一映射策略, 用于实体类中的对象属性。
属性:

属性名 作用 类型
cascade 指定级联操作的行为(可多选)
fetch 懒加载
optional
targetEntity

@OneToMany

一对多映射策略, 用于实体类中的列表,数组属性。
属性:

属性名 作用 类型
cascade 指定级联操作的行为(可多选)
fetch 懒加载
mappedBy
targetEntity
orphanRemoval

@ManyToMany

多对多映射策略, 用于实体类中的列表,数组属性。
属性:

属性名 作用 类型
cascade 指定级联操作的行为(可多选)
fetch 懒加载
mappedBy
targetEntity
mappedBy

@JoinColumn

外键映射策略的属性的的映射规则

@JoinTable

@Transient

忽略该属性不做映射

@Embeddable

嵌入式类,当类使用该注解时,类中的属性将作为为所属类的属性转化

@Temporal

做日期类型转换

@Lob

声明字段为Clob或Blob

关系映射模型

一对一

一对一映射包含4种映射方式

  1. 单向外键关联
  2. 双向外键关联
  3. 单向主键关联
  4. 双向主键关联

    • 主键关联: 使用主键关联.不需要额外设置唯一性约束.主键默认唯一性
    • 外键关联: 使用外键关联,需要额外设置外键的唯一性约束.否则将无法保证为一对一.但换个角度来说,如果需要将一对一映射转变为一对多,只需要将外键的唯一性约束去掉即可
    • 单向关联
    • 双向关联

单向外键关联

单向外键一对一关联,即A表中有指向B表主键的外键,且外键为unique(若非unique,则将成为一对多关联)
单向外键一对一关联

@Data
@Entity
@Table
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToOne
    private Address address;
}
@Data
@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String city;
}

双向外键关联

双向外键一对一关联,即A表中有指向B表主键的外键,B表中也有指向A表主键的外键, 且外键均为unique(若非unique,则将变成一对多关联)
双向外键一对一关联

@Data
@Entity
@Table
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToOne
    private Address address;
}
@Data
@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String city;
    @OneToOne
    private User user;
}

单向主键关联

单向主键关联。 即A类的主键必须是B的主键。

双向主键关联

双向主键关联. 即A类与B类主键相等

多对一

外键关联

一对一外键关联的基础上, 取消外键的唯一性约束,即可形成一对多关联.
多对一关联是对于外键所在类而言的. 即
多对一外键关联

@Data
@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String city;
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}

第三表关联

多对一在默认情况下(不使用@JoinColumn)使用的是外键关联.也可以通过@JoinTable指定第三表的映射关系

一对多

外键关联

一对多与多对一的外键关联模型是一样的.只是在一对多中.是处于多的一方而言
多对一外键关联

@Data
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToMany
    @JoinColumn(name = "user_id")
    private List<Address> addressList;
}

第三表关联

在一对多模映射中, 若@ManyToOne不带@JoinColumn声明外键, 则将会自动生成第三表关联的映射模式. 即
第三表一对多关联

@Data
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Integer age;
    @OneToMany
    private List<Address> addressList;

}

或通过@JoinTable指定第三表的映射关系

多对多

多对多映射通过第三表关联.
多对多关联

@Data
@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String city;

    @ManyToMany
    @JoinTable(
            name="user_address",
            joinColumns={
                    @JoinColumn(name="address_id",referencedColumnName="id")
            },
            inverseJoinColumns={
                    @JoinColumn(name="user_id",referencedColumnName="id")
            }
    )
    private List<User> userList;
}
@Data
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany
    @JoinTable(
            name="user_address",
            joinColumns={
                    @JoinColumn(name="user_id",referencedColumnName="id")
            },
            inverseJoinColumns={
                    @JoinColumn(name="address_id",referencedColumnName="id")
            }
    )
    private List<Address> addressList;

}

若是双向多对多映射,则必须设定@JoinTable并指定第三方表.

继承策略

实体类继承后的映射策略

猜你喜欢

转载自blog.csdn.net/d292222100/article/details/81908179
今日推荐