映射

 

一、Set集合映射

当实体类中有HashSet属性时,它是如何进行初始化的呢?当持久化这个实体类的一个实例,比如调用persist()方法进行了持久化时,hibernate将自动利用hibernate自己实现了Set接口的类替换掉HashSet。所以一定要防止出现如下所示的错误:

Java代码

  1. HashSet<Employee> hSet = (HashSet<Employee>)depart.getEmps(); //Error

HashSet<Employee> hSet = (HashSet<Employee>)depart.getEmps(); //Error

当运行时,会出现如下的异常:

java.lang.ClassCastException: org.hibernate.collection.PersistentSet cannot be cast to java.util.HashSet

二、List集合映射

1. 实体类:

实体类还是采用Department和Employee,详见我写的多对一(many-to-one)文章,在它们的基础上进行修改如下所示:

将原Department实体类中的Set替换成List,如下所示:

Java代码

  1. package com.reiyen.hibernate.domain;
  2.  
  3. public class Department {
  4.  
  5. private int id;
  6. private String name;
  7. private List<Employee> emps;
  8. //Setter和Getter方法
  9. }

package com.reiyen.hibernate.domain;

 

public class Department {

 

  private int id;

  private String name;

  private List<Employee> emps;

       //Setter和Getter方法

}

在原Employee实体类中增加了重写的toString()方法,方法如下:

Java代码

  1. @Override
  2. public String toString() {
  3. return "id=" + this.id + " name=" + this.name;
  4. }

@Override

public String toString() {

  return "id=" + this.id + " name=" + this.name;

}

2. 配置文件:

修改Department.hbm.xml配置文件,其它的还是保持以前的不变,修改的Department.hbm.xml配置文件如下:

Xml代码

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.reiyen.hibernate.domain">
  6. <class name="Department" >
  7. <id name="id" >
  8. <generator class="native" />
  9. </id>
  10. <property name="name" />
  11. <!--
  12. <set name="emps">
  13. <key column="depart_id" />
  14. <one-to-many class="Employee"/>
  15. </set>-->
  16. <list name="emps">
  17. <key column="depart_id" />
  18. <list-index column="order_col" />
  19. <one-to-many class="Employee"/>
  20. </list>
  21. </class>
  22. </hibernate-mapping>

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.reiyen.hibernate.domain">

<class name="Department" >

  <id name="id" >

   <generator class="native" />

  </id>

  <property name="name" />

  <!-- 

  <set name="emps">

  <key column="depart_id" />

  <one-to-many class="Employee"/>

  </set>-->

  <list name="emps">

  <key column="depart_id" />

  <!-- list-index:用来记录加入list集合的元素的顺序 ,会一定程度影响性能,所以可以使用bag替代list-->

  <list-index column="order_col" />

  <one-to-many class="Employee"/>

  </list>

</class>

</hibernate-mapping>

3.测试类(只是对many-to-one中的测试类进行了少量的修改),如下所示:

Java代码

  1. public class Many2One {
  2.  
  3. public static void main(String[] args) {
  4. Department depart = add();
  5. Department department = queryDepart(depart.getId());
  6. }
  7.  
  8. static Department queryDepart(int departId) {
  9. Session s = null;
  10. Transaction tx = null;
  11. try {
  12. s = HibernateUtil.getSession();
  13. tx = s.beginTransaction();
  14. Department depart = (Department) s.get(Department.class, departId);
  15. System.out.println("emps:" + depart.getEmps());
  16. tx.commit();
  17. return depart;
  18. } finally {
  19. if (s != null)
  20. s.close();
  21. }
  22. }
  23.  
  24. static Department add() {
  25. Session s = null;
  26. Transaction tx = null;
  27. try {
  28. Department depart = new Department();
  29. depart.setName("department name");
  30.  
  31. Employee employee1 = new Employee();
  32. employee1.setName("employee1 name1");
  33.  
  34. Employee employee2 = new Employee();
  35. employee2.setName("employee2 name2");
  36.  
  37. List<Employee> list= new ArrayList<Employee>();
  38. list.add(employee1); //1
  39. list.add(employee2); //2
  40. depart.setEmps(list);
  41.  
  42. s = HibernateUtil.getSession();
  43. tx = s.beginTransaction();
  44. s.save(depart);
  45. s.save(employee1);
  46. s.save(employee2);
  47. tx.commit();
  48. return depart;
  49. } finally {
  50. if (s != null)
  51. s.close();
  52. }
  53. }
  54. }

public class Many2One {

 

  public static void main(String[] args) {

    Department depart = add();

    Department department = queryDepart(depart.getId());

  }

 

  static Department queryDepart(int departId) {

    Session s = null;

    Transaction tx = null;

    try {

      s = HibernateUtil.getSession();

      tx = s.beginTransaction();

      Department depart = (Department) s.get(Department.class, departId);

      System.out.println("emps:" + depart.getEmps());

      tx.commit();

      return depart;

    } finally {

      if (s != null)

        s.close();

    }

  }

 

  static Department add() {

    Session s = null;

    Transaction tx = null;

    try {

      Department depart = new Department();

      depart.setName("department name");

     

      Employee employee1 = new Employee();

      employee1.setName("employee1 name1");

     

      Employee employee2 = new Employee();

      employee2.setName("employee2 name2");

     

      List<Employee> list= new ArrayList<Employee>();

      list.add(employee1); //1

      list.add(employee2); //2

      depart.setEmps(list);

     

      s = HibernateUtil.getSession();

      tx = s.beginTransaction();

      s.save(depart);

      s.save(employee1);

      s.save(employee2);

      tx.commit();

      return depart;

    } finally {

      if (s != null)

        s.close();

    }

  }

}

