Springboot开发Spring 学习java学习

个人JPA参考手册

2017-02-28  本文已影响961人  jcala

个人的JPA参考手册,尚未整理完毕,会更新

githu地址:https://github.com/jcalaz/tip

1. JPA普通注解

@Entity
@Table(name="person_table", indexes = {
        @Index(name="idx_person", columnList="name")
        })
@NamedQuery(
        name="simpleByTest",
        query="SELECT x FROM SimpleModel x WHERE x.test LIKE :test"
    )
public class Person {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    //...
}
当@Enumerated的value属性为EnumType.STRING时,底层数据库保存的是枚举值的名称;
当@Enumerated的value属性为EnumType.ORDINAL时,保存枚举值的序号。
如@Enumerated(EnumType.ORDINAL).
当修饰的属性为byte[],Byte[],java.io.Serializable类型时,将映射为数据库底层的Blob列;
当修饰的属性为char[],Character[]或java.lang.String类型时,映射为底层的Clob列。
比如JPA加载Person实体时并不需要立即加载它的pic属性,而只加载一个"虚拟的"代理,真正需要pic属性再从数据库加载。
@Basic可以指定的属性:
fetch:指定是否需要延迟加载该属性。FetchType.EAGER不使用延迟加载,Fetch.LAZY使用延迟加载。
optional:指定映射的数据列是否允许使用null值。
例如:
@Lob
@Basic(fetch=FetchType.LAZY)
private byte[] pic;
@Temporal可以指定一个value属性,
该属性支持Temporal.DATE,Temporal.TIME,Temporal.TIMESTAMP,
分别对应于数据库date,time,timestamp类型的数据列。
   @Entity
   @Table(name="person_table")
   public class Person{
   @Id
   private int id;
   @Column(name="person_name",length=50)
   private String name;
   @Embedded
   @AttributeOverrides({
    @AttributeOverride(name="name",column=@Column(name="cat_name",length=35)),
    @AttributeOverride(name="color",column=@Column("cat_color"))
   })
   private Cat cat;
   }
   @Embeddable
   public class Cat{
     private String name;
     private String color;
   }
方式一:使用@IdClass和多个@Id
   @Entity
   @Table(name="person_table")
   @IdClass(Cat.class)
   public class Person{
   //两个@Id定义联合主键
   @Id
   private int id;
   @Id
   private String name;
   private Cat cat;
   }
方式二:用一个@EmbeddedId
 @Entity
   @Table(name="person_table")
   public class Person{
   @Id
   private int id;
   @Column(name="person_name",length=50)
   private String name;
   @EmbeddedId
   @Embedded
   @AttributeOverrides({
    @AttributeOverride(name="name",column=@Column(name="cat_name",length=35)),
    @AttributeOverride(name="color",column=@Column("cat_color"))
   })
   private Cat cat;
   }
   @Embeddable
   public class Cat{
     private String name;
     private String color;
   }
   //Example 1:
    @Entity
    public class Course {
       @ManyToMany
       @OrderBy("lastname ASC")
       public List<Student> getStudents() {};
    }
    //Example 2:
    @Entity
    public class Student {
       @ManyToMany(mappedBy="students")
       @OrderBy // ordering by primary key is assumed
       public List<Course> getCourses() {};
    }
    //Example 3:
    @Entity
    public class Person {
       @ElementCollection
       @OrderBy("zipcode.zip, zipcode.plusFour")
       public Set<Address> getResidences() {};
    }
    @Embeddable
    public class Address {
       protected String street;
       protected String city;
       protected String state;
       @Embedded protected Zipcode zipcode;
    }
    @Embeddable
    public class Zipcode {
       protected String zip;
       protected String plusFour;
    }
 @MappedSuperclass
    public class Employee {
        @Id protected Integer empId;
        @Version protected Integer version;
        @ManyToOne @JoinColumn(name="ADDR")
        protected Address address;
        public Integer getEmpId() { }
        public void setEmpId(Integer id) {  }
        public Address getAddress() { }
        public void setAddress(Address addr) { }
    }
    // Default table is FTEMPLOYEE table
    @Entity
    public class FTEmployee extends Employee {
        // Inherited empId field mapped to FTEMPLOYEE.EMPID
        // Inherited version field mapped to FTEMPLOYEE.VERSION
        // Inherited address field mapped to FTEMPLOYEE.ADDR fk
        // Defaults to FTEMPLOYEE.SALARY
        protected Integer salary;
        public FTEmployee() {}
        public Integer getSalary() { }
        public void setSalary(Integer salary) { }
    }
    @Entity @Table(name="PT_EMP")
    @AssociationOverride(
        name="address",
        joincolumns=@JoinColumn(name="ADDR_ID"))
    public class PartTimeEmployee extends Employee {
        // Inherited empId field mapped to PT_EMP.EMPID
        // Inherited version field mapped to PT_EMP.VERSION
        // address field mapping overridden to PT_EMP.ADDR_ID fk
        @Column(name="WAGE")
        protected Float hourlyWage;
        public PartTimeEmployee() {}
        public Float getHourlyWage() {}
        public void setHourlyWage(Float wage) {}
    }

