Hibernate學習(四)

映射關係(關聯映射,使用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();

}

}

 

    (4Cascadeinverse

詳細見: 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屬性默認會進行“關聯更新”。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章