在數(shù)據(jù)庫中,表表之間是通過外鍵關(guān)聯(lián)的,在程序中是要轉(zhuǎn)化為持久化類也就是(java Bean)來實(shí)例的。
但在Hibernater中持久化的之間的映射關(guān)系,不是通外鍵建立關(guān)聯(lián),而是通過屬性.主要有以下幾種
關(guān)聯(lián)方向:
班級表,和學(xué)生表,學(xué)生生通過班級表中的,班級編號為外鍵
--班級表create table grade( gid number PRimary key, --班級ID gname varchar2(50), --班級名稱 gdesc varchar2(50) --班級介紹);--學(xué)生表create table student( sid number primary key, --主鍵ID學(xué)生ID sname varchar2(20), --學(xué)生姓名 sex varchar2(20), --學(xué)生性別 gid number references grade(gid) ---外鍵班級ID);2.2、建立持久化類和映射配置文件
班級和學(xué)生類

package entity;import java.util.HashSet;import java.util.Set;/* * 班級類 */public class Grade implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L; private int gid; private String gname; private String gdesc; private Set<Student> students = new HashSet<Student> (); // Constructors /** default constructor */ public Grade() { } /** minimal constructor */ public Grade(int gid) { this.gid = gid; } /** full constructor */ public Grade(int gid, String gname, String gdesc, Set<Student> students) { this.gid = gid; this.gname = gname; this.gdesc = gdesc; this.students = students; } // Property accessors public int getGid() { return this.gid; } public void setGid(int gid) { this.gid = gid; } public String getGname() { return this.gname; } public void setGname(String gname) { this.gname = gname; } public String getGdesc() { return this.gdesc; } public void setGdesc(String gdesc) { this.gdesc = gdesc; } public Set<Student> getStudents() { return this.students; } public void setStudents(Set<Student> students) { this.students = students; }}View Code學(xué)生類