2. JPA生命周期注解

@Entity
@EntityListeners(PersonListener.class)
public class Person implements Serializable{}

3. 关联

@Entity(name = "Person")
public static class Person {
    @Id
    @GeneratedValue
    private Long id;
    public Person() {
    }
}
@Entity(name = "Phone")
public static class Phone {
    @Id
    @GeneratedValue
    private Long id;
    @Column(name = "`number`")
    private String number;
    @ManyToOne(optional=false,cascade=CascadeType.ALL,fetch=FetchType.LAZY,targetEntity=Person.class)
    @JoinColumn(name = "person_id",
            foreignKey = @ForeignKey(name = "PERSON_ID_FK")
    )
    private Person person;
    public Phone() {
    }
    public Phone(String number) {
        this.number = number;
    }
    public Long getId() {
        return id;
    }
    public String getNumber() {
        return number;
    }
    public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
}

对应的sql语句:

CREATE TABLE Person (
    id BIGINT NOT NULL ,
    PRIMARY KEY ( id )
)
CREATE TABLE Phone (
    id BIGINT NOT NULL ,
    number VARCHAR(255) ,
    person_id BIGINT ,
    PRIMARY KEY ( id )
 )
ALTER TABLE Phone
ADD CONSTRAINT PERSON_ID_FK
FOREIGN KEY (person_id) REFERENCES Person
@Entity
@Table(name="person_table")
public class Person{
@Id
private int personid;
private String name;
@OneToOne(optional=false,cascade=CascadeType.ALL,fetch=FetchType.LAZY,targetEntity=IdCard.class)
@JoinColumn(name="id_card_id",nullable=false,updatable=false)//映射外键列
private IdCard idCard;
}
@Entity
@Table(name="id_card_table")
public class IdCard{
@Id
private int idCardId;
private String cardNumber;
}
@Entity(name = "Person")
public static class Person {
    @Id
    @GeneratedValue
    private Long id;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Phone> phones = new ArrayList<>();
    public Person() {
    }
    public List<Phone> getPhones() {
        return phones;
    }
}
@Entity(name = "Phone")
public static class Phone {
    @Id
    @GeneratedValue
    private Long id;
    @Column(name = "`number`")
    private String number;
    public Phone() {
    }
    public Phone(String number) {
        this.number = number;
    }
    public Long getId() {
        return id;
    }
    public String getNumber() {
        return number;
    }
}

对应的sql:

CREATE TABLE Person (
    id BIGINT NOT NULL ,
    PRIMARY KEY ( id )
)
CREATE TABLE Person_Phone (
    Person_id BIGINT NOT NULL ,
    phones_id BIGINT NOT NULL
)
CREATE TABLE Phone (
    id BIGINT NOT NULL ,
    number VARCHAR(255) ,
    PRIMARY KEY ( id )
)
ALTER TABLE Person_Phone
ADD CONSTRAINT UK_9uhc5itwc9h5gcng944pcaslf
UNIQUE (phones_id);
ALTER TABLE Person_Phone
ADD CONSTRAINT FKr38us2n8g5p9rj0b494sd3391
FOREIGN KEY (phones_id) REFERENCES Phone;
ALTER TABLE Person_Phone
ADD CONSTRAINT FK2ex4e4p7w1cj310kg2woisjl2
FOREIGN KEY (Person_id) REFERENCES Person
@Entity(name = "Person")
public static class Person {
    @Id
    @GeneratedValue
    private Long id;
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private List<Address> addresses = new ArrayList<>();
    public Person() {
    }
    public List<Address> getAddresses() {
        return addresses;
    }
}
@Entity(name = "Address")
public static class Address {
    @Id
    @GeneratedValue
    private Long id;
    private String street;
    @Column(name = "`number`")
    private String number;
    public Address() {
    }
    public Address(String street, String number) {
        this.street = street;
        this.number = number;
    }
    public Long getId() {
        return id;
    }
    public String getStreet() {
        return street;
    }
    public String getNumber() {
        return number;
    }
}

对应的sql:

CREATE TABLE Address (
    id BIGINT NOT NULL ,
    number VARCHAR(255) ,
    street VARCHAR(255) ,
    PRIMARY KEY ( id )
)
CREATE TABLE Person (
    id BIGINT NOT NULL ,
    PRIMARY KEY ( id )
)
CREATE TABLE Person_Address (
    Person_id BIGINT NOT NULL ,
    addresses_id BIGINT NOT NULL
)
ALTER TABLE Person_Address
ADD CONSTRAINT FKm7j0bnabh2yr0pe99il1d066u
FOREIGN KEY (addresses_id) REFERENCES Address;
ALTER TABLE Person_Address
ADD CONSTRAINT FKba7rc9qe2vh44u93u0p2auwti
FOREIGN KEY (Person_id) REFERENCES Person

