jacksun1978

导航

 

一、JPA实体需要满足的条件

  •     必须有一个public或者protect类型不带参数的构造函数
  •     如果实体类在分布式环境中作为参数传递,必须实现Serializable接口
  •     实体类不能是final的,也不带有final的方法和属性
  •     实体类属性不能是public的,必须通过getter/setter方法存取
  •     抽象类和具体类都可以作为实体类

二、实体类的类型

     实体类变量和属性遵循以下几种类型:

     1、原始类型

     2、String类型

     3、其他序列化类型,包括:

  •          原始类型包装类
  •          java.math.BigInteger;
  •          java.math.BigDecimal;
  •          java.util.Date;
  •          java.util.Calendar;
  •          java.sql.Date;
  •          java.sql.Time;
  •          java.sql.TimeStamp;
  •          user defined serializable types;
  •          byte[];
  •          Byte[];
  •          char[];
  •          Character[];

      4、枚举类型

      5、其他实体或者实体集合

      6、Embeddable类型

二、标注

    1、变量(field)标注和属性(property)标注

        主要取决于@Id标注的位置。可以采用变量标注,也可以采用属性标注,但是一旦采用其中一种,就不能混合使用。

        变量标注:

        @Id

         private int id;

       属性标注:标注在getter方法上

 

       private int id;

       @Id

       public int getId(){

           return id;

       }

 

       public void setId(int id){

           this.id= id;

       }

     2、变量和属性中使用集合

     如何变量或者属性是基本类型或者嵌入式类的集合,使用@ElementCollection标注。集合类型的变量和属性放在单独的集合表中。

     @ElementCollection指定集合的变量或者属性,有两个属性,targetClass和fetch,如果集合中使用泛型,可以不指定targetClass。

     @CollectionTable注解指定集合表的详细信息,如它包含的列

 

 

三、

    @Table(name,schema);

    @Column(name,..);

    @Basic(fetch,);

    @Lob

    @Enumerated(EnumType.STRING)

    @Temporal(TemporalType.DATE)

    @Transient

    @GeneratedValue:

     GenerationType:

     AUTO类型通常用于开发阶段或者原型验证阶段,速度较快,但是在正式运行环境,最好选用其他类型。

     TABLE:最灵活和轻便的方式,可以适用不同的数据库,并且可以在一个表中定义多个生成器。

     example:

@TableGenerator(name="Address_Gen",
table="ID_GEN",
pkColumnName="GEN_NAME",
valueColumnName="GEN_VAL",
pkColumnValue="Addr_Gen",
initialValue=10000,
allocationSize=100)
@Id @GeneratedValue(generator="Address_Gen")
private int id;

      SEQUENCE:通过数据库sequence来生成id,需要后台数据库支持sequence。

      example:

@SequenceGenerator(name="Emp_Gen", sequenceName="Emp_Seq")
@Id @GeneratedValue(generator="Emp_Gen")
private int getId;

       IDENTITY:需要数据库的支持

 

      RelationShips

      单向ManyToOne:

      example:

@Entity
public class Employee {
@Id private int id;
@ManyToOne
@JoinColumn(name="DEPT_ID")
private Department department;
// ...
}

  如果没有定义JoinColumn,默认的外键是department_id

     双向OneToMany或者ManyToOne:Employee与Department的关系

  •      ManyToOne的一侧是拥有者,JoinColumn被定义在这一段
  •      OneToMany的一侧是反向的一段,所以必须用mappedBy

     单向OneToOne:与ManyToOne一样

     example:

@Entity
public class Employee {
@Id private int id;
private String name;
@OneToOne
@JoinColumn(name="PSPACE_ID")
private ParkingSpace parkingSpace;
// ...
}

    双向OneToOne: employee与parkingspace(停车位)的关系

@Entity
public class Employee {
@Id private int id;
private String name;
@OneToOne
@JoinColumn(name="PSPACE_ID")
private ParkingSpace parkingSpace;
// ...
}

  

@Entity
public class ParkingSpace {
@Id private int id;
private int lot;
private String location;
@OneToOne(mappedBy="parkingSpace")
private Employee employee;
// ...
}

 

   @JoinColumn表明实体是关系的拥有者(owner),而mappedBy表明实体是关系的被拥有者。

 

    ManyToMany:Employee与Project的关系

 

@Entity
public class Employee {
@Id private int id;
private String name;
@ManyToMany
@JoinTable(name="EMP_PROJ",
joinColumns=@JoinColumn(name="EMP_ID"),
inverseJoinColumns=@JoinColumn(name="PROJ_ID"))

private Collection<Project> projects;
// ...
}

 

   单向OneToMany映射:Employee与phoneNum的关系。。

 

@Entity
public class Employee {
@Id private int id;
private String name;
@OneToMany
@JoinTable(name="EMP_PHONE",
joinColumns=@JoinColumn(name="EMP_ID"),
inverseJoinColumns=@JoinColumn(name="PHONE_ID"))
private Collection<Phone> phones;
// ...
}

 

   Embedded Object

 

   Embedded Object没有自己的标志符,而是依赖实体的标志符。数据库中Embedded Object 和实体存在一个表中。

   为什么要把一个实体分解出具有一个或者多个Embedded Object,主要是从领域建模方面讲,抽象出Embedded Object是一种更加自然的表述,而且有利于复用。例子:抽象出Address,在Employee实体类中有这个属性,在Comany实体类中也有这个属性。

@Embeddable @Access(AccessType.FIELD)
public class Address {
private String street;
private String city;
private String state;
@Column(name="ZIP_CODE")
private String zip;
// ...
}

 

@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
@Embedded private Address address;
// ...
}

 

   如果实体类表中的字段名与Embedded Object中定义的不一样,使用注解@AttributeOverrides

 

@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="state", column=@Column(name="PROVINCE")),
@AttributeOverride(name="zip", column=@Column(name="POSTAL_CODE"))
})
private Address address;
// ...
}
@Entity
public class Company {
@Id private String name;
@Embedded
private Address address;
// ...
}

 

  Collection Map:

  如果Collection属性的类型是Embeddable类型或者基本类型,不能称之为两者之间的Relationship。

  @ElementCollection

  @CollectionTable

  Example:

@Embeddable
public class VacationEntry {
@Temporal(TemporalType.DATE)
private Calendar startDate;
@Column(name="DAYS")
private int daysTaken;
// …
}

 

@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
// ...
@ElementCollection(targetClass=VacationEntry.class)
private Collection vacationBookings;
@ElementCollection
private Set<String> nickNames;
// ...
}

 

 

@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
// …
@ElementCollection(targetClass=VacationEntry.class)
@CollectionTable(
name="VACATION",
joinColumns=@JoinColumn(name="EMP_ID"))
@AttributeOverride(name="daysTaken",
column=@Column(name="DAYS_ABS"))

private Collection vacationBookings;
@ElementCollection
@Column(name="NICKNAME")
private Set<String> nickNames;
// ...
}

 

  Map:Map的key和value的类型可以是实体,Embeddables或者基本类型。

  记住:永远是Map的value对象的类型决定使用什么方式的映射。如果value的类型是实体,Map必须被映射成OneToMany或者ManyToMany关系,如果value对象类型是Embeddable或者基本类型,用ElementCollection

 

image

posted on 2012-03-22 22:23  jacksun1978  阅读(1688)  评论(0编辑  收藏  举报