hibernate关系映射

以你之姓@ 2022-04-16 01:59 377阅读 0赞

一对多映射

xml配置文件

  1. <?xml version='1.0' encoding='utf-8'?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.jie.domain.TAddressProvince" table="t_address_province" schema="region">
  7. <id name="id" column="id">
  8. <generator class="native"></generator>
  9. </id>
  10. <property name="code" column="code"/>
  11. <property name="name" column="name"/>
  12. <!--一对多set
  13. name:当前类的属性名
  14. column:从表中的外键名
  15. foreign-key:主表中的被参照字段
  16. property-ref:主表中被参照字段的属性名
  17. class:从表的类
  18. -->
  19. <set name="citys" cascade="all">
  20. <key column="provinceCode" foreign-key="code" property-ref="code"></key>
  21. <one-to-many class="com.jie.domain.TAddressCity"></one-to-many>
  22. </set>
  23. </class>
  24. </hibernate-mapping>

domain类

  1. package com.jie.domain;
  2. import java.util.HashSet;
  3. import java.util.Set;
  4. public class TAddressProvince {
  5. private int id;
  6. private String code;
  7. private String name;
  8. private Set<TAddressCity>citys=new HashSet<>();
  9. public Set<TAddressCity> getCitys() {
  10. return citys;
  11. }
  12. public void setCitys(Set<TAddressCity> citys) {
  13. this.citys = citys;
  14. }
  15. public int getId() {
  16. return id;
  17. }
  18. public void setId(int id) {
  19. this.id = id;
  20. }
  21. public String getCode() {
  22. return code;
  23. }
  24. public void setCode(String code) {
  25. this.code = code;
  26. }
  27. public String getName() {
  28. return name;
  29. }
  30. public void setName(String name) {
  31. this.name = name;
  32. }
  33. @Override
  34. public boolean equals(Object o) {
  35. if (this == o) return true;
  36. if (o == null || getClass() != o.getClass()) return false;
  37. TAddressProvince that = (TAddressProvince) o;
  38. if (id != that.id) return false;
  39. if (code != null ? !code.equals(that.code) : that.code != null) return false;
  40. if (name != null ? !name.equals(that.name) : that.name != null) return false;
  41. return true;
  42. }
  43. @Override
  44. public int hashCode() {
  45. int result = id;
  46. result = 31 * result + (code != null ? code.hashCode() : 0);
  47. result = 31 * result + (name != null ? name.hashCode() : 0);
  48. return result;
  49. }
  50. }

这个其实就是在hibernate生成类的基础上添加属性 private Setcitys=new HashSet<>();和其get、set方法。

util工具类

  1. package com.jie.util;
  2. import org.hibernate.Session;
  3. import org.hibernate.SessionFactory;
  4. import org.hibernate.cfg.Configuration;
  5. public class HibernateUtil {
  6. static SessionFactory factory=null;
  7. static {
  8. //创建配置文件
  9. Configuration config=new Configuration();
  10. //读取配置文件
  11. config.configure("/hibernate.cfg.xml");
  12. //创建sessionFactory
  13. factory=config.buildSessionFactory();
  14. }
  15. //获取session
  16. public static Session getCurrentSession(){
  17. Session session=factory.openSession();
  18. return session;
  19. }
  20. //关闭session
  21. public static void closeSession(Session session){
  22. if (session!=null){
  23. session.close();
  24. }
  25. }
  26. }

