標籤:get 簡單 port gets tools rate this 建立 out
一.概述
單向一對多,雙向多對多我就不寫了,網上好多。一對多,多對一都是為了表級完整性,防止資料冗餘,無意義資料記錄的產生。作用其實就是相當於前台的表單驗證,你輸了一個密碼,這個密碼在表裡不存在,會出錯。
一對多和多對一都是在多那一段的表建立外部索引鍵關聯,就是去維護資料方不同。
單向一對多:當一這一端的對象需要用到多這一端的對象。比如班級類對象,一個班級有很多學生,我想在載入班級的時候順便載入所有的學生,顯示他們的名字,這樣的話我們就要在班級對象裡存放一個集合屬性,用來存放相關班級的所有學生了。
我這裡用的是list,對應你實際的例子用對應的最好的東西,list是有序可以重複,set是無序不可以重複,因為不能重複所以往往用set
二.代碼
1.單向一對多。
①class.java--班級類,代表一這端
package com.st.test;import java.util.ArrayList;import java.util.List;public class Class { private int id;//自增主鍵 private String className;//班級名 private List<Student> students=new ArrayList<Student>();//一對多中用到的多一端的對象 //對應getter,setter public int getId() { return id; } public void setId(int id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { System.out.println(students.size()); for(Student s:students){ System.out.println("設定studnets+"+s.getStudentname()); } this.students = students; } }
②student.java
package com.st.test;public class Student { private int id;//主鍵 private String studentname;//學生名 //對應gettter,setter public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStudentname() { return studentname; } public void setStudentname(String studentname) { this.studentname = studentname; }}
③Class.hbm.xml--關鍵的xml配置:在一這一段配置一對多。注釋挺清楚了。
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2017-4-24 15:36:01 by Hibernate Tools 3.5.0.Final --><hibernate-mapping> <!-- 下面就是這個class對應的配置 --> <class name="com.st.test.Class" table="CLASS"> <!-- 下面這個節點是配置主鍵 --> <id name="id" type="int"> <column name="ID" /> <generator class="identity" /> </id> <!-- 普通的屬性配置 --> <property name="className" type="java.lang.String"> <column name="CLASSNAME" /> </property> <!-- 下面是個重要的點:key裡的column表示你想在student表裡作為外部索引鍵關聯的那列的列名,別用自動產生的’ID‘這個名字,會和student的自增主鍵id衝突 --> <list name="students" inverse="false" table="STUDENT" lazy="true"> <key> <column name="class_id" /> </key> <!-- 這個是用list做集合時會有的,它會在表後面再加一列idx,作為元素在list裡的位子。 --> <list-index></list-index> <one-to-many class="com.st.test.Student" /> </list> </class></hibernate-mapping>
④Student.hbm.xml---用自動產生的就行 不用改什麼的。
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2017-4-24 13:55:39 by Hibernate Tools 3.5.0.Final --><hibernate-mapping> <class name="com.st.test.Student" table="STUDENT"> <id name="id" type="int"> <column name="ID" /> <generator class="identity" /> </id> <property name="studentname" type="java.lang.String"> <column name="STUDENTNAME" /> </property> </class></hibernate-mapping>
⑤測試代碼
package com.st.test;import java.util.ArrayList;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.springframework.transaction.annotation.Transactional;@Transactionalpublic class Test { public static void main(String[] args) { Configuration cfg = new Configuration(); cfg.configure();//此處不指定,會預設讀取src根目錄下名為hibernate.cfg.xml的檔案。也可以指定如:cfg.configure(“hibernate.xml”); SessionFactory sessionfactory = cfg.buildSessionFactory(); Session session=sessionfactory.openSession(); session.beginTransaction();//事務開始 //先聲明要用到的多的一端的對象,並且儲存,不儲存,這個對象還是游離對象 Student s1=new Student(); s1.setStudentname("student1"); Student s2=new Student(); s2.setStudentname("student2"); session.save(s1); session.save(s2); //student對象聲明結束 //list是因為我們要設定這個班級的屬性student學生集合時用的 List<Student> list=new ArrayList<Student>(); list.add(s1); list.add(s2); //聲明一端對象class,並且儲存到資料庫 Class c=new Class(); c.setClassName("class1"); c.setStudents(list); session.save(c); session.getTransaction().commit();//事務提交,這之後資料庫就會改變 }}
⑥sql語句
Hibernate: insert into STUDENT (STUDENTNAME) values (?)Hibernate: insert into STUDENT (STUDENTNAME) values (?)Hibernate: insert into CLASS (CLASSNAME) values (?)Hibernate: update STUDENT set class_id=?, idx=? where ID=?Hibernate: update STUDENT set class_id=?, idx=? where ID=?
*從這裡我們也可以看出,由一這一端去維護後面要多用update語句去更新對應的student的外部索引鍵關聯列,這裡還好只是2個對象,要是多了,這update語句就可怕了。所以多對一比一對多要好一些的。
*還有就是,在student表的那個外鍵class_id不可以設定為not null,因為設定了非空約束的話,一開始的儲存student對象就會出錯,因為你儲存student時是暫時沒有設定外部索引鍵關聯的那個class的id值的
三.總結
這是我在測試hibernate,單向一對多,單向多對一,雙向多對多過程中,單向一對多是唯一不小心出錯的,簡單記錄下,這個東西網上有很多的參考。前輩們路過,有錯的地方請指正,謝謝大家。
qq:2656062151 email:[email protected] (非問問題勿擾)
hibernate--單向一對多