通常在企业开发中,开发Dao层有两种做法: 
(1)先建表,后再根据表来编写配置文件和实体bean。使用这种方案的开发人员受到了传统数据库建模的影响。 
(2)先编写配置文件和实体bean,然后再生成表,使用这种方案的开发人员采用的是领域建模思想,这种思想相对前一种思想更加OOP。

建议使用第二种(领域建模思想),从软件开发来想,这种思想比第一种思想更加面向对象。 领域建模思想也是目前比较新的一门建模思想,第一种是传统的建模思想,已经有10来年的发展历程了,而领域建模思想是近几年才兴起的,这种思想更加的面向对象。

一、一对多双向关联与级联操作:

以订单类和订单商品类为例:

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

1、订单类:

@Entity
public class Orders {private String orderid;private Float amount = 0f;private Set<OrderItem> items=new HashSet<OrderItem>();@Id @Column(length=12)public String getOrderid() {return orderid;}public void setOrderid(String orderid) {this.orderid = orderid;}@Column(nullable=false)public Float getAmount() {return amount;}public void setAmount(Float amount) {this.amount = amount;}//REFRESH,级联刷新(调用refresh方法才会起作用);PERSIST,级联保存(persist);//MERGE,级联更新(merge方法);REMOVE,级联删除(remove方法);//级联:cascade={CascadeType.ALL})如果要使用上面四项的使用,可以使用ALL来代替//@OneToMany默认行为是延迟加载//mappedBy:指定关系被维护端,指定OrderItem里面的order,相当于hibernate的inverse放弃维护@OneToMany(cascade={CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},fetch=FetchType.LAZY,mappedBy="orders")public Set<OrderItem> getItems() {return items;}public void setItems(Set<OrderItem> items) {this.items = items;}public void addOrderItem(OrderItem orderItem){orderItem.setOrders(this);this.items.add(orderItem);}
}

2、订单列表类:

@Entity
public class OrderItem {private Integer id;private String productName;private Float sellPrice = 0f;private Orders orders;//对应Order类里面指定的关系被维护端@Id @GeneratedValuepublic 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;}//默认立即加载//optional=true,选项允许为null,false时,不能为null@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)@JoinColumn(name="order_id")//设置外键名称public Orders getOrders() {return orders;}public void setOrders(Orders orders) {this.orders = orders;}
}

3、一对多的测试类:

//JPA的Dao层
@Transactional
public class JpaDaoImpl implements JpaDao {//事务管理@PersistenceContextprivate EntityManager em;//JPA一对多测试类@Overridepublic void jpaTest() {Orders orders=new Orders();orders.setAmount(34f);orders.setOrderid("999");OrderItem orderItem1=new OrderItem();orderItem1.setProductName("篮球");orderItem1.setSellPrice(150f);OrderItem orderItem2=new OrderItem();orderItem2.setProductName("足球");orderItem2.setSellPrice(90f);orders.addOrderItem(orderItem1);orders.addOrderItem(orderItem2);em.merge(orders);}
}

由于配置了事务管理,这里就不需要手动开启、提交事务和关闭资源等重复的代码,直接交由事务进行管理。

具体配置步骤可以参看这篇博客:https://blog.csdn.net/a745233700/article/details/81415550

二、一对一双向关联与级联操作:

以身份证类和人为例:

1、Persion类:

@Entity
public class Person {public Person() {}public Person(String name) {this.name=name;}private Integer id;private String name;private IDcard idcard;@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=10,nullable=false)public String getName() {return name;}public void setName(String name) {this.name = name;}//一对一配置@OneToOne(optional=false,cascade={CascadeType.ALL})@JoinColumn(name="idcard_id")public IDcard getIdcard() {return idcard;}public void setIdcard(IDcard idcard) {this.idcard = idcard;}
}

2、IDcard类:

@Entity
public class IDcard {public IDcard() {}public IDcard(String cardno) {this.cardno = cardno;}private Integer id;private String cardno;private Person person;@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=18,nullable=false)public String getCardno() {return cardno;}public void setCardno(String cardno) {this.cardno = cardno;}//一对一配置:@OneToOne(mappedBy="idcard",cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}
}

3、一对一测试类:

   //JPA一对多测试类@Overridepublic void jpaTest() {Person person=new Person("小张");      person.setIdcard(new IDcard("448xxx1990xxxx1234"));em.persist(person);}

三、多对多双向关联与级联操作:

以教师类和学生类为例:

1、教师类:

//老师为关系被维护端
@Entity
public class Teacher {public Teacher(){}public Teacher(String name) {this.name = name;}private Integer id;private String name;private Set<Student> students=new HashSet<Student>();@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=10,nullable=false)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")public Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Teacher other = (Teacher) obj;if (id == null) {if (other.id != null)return false;} else if (!id.equals(other.id))return false;return true;}
}