test测试类

  1. package com.jie;
  2. import com.jie.domain.TAddressCity;
  3. import com.jie.domain.TAddressProvince;
  4. import com.jie.util.HibernateUtil;
  5. import org.hibernate.Session;
  6. import org.junit.Test;
  7. import java.util.HashSet;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import java.util.Set;
  11. //一对多
  12. public class Test2 {
  13. //查询
  14. @Test
  15. public void getCityInfo(){
  16. Session session= HibernateUtil.getCurrentSession();
  17. List<TAddressProvince>provinces=session.createQuery("from TAddressProvince").list();
  18. HibernateUtil.closeSession(session);
  19. }
  20. //级联增加
  21. @Test
  22. public void sava(){
  23. Session session= HibernateUtil.getCurrentSession();
  24. session.beginTransaction();
  25. TAddressProvince province=new TAddressProvince();
  26. province.setName("JXQY");
  27. province.setCode("830000");
  28. Set<TAddressCity>cities=new HashSet<>();
  29. TAddressCity city1=new TAddressCity();
  30. city1.setName("QQ");
  31. city1.setCode("831000");
  32. TAddressCity city2=new TAddressCity();
  33. city2.setName("ZJSZ");
  34. city2.setCode("832000");
  35. cities.add(city1);
  36. cities.add(city2);
  37. province.setCitys(cities);
  38. session.save(province);
  39. session.getTransaction().commit();
  40. HibernateUtil.closeSession(session);
  41. }
  42. //级联修改
  43. @Test
  44. public void updata(){
  45. Session session= HibernateUtil.getCurrentSession();
  46. session.beginTransaction();
  47. TAddressProvince province=session.get(TAddressProvince.class,48);
  48. province.setName("JXQY123");
  49. Set cities=province.getCitys();
  50. Iterator iterator=cities.iterator();
  51. int i=100;
  52. while (iterator.hasNext()){
  53. TAddressCity city=(TAddressCity) iterator.next();
  54. city.setName("qq"+i++);
  55. }
  56. session.update(province);
  57. session.getTransaction().commit();
  58. HibernateUtil.closeSession(session);
  59. }
  60. //级联删除
  61. @Test
  62. public void delete(){
  63. Session session=HibernateUtil.getCurrentSession();
  64. session.beginTransaction();
  65. TAddressProvince province=session.get(TAddressProvince.class,48);
  66. session.delete(province);
  67. session.getTransaction().commit();
  68. HibernateUtil.closeSession(session);
  69. }
  70. }

一对多映射总结:

分析SQL:
get方法:
1:通过one方获取many方,使用了延迟加载.
2:one方的many方的属性是一个集合,必须使用接口来声明.
3:不能通过if-null来判断one方是否有many方,只能通过size方法来判断.
4:必须在session关闭之前使用集合对象,否则报错:no session.
save方法:
由One方来维护外键关系,所以得发额外的两条SQL:
在保存对象的时候,因为对象的关系由one方维护,所以,在保存many方的时候,不会去修改外键的值;
只能在one方保存完成之后,由one方发送额外的update语句去修改many方的外键的值;

多对一映射

xml配置文件

  1. <?xml version='1.0' encoding='utf-8'?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.jie.domain.TAddressCity" table="t_address_city" schema="region">
  7. <id name="id" column="id">
  8. <generator class="native"></generator>
  9. </id>
  10. <property name="code" column="code"/>
  11. <property name="name" column="name"/>
  12. <!--<property name="provinceCode" column="provinceCode"/>-->
  13. <!-- 多对一映射,关系有多方维护 name many方通过哪一个属性找到one方 column 生成外键的列名 -->
  14. <many-to-one name="province" class="com.jie.domain.TAddressProvince" property-ref="code" cascade="all">
  15. <column name="provinceCode"></column>
  16. </many-to-one>
  17. </class>
  18. </hibernate-mapping>

