JPA关系映射

来源:互联网 发布:龙口美工 编辑:程序博客网 时间:2024/04/30 07:35

关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一、一对多和多对多几种关系。细分起来他们又有单向和双向之分

多的一方为关系维护端,关系维护端负责外键纪录的更新,关系被维护端没有权力更新外键纪录。

拥有mappedBy注解的实体类为关系被维护端,另外的实体类为关系维护端的。关系的维护端负责对关系(在多对多为中间关联表)的CRUD做操作。关系的被维护端不能进行该操作,不能维护关系。

单向 OneToOne

单向一对一是关联关系映射中最简单的一种,简单地说就是可以从关联的一方去查询另一方,却不能反向查询

单向一对一关系的拥有端

@Entity

public classPerson implements Serializable{

   @Id

   @GeneratedValue(strategy= GenerationType.AUTO)

   privateLong id;

   privateString name;

   privateint age;

   @OneToOne

   privateAddress address;

  //Getters&Setters

}

单向一对一关系的反端

@Entity

public classAddress implementsSerializable {

   @Id

   @GeneratedValue(strategy= GenerationType.AUTO)

   privateLong id;

   privateString street;

   privateString city;

  private String country;

  //Gettes& Setters

}

这种单向的一对一关系在数据库中是以外键的形式被映射的。其中关系的发出端存储一个指向关系的接收端的一个外键, 缺省情况下这个外键的字段名称,是以它指向的表的名称加下划线“_”加“ID”组成的, 当然我们也可以根据我们的喜好来修改这个字段,修改的办法就是使用 @JoinColumn 这个注解

 

双向 OneToOne

双向一对一关系中的接受端

@Entity

 publicclassAddress implements Serializable {

   @Id

   @GeneratedValue(strategy= GenerationType.AUTO)

   privateLong id;

   privateString street;

   privateString city;

  private String country;

   @OneToOne(mappedBy="address")

  private Person person;

   //Gettes& Setters

}

双向关系有一方为关系的拥有端,另一方是关系的反端,也就是“Inverse”端。在这里例子中 Person 拥有这个关系,而 Address 就是关系的“Inverse”端。Address 中我们定义了一个 person 属性,在这个属性上我们使用了 @OneToOne 注解并且定义了他的“mappedBy”属性,这个在双向关系的“Inverse”端是必需的

双向OneToMany

双向一对多关系的接受端

@Entity

public class Person implementsSerializable {

       @Id

       @GeneratedValue(strategy= GenerationType.AUTO)

       privateLong id;

       privateString name;

       privateint age;

 

       @OneToMany(mappedBy= "person")

       privateList<CellPhone> cellPhones;

       //Getters and Setters

}

 

双向一对多关系的发出端

@Entity

public class CellPhone implementsSerializable {

       @Id

       @GeneratedValue(strategy= GenerationType.AUTO)

       privateLong id;

 

       privateString manufacture;

       privateString color;

       privateLong  phoneNo;

       @ManyToOne

       privatePerson person;

       //Getters and Setters

}

 

单向 ManyToMany

多对多关联关系中只能通过中间表的方式进行映射

单向多对多关系的发出端

@Entity

public classTeacher implements Serializable {

       @Id

       @GeneratedValue(strategy =GenerationType.AUTO)

       private Long id;

       private String name;

       private Boolean gender;

       private int age;

       private int height;

       @ManyToMany

       private List<Student> students;

       // Getters  and Setters

}

单向多对多关系的反端

@Entity

public classStudent implements Serializable {

       @Id

       @GeneratedValue(strategy =GenerationType.AUTO)

       private Long id;

       private String name;

       private Boolean gender;

       private int age;

       private int height;

       //Getters and  Setters

}

 

双向 ManyToMany

双向多对多关系的拥有端

@Entity

public classTeacher implements Serializable {

       @Id

       @GeneratedValue(strategy =GenerationType.AUTO)

       private Long id;

       private String name;

       private Boolean gender;

       private int age;

       private int height;

       @ManyToMany

       private List<Student> students;

       // Getters  and Setters

}

 

双向多对多关系的反端

@Entity

public classStudent implements Serializable {

       @Id

       @GeneratedValue(strategy =GenerationType.AUTO)

       private Long id;

       private String name;

       private Boolean gender;

       private int age;

       private int height;

       @ManyToMany(mappedBy = "students")

       private List<Teacher> teachers;

       //Getters and  Setters

}

 

 