2、学生类:

//学生为关系维护端
@Entity
public class Student {public Student(){}public Student(String name) {this.name = name;}private Integer id;private String name;private Set<Teacher> teachers=new HashSet<Teacher>();@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=10,nullable=false)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToMany(cascade=CascadeType.REFRESH)@JoinTable(name="student_teacher",//设置第三张表的表名inverseJoinColumns=@JoinColumn(name="teacher_id"),//设置被维护端在第三张表中的外键名称joinColumns=@JoinColumn(name="student_id"))//设置维护端在第三张表中的外键名称public Set<Teacher> getTeachers() {return teachers;}public void setTeachers(Set<Teacher> teachers) {this.teachers = teachers;}public void addTeacher(Teacher teacher){this.teachers.add(teacher);}public void removeTeacher(Teacher teacher){if(this.teachers.contains(teacher)){this.teachers.remove(teacher);}}
}

3、多对多测试类:

   //JPA多对多测试类:没有建立关系联系的添加@Overridepublic void jpaTest() {//没有建立关系联系的添加em.persist(new Student("小张"));em.persist(new Teacher("李老师"));}
   //JPA多对多测试类:建立学生跟老师的联系@Overridepublic void jpaTest() {//建立学生和老师的关系Student student=em.find(Student.class, 15);student.addTeacher(em.getReference(Teacher.class, 16));}
   //JPA多对多测试类:删除学生跟老师的联系@Overridepublic void jpaTest() {//删除学生跟老师的联系Student student=em.find(Student.class, 15);student.removeTeacher(em.getReference(Teacher.class, 16));}
   //JPA多对多测试类:删除对象:只删除教师//直接不接触外键,直接删除老师,这种方式删除不了,被维护端没有权限删除外键,抛异常@Overridepublic void jpaTest() {em.remove(em.getReference(Teacher.class, 16));}
   //JPA多对多测试类:删除对象:只删除教师//先解除学生与老师的关系,再删除教师对象@Overridepublic void jpaTest() {Student student=em.find(Student.class, 15);Teacher teacher=em.getReference(Teacher.class, 16);student.removeTeacher(teacher);em.remove(teacher);}
   //JPA多对多测试类:删除对象:学生,并删除第三表中的记录,不删除老师//关系维护端有权限删除外键@Overridepublic void jpaTest() {em.remove(em.getReference(Student.class, 15));}

四、联合主键:

以飞机航线为例:两个城市决定一条航线。

1、联合主键的三个要求:

(1)必须定义无参构造函数;

(2)必须实现序列化接口Serializable;

(3)必须重写hashCode()和equals()方法。

2、AirLinkPK联合主键类:

/*联合主键的三个要求:
1.必须定义无参构造函数
2.必须实现序列化接口Serializable
3.必须重写hashCode()和equals()方法
*/
@Embeddable
public class AirLinePK implements Serializable {        public AirLinePK(){}public AirLinePK(String startCity, String endCity) {this.startCity = startCity;this.endCity = endCity;}private String startCity;//开始城市private String endCity;//结束城市@Column(length=3)public String getStartCity() {return startCity;}public void setStartCity(String startCity) {this.startCity = startCity;}@Column(length=3)public String getEndCity() {return endCity;}public void setEndCity(String endCity) {this.endCity = endCity;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((endCity == null) ? 0 : endCity.hashCode());result = prime * result + ((startCity == null) ? 0 : startCity.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;AirLinePK other = (AirLinePK) obj;if (endCity == null) {if (other.endCity != null)return false;} else if (!endCity.equals(other.endCity))return false;if (startCity == null) {if (other.startCity != null)return false;} else if (!startCity.equals(other.startCity))return false;return true;}
}

3、AirLine类:

@Entity
public class AirLine {public AirLine(){}public AirLine(AirLinePK id) {this.id = id;}public AirLine(String startCity,String endCity,String name){this.id=new AirLinePK(startCity,endCity);this.name=name;}private AirLinePK id;private String name;//联合主键的实体标识符@EmbeddedIdpublic 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;}
}

3、联合主键测试类:

   //联合主键测试类@Overridepublic void jpaTest() {em.persist(new AirLine("PEK","SHA","北京飞上海"));}