方式二:通过@JoinTable配置关联表

@Entity(name = "Person")
public static class Person {
    @Id
    @GeneratedValue
    private Long id;
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},targetEntity=Address.class)
    @JoinTable(
    name="person_address",
    joinColumns=@JoinColumn(name="person_id"),
    inverseJoinTableColumns=@JoinColumn(name="address_id")
    )
    private List<Address> addresses = new ArrayList<>();
    public Person() {
    }
    public List<Address> getAddresses() {
        return addresses;
    }
}
@Entity
@Table(name="person_table")
public class Person{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int personId;
private String name;
private int age;
@OneToOne(mappedBy="person",cascade=CascadeType.ALL)
private Address address;
//...
}
@Entity
@Table(name="address_table")
public class Address{
 @Id
 private int addressId;
 private String detail;
 @OneToOne(optional=false,cascade=CascadeType.ALL)
 @JoinColumn(name="person_id",nullable=false,updatable=false)
 private Person person;
 //...
}
@Entity
@Table(name="person_table")
public class Person{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int personId;
private String name;
private int age;
@OneToMany(mappedBy="person",cascade=CascadeType.ALL)
private Set<Address> addresses=new HashSet<Address>();
//...
}
@Entity
@Table(name="address_table")
public class Address{
 @Id
 private int addressId;
 private String detail;
 @ManyToOne(optional=false,cascade=CascadeType.ALL)
 @JoinColumn(name="person_id",nullable=true)
 private Person person;
 //...
}
@Entity
@Table(name="person_table")
public class Person{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int personId;
private String name;
private int age;
@ManyToMany(mappedBy="persons",cascade=CascadeType.ALL)
private Set<Address> addresses=new HashSet<Address>();
//...
}
@Entity
@Table(name="address_table")
public class Address{
 @Id
 private int addressId;
 private String detail;
 @ManyToMany(optional=false,cascade=CascadeType.ALL)
 @JoinColumn(name="person_id",nullable=true)
 @JoinTable(
    name="person_address",
    joinColumns=@JoinColumn(name="address_id"),
    inverseJoinTableColumns=@JoinColumn(name="person_id")
 )
 private Set<Person> persons=new HashSet<Person>();
 //...
}
@Entity
@Table(name="person_table")
public class Person{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int personId;
private String name;
private int age;
@OneToMany(mappedBy="person",cascade=CascadeType.ALL)
@MapKey(name="pk")
private Map<AddressPk,Address> addresses=new HashMap<AddressPk,Address>();
//...
}

4. JPA映射策略

JPA提供了3种映射策略:
(1)、 整个类层次对应一张表策略,这是继承映射的默认策略。
即如果实体类B继承实体类A,实体类C也继承自实体A,那么只会映射成一个表,
这个表中包括了实体类A、B、C中所有的字段,JPA使用一个叫做“discriminator列”来区分某一行数据是应该映射成哪个实体。
注解为:@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
(2)、 连接子类策略。父亲的放在一张表,儿子只是保存和父亲不一样的,增加的属性。
这种情况下子类的字段被映射到各自的表中,这些字段包括父类中的字段,并执行一个join操作来实例化子类。
注解为:@Inheritance(strategy = InheritanceType.JOINED)
(3)、 每个具体的类一个表的策略。
注解为:@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
可使用@Inheritance指定映射策略
InheritanceType.SINGLE_TABLE:第一种
InheritanceType.JOINED:第二种
InheritanceType.TABLE_PER_CLASS:第三种
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
// 定义辨别者列的列名为person_type,列类型为字符串
@DiscriminatorColumn(name="person_type" ,
    discriminatorType=DiscriminatorType.STRING)
// 指定Person实体对应的记录在辨别者列的值为"普通人"
@DiscriminatorValue("普通人")
@Table(name="person_inf")
public class Person{}
// 顾客类继承了Person类
@Entity
// 指定Customer实体对应的记录在辨别者列的值为"顾客"
@DiscriminatorValue("顾客")
@Table(name="customer_inf")
public class Customer extends Person{}
// 员工类继承了Person类
@Entity
// 指定Employee实体对应的记录在辨别者列的值为"员工"
@DiscriminatorValue("员工")
@Table(name="employee_inf")
public class Employee extends Person{}
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Table(name="person_inf")
public class Person{}
@Entity
@Table(name="customer_inf")
public class Customer extends Person{}
@Entity
@Table(name="employee_inf")
public class Employee extends Person{}
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@Table(name="person_inf")
public class Person{}

5. spring data注解

参考

上一篇 下一篇

猜你喜欢

热点阅读