执行测试类,控制台打印如下信息:

emps:[id=1 name=employee1 name1, id=2 name=employee2 name2]

将测试类中注释为1和注释为2的语句对换顺序后,重新执行,控制台打印如下信息:

emps:[id=2 name=employee2 name2, id=1 name=employee1 name1]

说明使用List时,因为配置文件下增加了<list-index column="order_col" />对加入List集合的元素的顺序进行记录,测试结果表明,确实对加入顺序进行了记录。

三、bag集合映射(使用bag集合映射时,注意实体类中还是使用java.util.List与之对应)

如果在实体类中使用了List类型的属性,而我们并不希望保证集合中元素的顺序(保证集合中元素的顺序会采用排序算法,因而会占用一些CPU资源,一定程序上影响性能),可以在配置文件中使用<bag>,它的使用与<list>唯一不同的就是不保证集合中元素的顺序。

在List集合映射的基础上,只需将配置文件中list部分替换成bag即可,其余部分不用修改,Department.hbm.xml配置文件修改如下:

Java代码

  1. <bag name="emps">
  2. <key column="depart_id" />
  3. <one-to-many class="Employee"/>
  4. </bag>

<bag name="emps">

    <key column="depart_id" />

    <one-to-many class="Employee"/>

    </bag>

将测试类中注释为1和注释为2的语句对换顺序后执行,控制台打印如下信息:

emps:[id=1 name=employee1 name1, id=2 name=employee2 name2]

四、Map集合映射

Map集合属性不仅需要映射属性value,还需要映射属性key。这里假设Employee的name属性是唯一的,如下修改Employee.hbm.xml配置文件中的name属性,设置unique='true':

Java代码

  1. <property name="name" unique="true"/>

<property name="name" unique="true"/>

实体类Department如下:

Java代码

  1. public class Department {
  2.  
  3. private int id;
  4. private String name;
  5. private Map<String, Employee> emps;
  6. //setter和getter方法
  7.  
  8. }

public class Department {

 

  private int id;

  private String name;

  private  Map<String, Employee> emps;

//setter和getter方法

 

}

修改Department.hbm.xml配置文件如下:

Xml代码

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.reiyen.hibernate.domain">
  6. <class name="Department">
  7. <id name="id">
  8. <generator class="native" />
  9. </id>
  10. <property name="name" />
  11. <map name="emps">
  12. <key column="depart_id" />
  13. <map-key type="string" column="name" />
  14. <one-to-many class="Employee" />
  15. </map>
  16. </class>
  17. </hibernate-mapping>

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.reiyen.hibernate.domain">

  <class name="Department">

    <id name="id">

      <generator class="native" />

    </id>

    <property name="name" />

    <map name="emps">

      <key column="depart_id" />

      <map-key type="string" column="name" />

      <one-to-many class="Employee" />

    </map>

  </class>

</hibernate-mapping>

将测试类下如下注释部分(即List部分)替换,改成Map重新进行测试:

Java代码

  1. //List<Employee> list= new ArrayList<Employee>();
  2. // list.add(employee2);
  3. // list.add(employee1);
  4. Map<String,Employee> emps = new HashMap<String,Employee>();
  5. emps.put(employee1.getName(), employee1);
  6. emps.put(employee2.getName(), employee2);
  7. depart.setEmps(emps);

//List<Employee> list= new ArrayList<Employee>();

//      list.add(employee2);

//      list.add(employee1);

      Map<String,Employee> emps = new HashMap<String,Employee>();

      emps.put(employee1.getName(), employee1);

      emps.put(employee2.getName(), employee2);

      depart.setEmps(emps);

测试结果如下:

emps:{employee1 name1 =id=1 name=employee1 name1, employee2 name2 =id=2 name=employee2 name2}

五、array(数组)映射

将实体类Department修改如下:

Java代码

  1. private Employee[] emps;

private Employee[] emps;

Department.hbm.xml修改如下:

Java代码

  1. <array name="emps">
  2. <key column="depart_id" />
  3. <list-index column="order_col" />
  4. <one-to-many class="Employee"/>
  5. </array>

<array name="emps">

      <key column="depart_id" />

      <list-index column="order_col" />

      <one-to-many class="Employee"/>

      </array>

测试类修改如下:

Java代码

  1. Employee[] emps= new Employee[2];
  2. emps[0] = employee2;
  3. emps[1] = employee1;
  4. depart.setEmps(emps);

Employee[] emps= new Employee[2];

   emps[0] = employee2;

   emps[1] = employee1;

   depart.setEmps(emps);

Java代码

  1. for(int i = 0; i < depart.getEmps().length; i++){
  2. System.out.println(depart.getEmps()[i]);
  3. }

for(int i = 0; i < depart.getEmps().length; i++){

        System.out.println(depart.getEmps()[i]);

      }

测试结果如下所示,控制台打印结果:

id=2 name=employee2 name2
id=1 name=employee1 name1

总结:集合的简单使用原则:大部分情况下用set,需要保证集合中的顺序时用list,想用java.util.List又不需要保证顺序时用bag.

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值