JPA规范:一对多、一对一、多对多的双向关联与级联操作以及JPA联合主键相关推荐

  1. jpa级联添加_JPA中的一对多双向关联与级联操作

    学习Spring有两周时间了 , 个人觉得服务端主要实现的是数据关系的维护和数据结构的制定 , 以及由业务需求产生的CRUD , 只要保证对前端提供的接口稳定高效响应 , 具体的前端实现完全不关心. ...

  2. EF里一对一、一对多、多对多关系的配置和级联删除

    EF里一对一.一对多.多对多关系的配置和级联删除 本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个Per ...

  3. 2019-7-27 [MySQL] DQL 简单查询[别名/去重/运算] 条件查询 排序查询 聚合查询 分组查询 导出与导入 多表操作[一对多/多对多][创外键 创联合主键 约束 添加 删除 测试]

    文章目录 5 SQL语句(DQL) 5.1DQL准备工作和语法 5.1.1准备工作 5.1.2 DQL语法: 5.2 简单查询 5.2.1 查询所有的商品 5.2.2 查询商品名和商品价格. 5.2. ...

  4. mysql 尽量不要使用 联合主键_MySQL 使用规范

    MySQL 使用规范 以下规范适用在线交易(OLTP)系统的数据库.数据仓库与分析系统也可以参考. 命名规范 表名.字段名.索引名使用小写字母.数字,采用下划线分割 表名采用模块名3个缩小字符_前缀, ...

  5. Hibernate关联关系配置(一对多,一对一,多对多)

    一对多 创建两个类  Manager(一这一端) Worker(多这一端)  即一个经理下有多个员工 package com.hibernate.n21;import java.util.HashSe ...

  6. springboot jpa 复合主键 联合主键

    为什么80%的码农都做不了架构师?>>>    在开发中,数据库中定义了一个复合主键,这时候在映射不稍微处理下会有一点问题.什么does not define an IdClass错 ...

  7. (5)hibernate多对一,一对多,一对一,多对多

    一 多对一关联 1 映射与原理分析 2 例子结构图 3代码 3.1 Department.java package com.learning;public class Department {priv ...

  8. 27.一对一,一对多,多对多关系表的各种骚操作

    1.关系表的数据操作 (1)一对多表关系的数据的添加修改 ①学院表信息的插入: 常规方法是写个视图函数,在视图函数里添加插入数据的逻辑代码.但是这样的话--你得访问此视图函数对应的接口才能添加成功!岂 ...

  9. JPA/Hibernate实体类定义联合主键@IdClass注解的使用

最新文章

  1. Dialog 去白色边框及透明
  2. Mycat探索之旅(3)----Mycat的全局序列号
  3. 为什么美国互联网没有“运营”岗?
  4. Py之docx:Python库之docx简介、安装、使用方法详细攻略
  5. java多线程流式写入文件夹_java多线程写入同一文件
  6. 红外线遥控c语言程序,红外遥控的C程序
  7. Java中线程池,你真的会用吗?
  8. 【转】POP3、SMTP和IMAP之间的区别和联系
  9. python客户画像_Python数据分析学习笔记05:用户画像
  10. windows2003 ftp 无法下载 解决
  11. airpods pro是按压还是触摸_为什么都不推荐购买AirPods Pro,看完这6个缺陷,你就明白了...
  12. ae去闪插件deflicker使用_AE去闪烁插件|RevisionFX DEFlicker(AE视频去闪烁插件) V1.4.12 官方版 下载_当下软件园_软件下载...
  13. 这一代系统,真的不行!(一)
  14. 大学四年因为知道了这 60 个网站,我成了别人眼中的大神!
  15. iPhone手机越狱不只是为了安装盗版应用、越狱的十大好处
  16. Windows补丁修复- Microsoft Windows HTTP.sys远程代码执行漏洞 (MS15-034)(CVE-2015-1635)
  17. java中倒三角形和正三角形_正三角形,倒三角形,以及正倒三角
  18. Java中split的用法
  19. Ubuntu18.04下的音频录制和编辑软件Ardour及QjackCtl(jackd gui)
  20. java 数组总结(赋值,反转,添加,查找)

热门文章

  1. 七十二、区间合并,插入求交集, 删除被覆盖区间
  2. 七十四、Python | Leetcode数字系列(下篇)
  3. 三十、Java 多线程编程(上篇)
  4. 算法工程师想拿百万高薪,5大维度评估竞争力,情商也很重要
  5. 10个快速提升技术水平的方法
  6. php mpdf html 转pdf,使用 MPDF 将HTML转为PDF,然后将该PDF转为PNG图片的时候,中文报错... ...汗血宝马...
  7. 樊登高效休息法心得400字_真的,你应该早点知道这个高效学习方法
  8. Spring Security + WebSocket——@MessageMapping中Authentication为NULL解决方案之一
  9. Windows Subsystem for Linux——[WslRegisterDistribution failed with error: 0x8007019e]解决方案
  10. 计算机网络(谢希仁第八版)第一章:概述