继承映射策略(Inheritance Mapping Stategies)
(1) 单表映射
(2) 关联关系映射
(3) 每个实体类一张表(不支持多态)
1、单表映射
优点:(1) 支持多态查询/多态更新
(2) 简洁
(3) 效率高(单表操作)
缺点:(1) 不适合深层次的继承结构,会形成庞大的表
(2) 要求列允许为空
@Inheritance
@DiscriminatorColumn(name="DISC", discri:
minatorType=STRING,length=20)//指定区别父子类的表述符的列名、类型和长度
@DiscriminatorValue("CUSTOMER")//指定本类描述符的值
以上两个标注只适用于所有类建一个表的情况。
@Inheritance(strategy=JOINED|SINGLE_TABLE|TABLE_PER_CLASS)
SINGLE_TABLE也就是所有类建一张表
JOINED也就是每个类建一个表。
TABLE_PER_CLASS只针对对具体类建表。
@MappedSuperclass//映射子类型,这个标注没有属性
@AttributeOverride
@AttributeOverrides
2、关联关系映射
一对一关联
@OnetoOne(targetEntity="",cascade="CascadeType.ALL|MERGE|PERSIST|REFRESH|REMOVE",fetch="FetchType.EAGER|LAZY", mappedBy="",optional="true|false")
cascade级联设置,
ALL对主对象的增删该操作,都会级联到子对象
PERSIST只有对主对象进行增加操作时,才级联到子对象
REMOVE只有对主对象进行删除操作时,才级联到子对象
MERGE只有对主对象进行修改操作时,才级联到子对象
REFRESH只有对主对象进更新操作时,才级联到子对象
fetch加载策略,FetchType.EAGER是采取立即加载策略,FetchType.LAZY是采用延迟加载。一对一关系,在默认情况下,会采用Fetch操作立即加载。
一对多关联
一对多单向关系需要中间表。
双向一对多关系,也要注意(mappedBy=“”)关系维护方的问题。
mappedBy,是指定拥有关系的属性,只需要在关联的反方向(非主对象)一端指定使用mappedBy的属性。
@JoinColumn(name="",referencedColumnName="",unique="true|false",nullable="true|false",updateable="true|false",table="...")// 用来指定根据类关系映射到表后和其他表关联的列名,以及关联的列名,以及本列的属性
name属性指定类中属性对应的列名,默认为属性名
referencedColumnName属性指定类对应的表中的关联引用的列的列名。
nullable属性指定类中属性对应的列是否可空,默认为true
updateable="true|false"属性指定类中该属性是否会出现在update语句中,也就是会不会被修改,默认为true可以被修改。
table属性指定类中有关联属性的列所对应的表,默认为实体类所对应的表。
@PrimaryKeyJoinColumn主键关联
例:
引用外键
@OneToOne(optional=false)
@JoinColumn(name="CUSTREC_ID", unique=true, nullable=false, updatable=false)
public CustomerRecord getCustomerRecord() { return customerRecord; }
@OneToOne(optional=false, mappedBy="customerRecord")
public Customer getCustomer() { return customer; }
共享主键
@Entity
public class Employee {
@Id
@OneToOne @PrimaryKeyJoinColumn
Integer id;
EmployeeInfo info;
...
}
On EmployeeInfo class:
@Entity
public class EmployeeInfo {
@Id
Integer id;
...
}
@OneToMany(targetEntity="",cascade="CascadeType.ALL|MERGE|PERSIST|REFRESH|REMOVE",fetch="FetchType.EAGER|LAZY", mappedBy="")
@OneToMany(cascade=ALL, mappedBy="customer")
public Set getOrders() { return orders; }
In Order class:
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() { return customer; }
@OneToMany(targetEntity=com.acme.Order.class, cascade=ALL,
mappedBy="customer")
public Set getOrders() { return orders; }
In Order class:
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() { return customer; }
多对多关联
@ManyToMany(targetEntity="",cascade="CascadeType.ALL|MERGE|PERSIST|REFRESH|REMOVE",fetch="FetchType.EAGER|LAZY", mappedBy="",optional="true|false")
@JoinTable标注是标识多对多中间表的中对应的信息的。
对于双向多对多关系,mappedBy=“”可以放在任意一方,@mappedBy与@JoinTable不能在同一个实体。
@JoinTable所在的实体称为主控方。
例:
@JoinTable(
name="CUST_PHONE"//中间表表名,
joinColumns=
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),
//指明本方id关联的列名及引用自哪一列
inverseJoinColumns=
@JoinColumn(name="PHONE_ID", referencedColumnName="ID")
//指明关联方id所对应的列名及引用自哪一列
)
关联的两个类Customer用户,和用户的电话号码PhoneNumber
例 1:
In Customer class:
@ManyToMany
@JoinTable(name="CUST_PHONES")
public Set getPhones() { return phones; }
In PhoneNumber class:
@ManyToMany(mappedBy="phones")
public Set getCustomers() { return customers; }
例 2:
In Customer class:
@ManyToMany(targetEntity=com.acme.PhoneNumber.class)
public Set getPhones() { return phones; }
In PhoneNumber class:
@ManyToMany(targetEntity=com.acme.Customer.class, mappedBy="phones")
public Set getCustomers() { return customers; }
例 3:
In Customer class:
@ManyToMany
@JoinTable(name="CUST_PHONE",
joinColumns=
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),
inverseJoinColumns=
@JoinColumn(name="PHONE_ID", referencedColumnName="ID")
)
public Set getPhones() { return phones; }
In PhoneNumberClass:
@ManyToMany(mappedBy="phones")
public Set getCustomers() { return customers; }
在实体中,两种类型的属性需要进行特殊标注,也就是Date和Calendar
需要使用@Temporal(Date),@Temporal(Calendar)
EJB QL语句
EJB3.0中的QL,可以使用order by和having字句,对得出的结果进行分组处理。
EJB3.0中的QL关联查询和hibernate的HQL的写法基本相同。
Bulk updates or deletes:
优点:批处理操作直接在数据库进行,避免了内存的大量占用,提高了性能。
缺点:没有缓存操作。
Group by
Group by中分组的字段必须在select中出现
例:
Query query = em.createQuery("select o from Order o left join o.orderItems where o.ower.age=26 order by o.orderid");
EJB QL也可以使用构造器查找。
把查询结果构造成一个对象,类必须使用全限定名。
例:
Query query=em.createQuery("select new com.foshanshop.ejb3.bean.SimplePerson(p.name,p.sex) from Person p order by p.personid desc");