前面的咱們使用的是一個表的操做,但咱們實際的開發中不可能只使用一個表的…所以,本博文主要講解關聯映射java
需求分析:當用戶購買商品,用戶可能有多個地址。數據庫
咱們通常以下圖同樣設計數據庫表,通常咱們不會在User表設計多個列來保存地址的。由於每一個用戶的地址個數都不一的,會形成數據冗餘markdown
因爲地址只是使用String類型來保存着,那麼咱們直接使用一個User對象就能夠了session
public class User { private String id; private String username; private String password; private Set<String> address; //各類setter和getter
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!--在domain包下--> <hibernate-mapping package="zhongfucheng.domain"> <class name="User" table="user"> <!--主鍵映射--> <id name="id" column="id" > <generator class="native"/> </id> <!--普通字段映射--> <property name="username" column="username"></property> <property name="password" column="password"></property> <!-- Set: name: 映射集合的名稱 table:集合的屬性要映射到哪張表(address) key: column:指定要映射的表(address)中的外鍵列 element:要映射的表的其餘字段 類型必定要指定! --> <set name="address" table="address"> <key column="user_id"></key> <element column="addr" type="string"></element> </set> </class> </hibernate-mapping>
package zhongfucheng.domain; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; /** * Created by ozc on 2017/5/6. */ public class App { public static void main(String[] args) { //建立對象 User user = new User(); user.setUsername("123"); user.setPassword("1234"); user.getAddress().add("廣州"); //獲取加載配置管理類 Configuration configuration = new Configuration(); //加載User的映射文件! configuration.configure().addClass(User.class); //建立Session工廠對象 SessionFactory factory = configuration.buildSessionFactory(); //獲得Session對象 Session session = factory.openSession(); //使用Hibernate操做數據庫,都要開啓事務,獲得事務對象 Transaction transaction = session.getTransaction(); //開啓事務 transaction.begin(); session.save(user); //提交事務 transaction.commit(); //關閉Session session.close(); } }
既然咱們如今已經會了如何配置Set集合了,List集合又怎麼配置呢??app
想一下,List集合和Set集合有什麼區別…List集合是有序的,所以要多配置一個列來維護數據的有序性!dom
<list name="address" table="address"> <key column="user_id"></key> <!--index是關鍵字,不能使用!!!!--> <list-index column="index"></list-index> <element column="addr" type="string"></element> </list>
Map集合和Collection集合的區別就是鍵值對模型,那麼在配置的時候多一個key便可!測試
<map name="address" table="address"> <key column="user_id" ></key> <map-key type="string" column="short"></map-key> <element type="string" column="addr"></element> </map>
上面咱們講解了集合映射是怎麼配置的,那集合裝載的元素有沒有多是對象呢??而不是簡單的String類型..那個就太多了!通常地,咱們集合裝載的都是對象,而不是簡單的String,若是咱們的裝載在集合的數據有不少類型,那麼String就不能用了!…ui
需求:部門與員工之間的關係this
員工表應該使用一個外鍵來記住部門表。這樣才能夠維護員工和部門之間的關係spa
部門實體要使用一個集合來記住全部的員工,員工要使用一個對象引用着部門
package zhongfucheng.domain; import java.util.HashSet; import java.util.Set; /** * Created by ozc on 2017/5/6. */ public class Dept { private int id ; private Set<Employee> set = new HashSet<>(); private String deptName; public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Set<Employee> getSet() { return set; } public void setSet(Set<Employee> set) { this.set = set; } }
package zhongfucheng.domain; /** * Created by ozc on 2017/5/6. */ public class Employee { private int id; private String empName; private double salary; private Dept dept; public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }
咱們在寫映射配置文件以前,分析一下怎麼寫。以部門映射配置文件爲例…
如今使用了一個Set集合來維護與員工的關係,Set集合的類型是員工對象…所以在映射文件中須要如下幾點
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!--在domain包下--> <hibernate-mapping package="zhongfucheng.domain"> <class name="Dept" table="dept"> <id column="id" name="id"> <generator class="native"> </generator> </id> <!--普通字段映射--> <property name="deptName" column="deptname"></property> <!--維護關係的是Set集合,對應employee表--> <set cascade="save-update" name="set" table="employee"> <!--employee的外鍵列是dept_no--> <key column="dept_no"></key> <!--一個部門對應多個員工,集合的類型是Employee--> <one-to-many class="Employee" ></one-to-many> </set> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!--在domain包下--> <hibernate-mapping package="zhongfucheng.domain"> <class name="Employee" table="employee"> <id column="id" name="id"> <generator class="native"> </generator> </id> <!--普通字段數據--> <property name="empName" column="empName"></property> <property name="salary" column="salary"></property> <!--Hibernate這個標籤可當作在當前表中設置一個外鍵dept_no--> <many-to-one name="dept" class="Dept" column="dept_no"></many-to-one> </class> </hibernate-mapping>
package zhongfucheng.domain; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; /** * Created by ozc on 2017/5/6. */ public class App { public static void main(String[] args) { //建立對象 Dept dept = new Dept(); dept.setDeptName("開發部"); Employee zs = new Employee(); zs.setEmpName("張珊"); zs.setSalary(1111); Employee ls = new Employee(); ls.setEmpName("李四"); ls.setSalary(2222); //添加關係 dept.getSet().add(zs); dept.getSet().add(ls); //獲取加載配置管理類 Configuration configuration = new Configuration(); //加載User的映射文件! configuration.configure().addClass(Dept.class).addClass(Employee.class); //建立Session工廠對象 SessionFactory factory = configuration.buildSessionFactory(); //獲得Session對象 Session session = factory.openSession(); //使用Hibernate操做數據庫,都要開啓事務,獲得事務對象 Transaction transaction = session.getTransaction(); //開啓事務 transaction.begin(); session.save(dept); session.save(zs); session.save(ls); //提交事務 transaction.commit(); //關閉Session session.close(); } }
Hibernate執行了5條SQL語句
package zhongfucheng.domain; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; /** * Created by ozc on 2017/5/6. */ public class App { public static void main(String[] args) { //建立對象 Dept dept = new Dept(); dept.setDeptName("開發部"); Employee zs = new Employee(); zs.setEmpName("張珊"); zs.setSalary(1111); Employee ls = new Employee(); ls.setEmpName("李四"); ls.setSalary(2222); //維護關係 zs.setDept(dept); ls.setDept(dept); //獲取加載配置管理類 Configuration configuration = new Configuration(); //加載User的映射文件! configuration.configure().addClass(Dept.class).addClass(Employee.class); //建立Session工廠對象 SessionFactory factory = configuration.buildSessionFactory(); //獲得Session對象 Session session = factory.openSession(); //使用Hibernate操做數據庫,都要開啓事務,獲得事務對象 Transaction transaction = session.getTransaction(); //開啓事務 transaction.begin(); session.save(dept); session.save(zs); session.save(ls); //提交事務 transaction.commit(); //關閉Session session.close(); } }
Hibernate執行了3條SQL
在一對多與多對一的關聯關係中,保存數據最好的經過多的一方來維護關係,這樣能夠減小update語句的生成,從而提升hibernate的執行效率!
值得注意是:配置了哪一方,哪一方纔有維護關聯關係的權限!