JPA复合主键映射
一个实体的主键可能同时构成,当且仅当多个字段的值完全相同时,才认为是相同的实体对象。
复合主键映射时,通常构成将复合主键的多个字段单独抽取出来建一个类作为符合主键类。
符合主键类必须满足以下几点要求
必须实现Serializable接口。
必须有默认的public无参数的构造方法。
必须覆盖equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。
@Embeddable
public class AirLinePK implements Serializable {
    @Column(nullable=false,length=3,name="LEAVECITY")
    private String leavecity;
    @Column(nullable=false,length=3,name="ARRIVECITY")
    private String arrivecity;
    public AirLinePK(){}
    public AirLinePK(String leavecity, String arrivecity) {
        this.leavecity = leavecity;
        this.arrivecity = arrivecity;
    }
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (this.leavecity!=null&& this.arrivecity!=null ? (this.leavecity+ "-"+this.arrivecity).hashCode() : 0);
        return hash;
    }
    @Override
    public boolean equals(Object object) {
        if (!(object instanceof AirLinePK)){
            returnfalse;
        }
        AirLinePK other = (AirLinePK)object;
        if (this.leavecity !=other.leavecity && (this.leavecity == null ||!this.leavecity.equalsIgnoreCase(other.leavecity))) return false;
        if (this.arrivecity !=other.arrivecity && (this.arrivecity == null ||!this.arrivecity.equalsIgnoreCase(other.arrivecity))) return false;
        return true;
    }
    //省略getter setter...
}
@Entity
public class AirLine implements Serializable {
    @EmbeddedId
    private AirLinePK id;
    @Column(length=15)
    private String airLineNum;
    public AirLine(){}
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (this.id != null ?this.id.hashCode() : 0);
        return hash;
    }
    @Override
    public boolean equals(Object object) {
        if (!(object instanceof AirLine)) {
            returnfalse;
        }
        AirLine other = (AirLine)object;
        if (this.id != other.id &&(this.id == null || !this.id.equals(other.id))) return false;
        return true;
    }
    //省略getter setter...
}
复合主键映射还有另一种映射方式
public class AirLinePK implements Serializable {
    @Column(length=3)
    private String leavecity;
    @Column(length=3)
    private String arrivecity;
    public AirLinePK(){}
    public AirLinePK(String leavecity, String arrivecity) {
        this.leavecity = leavecity;
        this.arrivecity = arrivecity;
    }
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (this.leavecity!=null&& this.arrivecity!=null ? (this.leavecity+ "-"+this.arrivecity).hashCode() : 0);
        return hash;
    }
    @Override
    public boolean equals(Object object) {
        if (!(object instanceof AirLinePK)){
            returnfalse;
        }
        AirLinePK other = (AirLinePK)object;
        if (this.leavecity !=other.leavecity && (this.leavecity == null ||!this.leavecity.equalsIgnoreCase(other.leavecity))) return false;
        if (this.arrivecity != other.arrivecity&& (this.arrivecity == null ||!this.arrivecity.equalsIgnoreCase(other.arrivecity))) return false;
        return true;
    }
    //省略getter setter
}

@Entity
@IdClass(AirLinePK.class)
public class AirLine implements Serializable {
    @Id private String leavecity;
    @Id private String arrivecity;
    @Column(length=15) private String airLineNum;
    public AirLine(){}
   //省略getter setter
}

 

javax.persistence.OneToOne

target Entity

表示该属性关联的实体类型.该属性通常不必指定,ORM框架根据属性类型自动判断targetEntity.

 

mappedBy

mappedBy 属性是 String类型的属性。mappedBy 属性的值是当前实体在关联实体中的属性名称,使用 mappedBy 可以定义实体类之间的双向关系。

如果类之间是单向关系,不需要提供定义

如果类和类之间形成双向关系,我们就需要使用这个属性进行定义,否则可能引起数据一致性的问题。

 

cascade

cascade 属性的类型是 CascadeType[] 类型。cascade 属性定义实体和实体之间的级联关系。可以从 CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。还有一个更方便的选择是使用 CascadeType.ALL,表示选择上面全部四项。

 

fetch

fetch 属性是 FetchType 类型的属性。可选择项包括:FetchType.EAGER  FetchType.LAZY

前者表示关联关系的从类在主类加载的时候同时加载,后者表示关联关系的从类在自己被访问时才加载。

optional

optional 属性是 boolean类型的属性。是否允许该字段为null,该属性应该根据数据库表的外键约束来确定,默认为true。默认值是 true


javax.persistence.JoinColumn

name

默认为引用关系属性/字段的名称 +”_”+被引用的主键列的名称

insertable

默认情况下字段可以插入到所有表列中

nullable

是否允许所属列包含空值

referencedColumnName

属性指定关联关系中的被维护端与关联关系中的维护端对应的表之间形成关联关系的字段名称,默认情况下假设在实体关系中,被引用的列名是被引用的主键列的名称,要指定其他列名,请将 referencedColumnName 设置为所需的 String 列名,通常用于关联关系中的被维护端的关联字段不是自己的主键的情况

table

实体的所有持久字段存储到一个名称为实体类名称的数据库表中

unique

JPA 持续性提供程序假设允许所有列包含重复值

updatable

默认情况下,JPA持续性提供程序假设它可以更新所有表列

columnDefinition


@OneToOne 注解定义
public @interface OneToOne{
     Class targetEntity( ) default void.class;
     CascadeType[] cascade( ) default {};
     FetchType fetch( ) default EAGER;
     boolean optional( ) default true;
     String mappedBy( ) default "";
}

 

@JoinColumn注解定义

@Target({METHOD,FIELD}) @Retention(RUNTIME)

public @interfaceJoinColumn {

String name() default "";

String referencedColumnName() default"";

boolean unique() default false;

boolean nullable() default true;

boolean insertable() default true;

boolean updatable() default true;

String columnDefinition() default"";

String table() default "";

}

 


原创粉丝点击