Hibernate框架--学习笔记(中):一对多配置、多对多配置
一、一對多:
一個客戶可以有多個聯系人,一個聯系人只能屬于一個客戶。
1、一對多映射配置:
(1)創建實體類
//客戶類:一個客戶可以有多個聯系人,一個聯系人只能屬于一個客戶 public class Customer {private Integer cid;private String custName;private String custLevel;private String custSource;//客戶來源private String custPhone;private String custMobile;//一個客戶可以有多個聯系人//hibernate要求使用集合表示多的數據,使用set集合private Set<LinkMan> setLinkMan=new HashSet<LinkMan>();public Set<LinkMan> getSetLinkMan() {return setLinkMan;}public void setSetLinkMan(Set<LinkMan> setLinkMan) {this.setLinkMan = setLinkMan;}public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCustName() {return custName;}public void setCustName(String custName) {this.custName = custName;}public String getCustLevel() {return custLevel;}public void setCustLevel(String custLevel) {this.custLevel = custLevel;}public String getCustSource() {return custSource;}public void setCustSource(String custSource) {this.custSource = custSource;}public String getCustPhone() {return custPhone;}public void setCustPhone(String custPhone) {this.custPhone = custPhone;}public String getCustMobile() {return custMobile;}public void setCustMobile(String custMobile) {this.custMobile = custMobile;} } //聯系人類:一個聯系人只能屬于一個客戶 public class LinkMan {private Integer lkm_id;private String lkm_name;private String lkm_gender;//性別private String lkm_phone;//一個聯系人只能屬于一個客戶private Customer customer;public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}public Integer getLkm_id() {return lkm_id;}public void setLkm_id(Integer lkm_id) {this.lkm_id = lkm_id;}public String getLkm_name() {return lkm_name;}public void setLkm_name(String lkm_name) {this.lkm_name = lkm_name;}public String getLkm_gender() {return lkm_gender;}public void setLkm_gender(String lkm_gender) {this.lkm_gender = lkm_gender;}public String getLkm_phone() {return lkm_phone;}public void setLkm_phone(String lkm_phone) {this.lkm_phone = lkm_phone;} }(2)在xxx.hbm.xml配置文件進行配置:
Customer.hbm.xml配置文件:
<?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="com.zwp.onetomany.Customer" table="t_customer"><id name="cid" column="cid"><generator class="native"></generator></id><property name="custName" column="custName"></property><property name="custLevel" column="custLevel"></property><property name="custSource" column="custSource"></property><property name="custPhone" column="custPhone"></property><property name="custMobile" column="custMobile"></property><!-- 在客戶映射文件中,表示所有聯系人使用set標簽表示所有的聯系人,set標簽里面有name屬性name屬性值寫在客戶實體類里面表示聯系人的set集合名稱--><set name="setLinkMan"><!-- 一對多建表,有外鍵hibernate機制,雙向維護外鍵,在一和多的哪一方都需要配置外鍵column屬性值,外鍵名稱--><key column="clid"></key><!-- 客戶所有的聯系人,class里面寫聯系人實體全路徑 --><one-to-many class="com.zwp.onetomany.LinkMan"/></set></class> </hibernate-mapping>LinkMan.hbm.xml配置文件:
<?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="com.zwp.onetomany.LinkMan" table="t_linkman"><id name="lkm_id" column="lkm_id"><generator class="native"></generator></id><property name="lkm_name" column="lkm_name"></property><property name="lkm_gender" column="lkm_gender"></property><property name="lkm_phone" column="lkm_phone"></property><!--表示聯系人所屬客戶name屬性:因為在聯系人實體類使用customer對象表示,寫customer名稱class屬性:customer全路徑column屬性:外鍵名稱 --><many-to-one name="customer" class="com.zwp.onetomany.Customer" column="clid"></many-to-one></class></hibernate-mapping>(3) 在核心配置文件hibernate.cfg.xml配置文件進行配置:
<!-- 把映射文件放到核心配置文件中 --><mapping resource="com/zwp/onetomany/Customer.hbm.xml" /><mapping resource="com/zwp/onetomany/LinkMan.hbm.xml" />(4)測試代碼:
//一對多測試類 public class OTMtest {//演示 OID查詢,對象導航查詢//OID查詢:根據id查詢,返回一個對象//對象導航查詢:根據id查詢客戶,在根據這個客戶查詢所有的聯系人@Testpublic void TextSelect1(){SessionFactory sessionfactory=null;Session session=null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();Customer customer=session.get(Customer.class, 1);Set<LinkMan> linkman=customer.getSetLinkMan();System.out.println(linkman.size());tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();}} }2、一對多級聯操作:
(1)級聯保存:
需求:添加客戶,為這個客戶添加一個聯系人。
//一對多級聯保存@Testpublic void TestAdd(){SessionFactory sessionfactory=null;Session session=null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();//1、創建客戶和聯系人對象Customer customer=new Customer();customer.setCustLevel("vip");customer.setCustName("谷歌");customer.setCustMobile("1321515");customer.setCustPhone("1165666");customer.setCustSource("網絡");LinkMan linkMan=new LinkMan();linkMan.setLkm_name("mike");linkMan.setLkm_gender("男");linkMan.setLkm_phone("1351565");//2、建立客戶對象和聯系人對象的關系customer.getSetLinkMan().add(linkMan);linkMan.setCustomer(customer);//3、保存到數據庫中session.save(customer);session.save(linkMan);tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();}}以下是上邊代碼的簡化寫法:
第一步:在客戶的映射文件Customer.hbm.xml中的set標簽中配置cascade進行級聯保存;
第二步:創建客戶和聯系人對象,只需要把聯系人放到客戶中,保存客戶就可以了。
<!-- 在客戶映射文件中,set標簽表示所有的聯系人cascade="save-update,delete":級聯保存,級聯刪除 --> <set name="setLinkMan" cascade="save-update,delete"><key column="clid"></key><!-- 客戶所有的聯系人,class里面寫聯系人實體全路徑 --><one-to-many class="com.zwp.onetomany.LinkMan"/> </set> //一對多級聯保存,簡化方式@Testpublic void TestAdd(){SessionFactory sessionfactory=null;Session session=null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();//1、創建客戶和聯系人對象Customer customer=new Customer();customer.setCustLevel("vip");customer.setCustName("YY歡聚時代");customer.setCustMobile("1321515");customer.setCustPhone("1165666");customer.setCustSource("網絡");LinkMan linkMan=new LinkMan();linkMan.setLkm_name("John");linkMan.setLkm_gender("男");linkMan.setLkm_phone("1351565");//2、建立客戶對象和聯系人對象的關系customer.getSetLinkMan().add(linkMan);//linkMan.setCustomer(customer);//3、保存到數據庫中session.save(customer);//session.save(linkMan);tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();}}?
(2)級聯刪除:
第一步:在客戶的映射文件Customer.hbm.xml中的set標簽中配置cascade進行級聯刪除;
第二步:在代碼中直接刪除客戶。
//一對多級聯刪除@Testpublic void TestDel(){SessionFactory sessionfactory=null;Session session=null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();//1、根據id查詢客戶對象Customer customer = session.get(Customer.class, 4);//2、調用方法刪除session.delete(customer);tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();}}(3)inverse屬性:
①問題:hibernate是使用雙向維護外鍵,會造成性能下降。
②解決方案:讓其中一方放棄外鍵維護。在一對多里面,讓一的那方放棄維護。
③在客戶的映射文件Customer.hbm.xml中的set標簽中配置inverse;
inverse屬性默認值,false不放棄關系的維護,true 表示放棄關系維護。
<!-- 在客戶映射文件中,表示所有聯系人。inverse屬性默認值,false不放棄關系的維護,true 表示放棄關系維護--> <set name="setLinkMan" cascade="save-update,delete" inverse="true"><!-- 一對多建表,有外鍵hibernate機制,雙向維護外鍵,在一和多的哪一方都需要配置外鍵column屬性值,外鍵名稱 --><key column="clid"></key><!-- 客戶所有的聯系人,class里面寫聯系人實體全路徑 --><one-to-many class="com.zwp.onetomany.LinkMan"/> </set>?
?
二、多對多:
1、多對多映射配置:
以用戶和角色為例子
第一步:創建實體類,用戶和角色:
第二步:讓兩個實體類之間互相表示:
①一個用戶里面表示所有角色,使用set集合
②一個角色有多個用戶,使用set集合
//用戶實體類:一個用戶有多個角色 public class User {private Integer user_id;private String user_name;private String user_passsword;//角色的set集合private Set<Role> setRole=new HashSet<Role>();public Set<Role> getSetRole() {return setRole;}public void setSetRole(Set<Role> setRole) {this.setRole = setRole;}public Integer getUser_id() {return user_id;}public void setUser_id(Integer user_id) {this.user_id = user_id;}public String getUser_name() {return user_name;}public void setUser_name(String user_name) {this.user_name = user_name;}public String getUser_passsword() {return user_passsword;}public void setUser_passsword(String user_passsword) {this.user_passsword = user_passsword;}} //角色實體類:一個角色有多個用戶 public class Role {private Integer role_id;private String role_name;private String role_memo;//角色描述//用戶的set集合private Set<User> setUser=new HashSet<User>();public Set<User> getSetUser() {return setUser;}public void setSetUser(Set<User> setUser) {this.setUser = setUser;}public Integer getRole_id() {return role_id;}public void setRole_id(Integer role_id) {this.role_id = role_id;}public String getRole_name() {return role_name;}public void setRole_name(String role_name) {this.role_name = role_name;}public String getRole_memo() {return role_memo;}public void setRole_memo(String role_memo) {this.role_memo = role_memo;} }第三步:配置映射關系:
①基本配置
②配置多對多關系
<?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"> <!-- 創建用戶的映射配置文件User.hbm.xml --> <hibernate-mapping><class name="com.zwp.manytomany.User" table="t_user"><id name="user_id" column="user_id"><generator class="native"></generator></id><property name="user_name" column="user_name"></property><property name="user_passsword" column="user_passsword"></property><!-- 在用戶里面表示所有角色,使用set標簽;name屬性:角色屬性set集合名稱;table:第三張表名稱; --><set name="setRole" table="user_role"><!-- key標簽里面配置,配置當前映射文件第三張表外鍵名稱 --><key column="userid"></key><!-- class:角色實體類全路徑;column:角色在第三張表外鍵名稱 --><many-to-many class="com.zwp.manytomany.Role" column="roleid"></many-to-many></set></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"> <!-- 創建角色的映射配置文件Role.hbm.xml --> <hibernate-mapping><class name="com.zwp.manytomany.Role" table="t_role"><id name="role_id" column="role_id"><generator class="native"></generator></id><property name="role_name" column="role_name"></property><property name="role_memo" column="role_memo"></property><set name="setUser" table="user_role"><key column="roleid"></key><many-to-many class="com.zwp.manytomany.User" column="userid"></many-to-many></set></class> </hibernate-mapping>第四步:在核心配置文件hibernate.cfg.xml中引入映射文件:
<!-- 把映射文件放到核心配置文件中 --> <mapping resource="com/zwp/manytomany/Role.hbm.xml" /> <mapping resource="com/zwp/manytomany/User.hbm.xml" />至此,hibernate多對多映射的配置已經完成。
?
2、多對多級聯保存:
第一步:在用戶的映射文件User.hbm.xml中的set標簽中配置cascade進行級聯保存;
第二步:創建用戶和角色對象,只需要把角色放到用戶中,保存用戶就可以了。
<set name="setRole" table="user_role" cascade="save-update"><!-- key標簽里面配置,配置當前映射文件第三張表外鍵名稱 --><key column="userid"></key><!-- class:角色實體類全路徑;column:角色在第三張表外鍵名稱 --><many-to-many class="com.zwp.manytomany.Role" column="roleid"></many-to-many></set> @Testpublic void Sava(){//多對多級聯保存//<set name="setRole" table="user_role" cascade="save-update">SessionFactory sessionfactory = null;Session session = null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();//創建用戶和角色User user1=new User();user1.setUser_name("小張");user1.setUser_passsword("213456");User user2=new User();user2.setUser_name("小王");user2.setUser_passsword("354656");Role role1=new Role();role1.setRole_name("總經理");role1.setRole_memo("總經理");Role role2=new Role();role2.setRole_name("秘書");role2.setRole_memo("秘書");Role role3=new Role();role3.setRole_name("保安");role3.setRole_memo("保安");user1.getSetRole().add(role1);user1.getSetRole().add(role2);user2.getSetRole().add(role2);user2.getSetRole().add(role3);session.save(user1);session.save(user2);tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();} }?
3、多對多級聯刪除
在用戶的映射文件User.hbm.xml中的set標簽中配置cascade進行級聯刪除;
<!-- 在用戶里面表示所有角色,使用set標簽;name屬性:角色屬性set集合名稱;table:第三張表名稱; --><set name="setRole" table="user_role" cascade="delete"><!-- key標簽里面配置,配置當前映射文件第三張表外鍵名稱 --><key column="userid"></key><!-- class:角色實體類全路徑;column:角色在第三張表外鍵名稱 --><many-to-many class="com.zwp.manytomany.Role" column="roleid"></many-to-many></set> @Testpublic void DelTest(){//多對多級聯刪除//<set name="setRole" table="user_role" cascade="delete">SessionFactory sessionfactory = null;Session session = null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();User user=session.get(User.class, 1);session.delete(user);tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();} }?
4、維護第三張表關系:
用戶和角色的多對多關系,維護關系通過第三張表維護。
(1)讓某個用戶有某個角色:
第一步:根據id查詢用戶和角色;
第二步:把角色放到用戶里面:即,把角色對象放到用戶set集合。
(2)讓某個用戶沒有某個角色:
第一步:根據id查詢用戶和角色;
第二步:從用戶里面把角色去掉:即,從set集合里面把角色移除。
@Testpublic void TextTbable(){//多對多維護第三張表SessionFactory sessionfactory = null;Session session = null;Transaction tx=null;try{sessionfactory=HibernateUtil.getSessionFactory();session=sessionfactory.openSession();tx=session.beginTransaction();User user=session.get(User.class, 2);Role role=session.get(Role.class, 4);//讓用戶4擁有角色2:user.getSetRole().add(role);//讓用戶4失去角色2:user.getSetRole().remove(role);tx.commit();}catch(Exception e){e.printStackTrace();tx.rollback();}finally{session.close();sessionfactory.close();} }?
?
總結
以上是生活随笔為你收集整理的Hibernate框架--学习笔记(中):一对多配置、多对多配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hibernate框架--学习笔记(上)
- 下一篇: Hibernate框架--学习笔记(下)