domain类

  1. package com.jie.domain;
  2. public class TAddressCity {
  3. private int id;
  4. private String code;
  5. private String name;
  6. // private String provinceCode;
  7. private TAddressProvince province;
  8. public int getId() {
  9. return id;
  10. }
  11. public void setId(int id) {
  12. this.id = id;
  13. }
  14. public String getCode() {
  15. return code;
  16. }
  17. public void setCode(String code) {
  18. this.code = code;
  19. }
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public TAddressProvince getProvince() {
  27. return province;
  28. }
  29. public void setProvince(TAddressProvince province) {
  30. this.province = province;
  31. }
  32. // public String getProvinceCode() {
  33. // return provinceCode;
  34. // }
  35. //
  36. // public void setProvinceCode(String provinceCode) {
  37. // this.provinceCode = provinceCode;
  38. // }
  39. @Override
  40. public boolean equals(Object o) {
  41. if (this == o) return true;
  42. if (o == null || getClass() != o.getClass()) return false;
  43. TAddressCity that = (TAddressCity) o;
  44. if (id != that.id) return false;
  45. if (code != null ? !code.equals(that.code) : that.code != null) return false;
  46. if (name != null ? !name.equals(that.name) : that.name != null) return false;
  47. //if (provinceCode != null ? !provinceCode.equals(that.provinceCode) : that.provinceCode != null) return false;
  48. return true;
  49. }
  50. @Override
  51. public int hashCode() {
  52. int result = id;
  53. result = 31 * result + (code != null ? code.hashCode() : 0);
  54. result = 31 * result + (name != null ? name.hashCode() : 0);
  55. //result = 31 * result + (provinceCode != null ? provinceCode.hashCode() : 0);
  56. return result;
  57. }
  58. @Override
  59. public String toString() {
  60. return "TAddressCity{" +
  61. "id=" + id +
  62. ", code='" + code + '\'' +
  63. ", name='" + name + '\'' +
  64. ", province=" + province +
  65. '}';
  66. }
  67. }

注释掉与上级有关联的属性,添加上级对象属性,数据库对象的字段修改为允许null

总结:

分析get方法:
1:many方获取one方的时候,使用了延迟加载,生成了代理对象
2:可以使用if-null方式来判断,是否存在one方.
3:得到的one方,必须在session关闭之前实例化(获取非OID属性),否则报错:no session.
分析save方法:
先保存many方再保存one方,会产生额外的SQL,这些SQL是由于持久化对象(many)的脏数据造成的;

查询个别字段

  1. package com.jie;
  2. import com.jie.domain.TAddressProvince;
  3. import com.jie.util.HibernateUtil;
  4. import org.hibernate.Session;
  5. import org.junit.Test;
  6. import java.util.List;
  7. public class Test3 {
  8. @Test
  9. public void toTest(){
  10. Session session= HibernateUtil.getCurrentSession();
  11. //List<Object[]>lists=session.createSQLQuery("select id,name,code from TAddressProvince").list();
  12. List<Object[]>lists=session.createQuery("select id,name,code from TAddressProvince").list();
  13. for (int i=0;i<lists.size();i++){
  14. Object[]obj=lists.get(i);
  15. System.out.println(obj[0]+" : "+obj[1]+" : "+obj[2]);
  16. }
  17. List<TAddressProvince>plists=session.createQuery("select new TAddressProvince( id,name,code) from TAddressProvince").list();
  18. for (int i=0;i<plists.size();i++){
  19. System.out.println(plists.get(i).getId()+" : "+plists.get(i).getName()+" : "+plists.get(i).getCode());
  20. }
  21. HibernateUtil.closeSession(session);
  22. }
  23. }

#

发表评论

表情:
评论列表 (有 0 条评论,377人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Hibernate映射组成关系

      建立域模型和关系数据模型有着不同的出发点。   域模型(面向对象设计):由程序代码组成,通过细化持久化类的的粒度可提高代码的可重用性,简化编程。   关系数据模型(

    相关 Hibernate 关系映射整理

    一、概念: 关系:名词,事物之间相互作用、相互联系的状态。 关联:名词:表示对象(数据库表)之间的关系;动词:将对象(数据库表)之间通过某种方式联系起来。 映射

    相关 hibernate-关系映射

    Hibernate的关联关系映射 三种实体关系分别是: 一对多:在多的一方,添加一的一方的主键作为外键 多对多:产生中间关系表,引入两张表的主键作为外键,两