JPA 学习日志 5
来源:互联网 发布:小学生模拟考试软件 编辑:程序博客网 时间:2024/06/09 14:06
五、关系
1. 1-m 一对多双向关联
多的一方为关系维护端,关系维护端负责外键记录的维护,关系被维护端没有权力更新外键记录。
package cn.itcast.bean.order;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class OrderItem {
private Integer id;
private String productName;
private Float sellPrice = 0f;
private Order order;
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(length=40,nullable=false)
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
@Column(nullable=false)
public Float getSellPrice() {
return sellPrice;
}
public void setSellPrice(Float sellPrice) {
this.sellPrice = sellPrice;
}
@ManyToOne(cascade={CascadeType.REFRESH,CascadeType.MERGE},
fetch=FetchType.EAGER,//XXXOne默认是EAGER,立即加载Order
optional=false)//optional为true,就是允许Order这个字段为空,false不允许这个字段为null
@JoinColumn(name="orderId")//设置外键名称
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
/********************************************************************/
package cn.itcast.bean.order;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="t_order")//order与数据库关系字冲突,改数据库名称
public class Order {
private Integer orderId;
private Float amount = 0f;
private Set<OrderItem> items = new HashSet<OrderItem>();
@Id @GeneratedValue
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
@Column(nullable=false)
public Float getAmount() {
return amount;
}
public void setAmount(Float amount) {
this.amount = amount;
}
@OneToMany(cascade={CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE},
fetch=FetchType.LAZY,
mappedBy="order")//xxxMany后面是Many的话默认都是延迟加载,保证EntityManager未关闭,XXXOne是EAGER立即加载;
//如果类中有mappedBy那就是关系被维护端,应该是少的一方。"order"指明关系维护由下面OrderItem类中的order这个属性来维护
public Set<OrderItem> getItems() {
return items;
}
public void setItems(Set<OrderItem> items) {
this.items = items;
}
public void addOrderItem(OrderItem orderItem) {
orderItem.setOrder(this);//OrderItem是外键维护端,要建立关系
this.items.add(orderItem);
}
}
2.m:n 双向多对多
双方面是对等的关系,自行决定关系维护端。采用中间表(关联表)来存在它们之间的关系定义。
学生A,老师B
假如我们选定学生为关系维护端,那么如何在中间表中插入一条数据呢?
学生A.getTeachers().add(老师B), 在数据库就会执行insert into ……
如果学生如果要删除这个老师
学生A.getTeachers().remove(老师B),在数据库就会执行delete from ……
package cn.itcast.bean;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class Student {
private Integer id;
private String name;
private Set<Teacher> teachers = new HashSet<Teacher>();
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(nullable=false,length=30)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany(cascade=CascadeType.REFRESH)
@JoinTable(name="student_teacher1",
inverseJoinColumns=@JoinColumn(name="teacherId"),
joinColumns=@JoinColumn(name="studentId"))
//@JoinTable定义中间表,name表名称,inverseJoinColumns是被维护端老师,joinColumns是维护端学生,
//在中间表中默认名称XXX_id,可以更改名称
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
/*****************************************************/
package cn.itcast.bean;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Teacher {
private Integer id;
private String name;
private Set<Student> students = new HashSet<Student>();
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(nullable=false, length=30)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")
//老师是被维护端,由学生的teachers属性来维护,级联操作只能有更新,其它的出问题。
//如果有级联删除,那么在删除老师的时候会删除他的学生
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
3.复合主键:
比如说航线,主键就是由出发点和终点定义的
复合主键我们一般要把它放到一个复合主键类中,这个类必须要遵守的JPA规范:
·要实现Serializable 序列化接口
·要重写hashCode()和equals()方法:用ctrl+shift+s h 自动生成,选择包括的主键
·要保证有无参的构造方法
package cn.itcast.bean;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class AirLinePK implements Serializable {
private String start;
private String end;
public AirLinePK() {}
public AirLinePK(String start, String end) {
this.start = start;
this.end = end;
}
@Column(length=3)
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
@Column(length=3)
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((end == null) ? 0 : end.hashCode());
result = prime * result + ((start == null) ? 0 : start.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final AirLinePK other = (AirLinePK) obj;
if (end == null) {
if (other.end != null)
return false;
} else if (!end.equals(other.end))
return false;
if (start == null) {
if (other.start != null)
return false;
} else if (!start.equals(other.start))
return false;
return true;
}
}
package cn.itcast.bean;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
public class AireLine {
private AirLinePK id;
private String name;
//要保证有一个无参数的构造方法
public AireLine(){}
//为了方便保存数据我们添加这个构造方法
public AireLine(String start, String end, String name) {
this.id = new AirLinePK(start, end);
this.name = name;
}
@EmbeddedId
public AirLinePK getId() {
return id;
}
public void setId(AirLinePK id) {
this.id = id;
}
@Column(length=20)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- JPA 学习日志 5
- JPA 学习日志 1
- JPA 学习日志2
- JPA 学习日志3
- JPA 学习日志 4
- JPA学习1-5
- JPA日志批量入库
- JPA学习
- JPA学习
- JPA学习
- JPA学习
- JPA学习
- JPA学习
- JPA学习
- JPA学习
- JPA学习
- 学习JPA
- JPA学习笔记-JPA基础
- JPA 学习日志3
- Flex 三种导航容器 ViewStack TabNavigator Accordion
- 思考微内核
- JPA 学习日志 4
- automake编译脚本
- JPA 学习日志 5
- 查找数组最大值最小值:时间复杂度最多为:o(3n/2)
- Oracle中日期时间的操作比较和加减
- SQL Server 2005 如何创建分区表
- Layer Programming with Quartz Core
- Struts2支持表单多对象提交
- 在Windows Mobile上监听Radio Interface Layer Notification
- 【数据结构总结】堆栈
- UNIX 技巧: UNIX 高手的另外 10 个习惯