Hibernate 基础配置及常用功能(二)
本章主要是描述幾種經(jīng)典映射關(guān)系,順帶比較Hibernate4.x和Hibernate5.x之間的區(qū)別。
一、建立測試工程目錄
有關(guān)實體類之間的相互映射關(guān)系,Hibernate官方文檔其實描述的非常詳細,這里只提供幾種常見映射。(推薦4.3.11版本的 hibernate-release-4.3.11.Final\documentation\manual)
二、編寫映射關(guān)系
(1)one2one單表內(nèi)嵌映射:
package model.family;import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;@Entity public class Husband {private int id;private String husbandName;private Wife wife;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getHusbandName() {return husbandName;}public void setHusbandName(String husbandName) {this.husbandName = husbandName;}// 兩個實體對象共用一張數(shù)據(jù)表,提高查詢速度 @Embeddedpublic Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}} Husband.java package model.family;//不用添加任何注解,持久化過程通過主表完成 public class Wife {private String wifeName;public String getWifeName() {return wifeName;}public void setWifeName(String wifeName) {this.wifeName = wifeName;} } Wife.java(2)one2one外鍵映射:
package model.userinfo;import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Transient;@Entity public class User {private int id;private String username;private String password;private String confirm;private Information info;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}/** 延遲加載,級聯(lián)操作。 * 刪除開啟了級聯(lián)的一方,被級聯(lián)的一方也會被刪除* 注意:如果session的操作是通過hibernate控制,延遲加載不會出問題。如果是通過手工開啟實物,操作不當(dāng)延遲加載可能拋出懶加載異常*/@OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)public Information getInfo() {return info;}public void setInfo(Information info) {this.info = info;}// 本字段不參與持久化過程 @Transientpublic String getConfirm() {return confirm;}public void setConfirm(String confirm) {this.confirm = confirm;} } User.java package model.userinfo;import java.util.Date;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Temporal; import javax.persistence.TemporalType;//注解也可以直接配置在字段上,但是不推薦。據(jù)說原因是可能破壞oop封裝。但是我覺得有時這樣配置可以讓代碼顯得更加整潔,特別是在Spring中。 @Entity public class Information {@Id@GeneratedValueprivate int id;@OneToOneprivate User user;@Temporal(TemporalType.DATE)private Date resgisterDate;private String address;public int getId() {return id;}public void setId(int id) {this.id = id;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}public Date getResgisterDate() {return resgisterDate;}public void setResgisterDate(Date resgisterDate) {this.resgisterDate = resgisterDate;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}} Information.java(3)many2many多表映射:
場景描述:學(xué)校里有多個老師,每個老師教授多個學(xué)生,每個學(xué)生每一門課程會有一個得分。
package model.school;import java.util.HashSet; import java.util.Set;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany;@Entity public class Teacher {private int id;private String tchName;private Set<Student> students = new HashSet<Student>();@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getTchName() {return tchName;}public void setTchName(String tchName) {this.tchName = tchName;}//老師和學(xué)生的對應(yīng)表由學(xué)生一方負責(zé)維護@ManyToMany(mappedBy = "teachers")public Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}} Teacher.java package model.school;import java.util.HashSet; import java.util.Set;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany;@Entity public class Student {private int id;private String stuName;private Set<Teacher> teachers = new HashSet<Teacher>();private Set<Score> scores = new HashSet<Score>();@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}/** many2many必須使用中間表,配置中間表的表明和列名*/@ManyToMany@JoinTable(name = "student_teacher", joinColumns = { @JoinColumn(name = "studentId") }, inverseJoinColumns = {@JoinColumn(name = "teacherId") })public Set<Teacher> getTeachers() {return teachers;}public void setTeachers(Set<Teacher> teachers) {this.teachers = teachers;}// 學(xué)生同分數(shù)之間的關(guān)系同樣交給多的一方負責(zé)維護@OneToMany(mappedBy = "student")public Set<Score> getScores() {return scores;}public void setScores(Set<Score> scores) {this.scores = scores;}} Student.java package model.school;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne;@Entity public class Score {private int id;private int courseScore;private Teacher teacher;private Student student;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public int getCourseScore() {return courseScore;}public void setCourseScore(int courseScore) {this.courseScore = courseScore;}@ManyToOnepublic Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}@ManyToOnepublic Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}} Score.java按照以上的映射關(guān)系生成數(shù)據(jù)表以后會注意到,其實老師和學(xué)生之間的關(guān)系表純粹多余,分數(shù)表已經(jīng)維護了雙方的關(guān)系。重新優(yōu)化他們之間的映射關(guān)系:
package model.school;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;@Entity public class Teacher {private int id;private String tchName;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getTchName() {return tchName;}public void setTchName(String tchName) {this.tchName = tchName;}} Teacher.java package model.school;import java.util.HashSet; import java.util.Set;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany;@Entity public class Student {private int id;private String stuName;private Set<Score> scores = new HashSet<Score>();@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}@OneToMany(mappedBy = "student")public Set<Score> getScores() {return scores;}public void setScores(Set<Score> scores) {this.scores = scores;}} Student.java package model.school;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne;@Entity public class Score {private int id;private int courseScore;private Teacher teacher;private Student student;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public int getCourseScore() {return courseScore;}public void setCourseScore(int courseScore) {this.courseScore = courseScore;}@ManyToOnepublic Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}@ManyToOnepublic Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}} Score.java由此可見,即使是一個相對復(fù)雜的映射關(guān)系也可以通過優(yōu)化得到一個相對簡單的數(shù)據(jù)模型。
(4)many2one和one2many單表樹形映射:
場景描述:地圖,一個國家包含多個省份,每個省份又包含多個城市...
package model.tree;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.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table;@Entity @Table(name = "_tree") public class Tree {private int id;private String name;private Tree parent;private Set<Tree> children = new HashSet<Tree>();@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}@Column(name = "t_name", unique = true)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToOnepublic Tree getParent() {return parent;}public void setParent(Tree parent) {this.parent = parent;}//刪除根節(jié)點,與它相關(guān)的所有子節(jié)點全部刪除@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)public Set<Tree> getChildren() {return children;}public void setChildren(Set<Tree> children) {this.children = children;} } Tree.java注意:以上4種映射關(guān)系在4.3.11版本中正常。但在5.0.6版本中id字段被系統(tǒng)強制指定為了@GeneratedValue(strategy=GenerationType.TABLE)的方式。我曾經(jīng)嘗試手工指定生成策略為auto或者identity均無效。如果是通過xml的方式配置是正常的,目前我還不清楚是什么原因?qū)е碌纳鲜霎惓!_@個問題造成了下面的映射關(guān)系目前只能在4.x版本中正常使用:
(5)one2one主鍵映射
package model.personaddr;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn;@Entity public class Person {private int id;private String name;private Address address;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}// 兩張表通過主鍵關(guān)聯(lián)@OneToOne(optional = true)@PrimaryKeyJoinColumnpublic Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;} } Person.java package model.personaddr;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne;@Entity public class Address {private int id;private String local;private Person person;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getLocal() {return local;}public void setLocal(String local) {this.local = local;}@OneToOne(mappedBy = "address")public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}} Address.javaps:好在主鍵映射在實際使用中并不常見。
?
最后按照慣例,提供整個項目的完整目錄結(jié)構(gòu)和IDE版本信息
轉(zhuǎn)載于:https://www.cnblogs.com/learnhow/p/5120948.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Hibernate 基础配置及常用功能(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 医院看不孕病哪个好
- 下一篇: 麻烦大家跟我讲讲纳美宝贝和舒客宝贝哪个好