package entity;/* * 學(xué)生類 */public class Student implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L; private int sid; private String sname; private String sex; // Constructors /** default constructor */ public Student() { } /** minimal constructor */ public Student(int sid) { this.sid = sid; } /** full constructor */ public Student(int sid, String sname, String sex ) { this.sid = sid; this.sname = sname; this.sex = sex; } // Property accessors public int getSid() { return this.sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return this.sname; } public void setSname(String sname) { this.sname = sname; } public String getSex() { return this.sex; } public void setSex(String sex) { this.sex = sex; }}View Codehibernate.cf.xml和班級、學(xué)生的配置文件
<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory> <property name="dialect"> org.hibernate.dialect.Oracle9Dialect </property> <property name="connection.url"> jdbc:oracle:thin:@localhost:1521:orcl </property> <property name="connection.username">root</property> <property name="connection.passWord">root</property> <property name="connection.driver_class"> oracle.jdbc.OracleDriver </property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="entity/Grade.hbm.xml" /> <mapping resource="entity/Student.hbm.xml" /></session-factory></hibernate-configuration>
持久類配置先來學(xué)生類
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Student" table="STUDENT" schema="ROOT"> <id name="sid" type="java.lang.Integer"> <column name="SID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="sname" type="java.lang.String"> <column name="SNAME" length="20" /> </property> <property name="sex" type="java.lang.String"> <column name="SEX" length="20" /> </property> </class></hibernate-mapping>
班級類配置
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Grade" table="GRADE" schema="ROOT"> <id name="gid" type="java.lang.Integer"> <column name="GID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="gname" type="java.lang.String"> <column name="GNAME" length="50" /> </property> <property name="gdesc" type="java.lang.String"> <column name="GDESC" length="50" /> </property> <!--建立set屬性,也可以建立list和持久化類中一致就行 --> <set name="students"> <key> <!--這里的列是指學(xué)生表中的班級編號 --> <column name="GID" precision="22" scale="0" /> </key> <!-- 通過class屬性指定set的屬性 --> <one-to-many class="entity.Student" /> </set> </class></hibernate-mapping>
測試類
package Test;import java.util.Set;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import entity.Grade;import entity.Student;public class Demo1 { /** * 測試類 */ public static void main(String[] args) { save(); find(); update(); } public static void save() { // 聲明班級對象,并賦值 Grade grade = new Grade(); grade.setGid(201504); grade.setGname("Java一班"); grade.setGdesc("剛開始學(xué)習(xí)JAVA"); // 聲明2個學(xué)生對象 Student stu1 = new Student(); stu1.setSid(201504012); stu1.setSname("張三"); stu1.setSex("男"); Student stu2 = new Student(); stu2.setSid(201504013); stu2.setSname("李四"); stu2.setSex("女"); // 將學(xué)生添加到班級 grade.getStudents().add(stu1); grade.getStudents().add(stu2); // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); // 開始事務(wù) Transaction transaction = session.beginTransaction(); // 保存班級 session.save(grade); // 保存學(xué)生 session.save(stu1); session.save(stu2); // 提交事務(wù) transaction.commit(); // 關(guān)閉session session.close(); } /* * 將基中一個學(xué)生更改為別一個班級 */ public static void update() { // 聲明班級對象,并賦值 Grade grade = new Grade(); grade.setGid(201506); grade.setGname("Java二班"); grade.setGdesc("學(xué)習(xí)JAVA二年級"); // 獲取一個學(xué)生的信息 // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); // 開始事務(wù) Transaction transaction = session.beginTransaction(); Student stu1=(Student) session.get(Student.class, 201504013); //將學(xué)生添加到這個新的班級 grade.getStudents().add(stu1); // 保存班級 session.save(grade); // 保存學(xué)生 session.save(stu1); // 提交事務(wù) transaction.commit(); // 關(guān)閉session session.close(); } // 查詢班級 public static void find() { // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); Grade g = (Grade) session.get(Grade.class, 201504); System.out.println("班級信息:" + g.getGid() + "/t" + g.getGname() + g.getGdesc()); // 通過班級獲取這個班級的學(xué)生信息 System.out.println("201504班的學(xué)生信息如下:"); Set<Student> set = g.getStudents(); for (Student stu : set) { System.out.println(stu.getSid() + "/t" + stu.getSname() + "/t" + stu.getSex()); } }}以上只上單向關(guān)聯(lián),一般都會有雙向關(guān)聯(lián)
同樣要在學(xué)生類中添加Grade 屬性
在學(xué)生類的配置文件中配置關(guān)聯(lián)字段
二、建立雙向關(guān)聯(lián)2.1、更改學(xué)生類和配置文件package entity;/* * 學(xué)生類 */public class Student implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L; private int sid; private String sname; private String sex; //增加班級屬性 private Grade grade; // Constructors /** default constructor */ public Student() { } /** minimal constructor */ public Student(int sid) { this.sid = sid; } /** full constructor */ public Student(int sid, String sname, String sex ) { this.sid = sid; this.sname = sname; this.sex = sex; } // Property accessors public int getSid() { return this.sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return this.sname; } public void setSname(String sname) { this.sname = sname; } public String getSex() { return this.sex; } public void setSex(String sex) { this.sex = sex; } public Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; } }配置文件
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Student" table="STUDENT" schema="ROOT"> <id name="sid" type="java.lang.Integer"> <column name="SID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="sname" type="java.lang.String"> <column name="SNAME" length="20" /> </property> <property name="sex" type="java.lang.String"> <column name="SEX" length="20" /> </property> <!--配置grade屬性 --> <many-to-one name="grade" class="entity.Grade"> <!--指定學(xué)生表中的外鍵 --> <column name="GID" /> </many-to-one> </class></hibernate-mapping>2.2、測試類
建立雙向關(guān)聯(lián)后,就可以通過學(xué)生來獲取班級信息
清空數(shù)據(jù)表中的數(shù)據(jù)
package Test;import org.hibernate.Session;import org.hibernate.cfg.Configuration;import entity.Student;public class Demo2 { /** * 測試類 */ public static void main(String[] args) { save();findByStu(); } public static void findByStu(){ Session session = new Configuration().configure().buildSessionFactory() .openSession(); //獲取一個學(xué)生的信息 get方法為通過主鍵查詢 Student stu=(Student) session.get(Student.class, 201504013); System.out.println("學(xué)生信息:/t"+stu.getSid()+"/t"+stu.getSname()+"/t"+stu.getSex()); //通過學(xué)生信息得到班級信息 System.out.println("這個學(xué)生的班級信息:"+stu.getGrade().getGid()+"/t"+stu.getGrade().getGname()+"/t"+stu.getGrade().getGdesc()); }}public static void save() {// 聲明班級對象,并賦值Grade grade = new Grade();grade.setGid(201504);grade.setGname("Java一班");grade.setGdesc("剛開始學(xué)習(xí)JAVA");// 聲明2個學(xué)生對象Student stu1 = new Student();stu1.setSid(201504012);stu1.setSname("張三");stu1.setSex("男");stu1.setGrade(grade);Student stu2 = new Student();stu2.setSid(201504013);stu2.setSname("李四");stu2.setSex("女");stu2.setGrade(grade);// 將學(xué)生添加到班級/*grade.getStudents().add(stu1);grade.getStudents().add(stu2);*/// 建立sessionSession session = new Configuration().configure().buildSessionFactory().openSession();// 開始事務(wù)Transaction transaction = session.beginTransaction();// 保存班級session.save(grade);// 保存學(xué)生session.save(stu1);session.save(stu2);// 提交事務(wù)transaction.commit();// 關(guān)閉sessionsession.close();}三、級聯(lián)保存和刪除能不能只保存學(xué)生時(shí),同時(shí)保存班級呢,或者保存班級時(shí),同時(shí)保存學(xué)生呢3.1、cascade屬性

保存班級時(shí),同時(shí)保存學(xué)生信息
修改班級配置,在set標(biāo)簽中添加cascade屬性,設(shè)置為save-update
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Grade" table="GRADE" schema="ROOT"> <id name="gid" type="java.lang.Integer"> <column name="GID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="gname" type="java.lang.String"> <column name="GNAME" length="50" /> </property> <property name="gdesc" type="java.lang.String"> <column name="GDESC" length="50" /> </property> <!--建立set屬性,也可以建立list和持久化類中一致就行 --> <set name="students" cascade="save-update"> <key> <!--這里的列是指學(xué)生表中的班級編號 --> <column name="GID" precision="22" scale="0" /> </key> <!-- 通過class屬性指定set的屬性 --> <one-to-many class="entity.Student" /> </set> </class></hibernate-mapping>
測試類
package Test;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import entity.Grade;import entity.Student;public class Demo3 { /** * @param args */ public static void main(String[] args) { save(); } public static void save() { // 聲明班級對象,并賦值 Grade grade = new Grade(); grade.setGid(201504); grade.setGname("Java一班"); grade.setGdesc("剛開始學(xué)習(xí)JAVA"); // 聲明2個學(xué)生對象 Student stu1 = new Student(); stu1.setSid(201504012); stu1.setSname("張三"); stu1.setSex("男"); stu1.setGrade(grade); Student stu2 = new Student(); stu2.setSid(201504013); stu2.setSname("李四"); stu2.setSex("女"); stu2.setGrade(grade); // 將學(xué)生添加到班級 grade.getStudents().add(stu1); grade.getStudents().add(stu2); // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); // 開始事務(wù) Transaction transaction = session.beginTransaction(); // 保存班級 session.save(grade); // 保存學(xué)生 //session.save(stu1); //session.save(stu2); // 提交事務(wù) transaction.commit(); // 關(guān)閉session session.close(); }}反之,在學(xué)生類的配置文件one-many中添加cascade屬性設(shè)置為save-update
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Student" table="STUDENT" schema="ROOT"> <id name="sid" type="java.lang.Integer"> <column name="SID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="sname" type="java.lang.String"> <column name="SNAME" length="20" /> </property> <property name="sex" type="java.lang.String"> <column name="SEX" length="20" /> </property> <!--配置grade屬性 --> <many-to-one name="grade" class="entity.Grade" cascade="save-update"> <!--指定學(xué)生表中的外鍵 --> <column name="GID" /> </many-to-one> </class></hibernate-mapping>

package Test;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import entity.Grade;import entity.Student;public class Demo3 { /** * @param args */ public static void main(String[] args) { save(); } public static void save() { // 聲明班級對象,并賦值 Grade grade = new Grade(); grade.setGid(201504); grade.setGname("Java一班"); grade.setGdesc("剛開始學(xué)習(xí)JAVA"); // 聲明2個學(xué)生對象 Student stu1 = new Student(); stu1.setSid(201504012); stu1.setSname("張三"); stu1.setSex("男"); stu1.setGrade(grade); Student stu2 = new Student(); stu2.setSid(201504013); stu2.setSname("李四"); stu2.setSex("女"); stu2.setGrade(grade); // 將學(xué)生添加到班級 grade.getStudents().add(stu1); grade.getStudents().add(stu2); // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); // 開始事務(wù) Transaction transaction = session.beginTransaction(); // 保存班級 //session.save(grade); // 保存學(xué)生 session.save(stu1); session.save(stu2); // 提交事務(wù) transaction.commit(); // 關(guān)閉session session.close(); }}View Code3.2、inverse屬性
首先在班級類中設(shè)置invers屬性為false時(shí),刪除班級

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Grade" table="GRADE" schema="ROOT"> <id name="gid" type="java.lang.Integer"> <column name="GID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="gname" type="java.lang.String"> <column name="GNAME" length="50" /> </property> <property name="gdesc" type="java.lang.String"> <column name="GDESC" length="50" /> </property> <!--建立set屬性,也可以建立list和持久化類中一致就行 --> <set name="students" cascade="save-update" inverse="false"> <key> <!--這里的列是指學(xué)生表中的班級編號 --> <column name="GID" precision="22" scale="0" /> </key> <!-- 通過class屬性指定set的屬性 --> <one-to-many class="entity.Student" /> </set> </class></hibernate-mapping>View Code
測試類

package Test;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import entity.Grade;import entity.Student;public class Demo4 { /** * @param args */ public static void main(String[] args) { delete() ; } public static void delete() { // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); // 開始事務(wù) Transaction transaction = session.beginTransaction(); // 保存班級 Grade grade=(Grade) session.get(Grade.class, 201504); // 保存學(xué)生 session.delete(grade); // 提交事務(wù) transaction.commit(); // 關(guān)閉session session.close(); }}View Code結(jié)果:發(fā)現(xiàn)班級表中的班級已經(jīng)刪除,而學(xué)生表中數(shù)據(jù)沒有刪除,只是GID字段為NULL
下面將inverse設(shè)置為true時(shí),添加新學(xué)生,和新的班級

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="entity.Grade" table="GRADE" schema="ROOT"> <id name="gid" type="java.lang.Integer"> <column name="GID" precision="22" scale="0" /> <generator class="assigned" /> </id> <property name="gname" type="java.lang.String"> <column name="GNAME" length="50" /> </property> <property name="gdesc" type="java.lang.String"> <column name="GDESC" length="50" /> </property> <!--建立set屬性,也可以建立list和持久化類中一致就行 --> <set name="students" cascade="save-update" inverse="true"> <key> <!--這里的列是指學(xué)生表中的班級編號 --> <column name="GID" precision="22" scale="0" /> </key> <!-- 通過class屬性指定set的屬性 --> <one-to-many class="entity.Student" /> </set> </class></hibernate-mapping>View Code
測試類

package Test;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import entity.Grade;import entity.Student;public class Demo4 { /** * @param args */ public static void main(String[] args) { delete() ; } public static void delete() { // 聲明班級對象,并賦值 Grade grade = new Grade(); grade.setGid(201509); grade.setGname("Java三班"); grade.setGdesc("asp.net"); // 聲明2個學(xué)生對象 Student stu1 = new Student(); stu1.setSid(201509009); stu1.setSname("王五"); stu1.setSex("女"); stu1.setGrade(grade); Student stu2 = new Student(); stu2.setSid(201509045); stu2.setSname("趙六"); stu2.setSex("女"); stu2.setGrade(grade); // 建立session Session session = new Configuration().configure().buildSessionFactory() .openSession(); // 開始事務(wù) Transaction transaction = session.beginTransaction(); // 保存學(xué)生 session.save(stu1); session.save(stu2); // 提交事務(wù) transaction.commit(); // 關(guān)閉session session.close(); }}View Code結(jié)果發(fā)現(xiàn),我并沒有用班級添加學(xué)生,也沒有保存班級,只是保存了學(xué)生,班級信息一起保存了
新聞熱點(diǎn)
疑難解答
圖片精選