映射關係(關聯映射,使用xml文件進行配置)
(1)一對一映射(一個公司對應一個地址,地址和公司的關係是一對一)
第一步:建立類
公司類:
//一對一 xml配置
public class CompanyXML {
private int id;
private String name;
private AddressXML addressId;
public 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;
}
public AddressXML getAddressId() {
return addressId;
}
public void setAddressId(AddressXML addressId) {
this.addressId = addressId;
}
}
地址類:
//一對一 xml配置
public class AddressXML {
private int id;
private String city;
private String country;
private CompanyXML companyXML;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public void setCompanyXML(CompanyXML companyXML) {
this.companyXML = companyXML;
}
public CompanyXML getCompanyXML() {
return companyXML;
}
}
第二步:映射文件
公司類映射文件:(CompanyXML.hbm.xml)
<hibernate-mapping package="hibernate.test.domain">
<class name="CompanyXML" table="companyXML" lazy="true">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<many-to-one name="addressId" class="AddressXML" cascade="all" unique="true">
<column name="address"></column>
</many-to-one>
<!-- <one-to-one name="addressId" class="AddressXML" property-ref="companyXML" cascade="all"></one-to-one> -->
</class>
</hibernate-mapping>
地址類映射文件(AddressXML.hbm.xml):
<hibernate-mapping package="hibernate.test.domain">
<class name="AddressXML" table="addressXML" lazy="true">
<id name="id">
<generator class="native"></generator>
</id>
<property name="city"></property>
<property name="country"></property>
<one-to-one name="companyXML" class="CompanyXML" property-ref="addressId" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
說明: 基於外鍵的1——1關聯,外鍵可以存放在任意一端,
1、 存放的一端要增加many-to-one元素,並添加unique=”true“,column="映射到本表的字段名"
2、另一端使用one-to-one元素,使用property-ref指定引用關聯類的屬性;
第三步:配置文件(hibernate.cfg.xml)
添加兩個映射:<mapping resource="hibernate/test/xml/AddressXML.hbm.xml"></mapping>
<mapping resource="hibernate/test/xml/CompanyXML.hbm.xml"></mapping>
第四步:測試
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=null;
Transaction tx=null;
try {
session=HibernateAnnocationUtil.getSession();
tx=session.beginTransaction();
AddressXML addressXML=new AddressXML();
addressXML.setCity("zhengzhou2");
addressXML.setCountry("zhengzhou1");
CompanyXML companyXML=new CompanyXML();
companyXML.setName("yizhilian");
companyXML.setAddressId(addressXML);
session.save(companyXML);
tx.commit();
} catch (Exception e) {
// TODO: handle exception
if(tx!=null)
{
tx.rollback();
}
throw e;
}
finally{
if(session!=null)
{
session.close();
}
}
(2)一對多映射(多對一映射)
第一步:建立類(一個部門中有多個員工,部門與員工之間是一對多的關係)
部門類:
public class Department {
private int deptid;
private String dname;
private String location;
private Set<Employee> employees=new HashSet<Employee>();
public int getDeptid() {
return deptid;
}
public void setDeptid(int deptid) {
this.deptid = deptid;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
員工類:
public class Employee {
private int id;
private String name;
private String job;
private Department department;
public 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;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public void setDepartment(Department department) {
this.department = department;
}
public Department getDepartment() {
return department;
}
}
第二步:映射文件
部門類映射文件(Department.hbm.xml):
<hibernate-mapping package="hibernate.test.domain">
<class name="Department" table="Department" lazy="true">
<id name="deptid">
<generator class="native"></generator>
</id>
<property name="dname" type="java.lang.String"></property>
<property name="location" type="java.lang.String"></property>
<set name="employees" cascade="save-update" inverse="true">
<key>
<column name="department"></column>
</key>
<one-to-many class="Employee"></one-to-many><!-- 表明關係 -->
</set>
</class>
</hibernate-mapping>
員工類映射文件(Employee.hbm.xml):
<hibernate-mapping package="hibernate.test.domain">
<class name="Employee" table="Employee" lazy="true">
<id name="id">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String"></property>
<property name="job" type="java.lang.String"></property>
<many-to-one name="department" class="Department" cascade="save-update" >
<column name="deptid"></column>
</many-to-one>
</class>
</hibernate-mapping>
說明: 基於外鍵的1——N關聯,外鍵存放在多的那一端,
1、 存放的一端(也就是多的一端)要增加many-to-one元素,column="映射到本表的字段名" (也可以不指定)
2、另一端使用set元素,使用key.column指定關聯的外鍵列,在one-to-many中指明用以映射到關聯類的屬性;
第三步:配置文件(hibernate.cfg.xml)
<mapping resource="hibernate/test/xml/Employee.hbm.xml"></mapping>
<mapping resource="hibernate/test/xml/Department.hbm.xml"></mapping>
第四步:測試
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=null;
Transaction tx=null;
try {
session=HibernateUtil.getSession();
tx=session.beginTransaction();
Department department=new Department();
department.setDname("技術部");
department.setLocation("zhengzhou");
session.save(department);
Employee employee1=new Employee();
employee1.setName("張三");
Employee employee2=new Employee();
employee2.setName("李四");
employee1.setDepartment(department);
employee2.setDepartment(department);
session.save(employee1);
session.save(employee2);
tx.commit();
} catch (Exception e) {
// TODO: handle exception
if(tx!=null)
tx.rollback();
}
finally{
if(session!=null)
session.close();
}
}
(3)多對多映射
第一步:建立類(學生和課程是多對多的關係)
學生類:
public class StudentXML {
private int id;
private String name;
private Set<CourseXML> courseXMLs=new HashSet<CourseXML>();
public 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;
}
public void setCourseXMLs(Set<CourseXML> courseXMLs) {
this.courseXMLs = courseXMLs;
}
public Set<CourseXML> getCourseXMLs() {
return courseXMLs;
}
}
課程類:
public class CourseXML {
private int id;
private String name;
private Set<StudentXML> studentXMLs=new HashSet<StudentXML>();
public 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;
}
public Set<StudentXML> getStudentXMLs() {
return studentXMLs;
}
public void setStudentXMLs(Set<StudentXML> studentXMLs) {
this.studentXMLs = studentXMLs;
}
}
第二步:映射文件
學生類映射文件(StudentXML.hbm.xml):
<hibernate-mapping package="hibernate.test.domain">
<class name="StudentXML" table="studentXML" lazy="true">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="courseXMLs" table="stu_coursexml" cascade="save-update">
<!-- 指定關聯的外鍵列 -->
<key column="studentId"/><!-- key.column指出本類提供中間表的字段-->
<many-to-many class="CourseXML" column="courseId"></many-to-many>
</set>
</class>
</hibernate-mapping>
課程類映射文件(CourseXML.hbm.xml):
<hibernate-mapping package="hibernate.test.domain">
<class name="CourseXML" table="courseXML" lazy="true">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="studentXMLs" table="stu_coursexml" cascade="save-update">
<key column="courseId"/> <!-- key.column指出本類提供中間表的字段-->
<many-to-many class="StudentXML" column="studentId"></many-to-many>
</set>
</class>
</hibernate-mapping>
說明: 基於外鍵的N——N關聯,兩個表的主鍵作爲第三張表進行存儲
1、 一端使用set元素,使用key.column指出本類提供中間表的字段,在many-to-many中指明用以映射到關聯類的屬性,而many-to-many中的column屬性指的是class類在第三張表(中間表)中的字段;
2、另一端和前面一樣,需要制定本類和關聯類在第三張表中的屬性。兩者配置時要注意屬性對應,第三張表的表名一樣。
第三步:配置文件(hibernate.cfg.xml)
<mapping resource="hibernate/test/xml/CourseXML.hbm.xml"></mapping>
<mapping resource="hibernate/test/xml/StudentXML.hbm.xml"></mapping>
第四步:測試
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=null;
Transaction tx=null;
try {
session=HibernateAnnocationUtil.getSession();
tx=session.beginTransaction();
StudentXML student2=new StudentXML();
student2.setName("zhangsan");
StudentXML student22=new StudentXML();
student22.setName("liuyang");
CourseXML course=new CourseXML();
course.setName("語文");
//course.setName("數學");
HashSet<CourseXML> courses=new HashSet<CourseXML>();
courses.add(course);
student2.setCourseXMLs(courses);
student22.setCourseXMLs(courses);
session.save(student2);
session.save(student22);
tx.commit();
} catch (Exception e) {
// TODO: handle exception
if(tx!=null)
tx.rollback();
}
finally{
if(session!=null)
session.close();
}
}
(4)Cascade和inverse
詳細見: http://www.cnblogs.com/amboyna/archive/2008/02/18/1072260.html
級聯指的是當主控方執行操作時,關聯對象(被動方)是否同步執行同一操作。
cascade定義的是關係兩端對象到對象的級聯關係;而inverse定義的是關係和對象的級聯關係
Cascade:
all : 所有情況下均進行關聯操作。
none:所有情況下均不進行關聯操作。這是默認值。
save-update:在執行save/update/saveOrUpdate時進行關聯操作。
delete:在執行delete時進行關聯操作。
all的意思是save-update + delete
all-delete-orphan 的意思是當對象圖中產生孤兒節點時,在數據庫中刪除該節點
Inverse:
只有集合標記(set/map/list/array/bag)纔有inverse屬性
commit後,這兩個屬性發揮作用的時機不同,hibernate會根據對pojo對象的改動,及cascade屬性的設置,生成一系列的Action,比如UpdateAction,DeleteAction,InsertAction等,每個Action都有execute方法以執行對應的sql語句。待所有這些Action都生成好了後,hibernate再一起執行它們,在執行sql前,inverse屬性起作用,
當inverse=true時,不執行sql;當inverse=false時,執行sql。 inverse的默認值爲false,所以inverse屬性默認會進行“關聯更新”。