Hibernate集合映射

Hibernate 定义了三种基本类型的集合:

  • 值数据集合
  • 一对多关联(One-to-many Associations)
  • 多对多关联

这个分类是区分了不同的表和外键关系类型,但是它没有告诉我们关系模型的所有内容。 要完全理解他们的关系结构和性能特点,我们必须同时考虑“用于 Hibernate 更新或删除集合行数据的主键的结构”。因此得到了如下的分类:

  • 有序集合类
  • 集合(sets)
  • 包(bags)

所有的有序集合类(maps,lists,arrays)都拥有一个由 <key><index> 组成的主键。这种情况下集合类的更新是非常高效的 — 主键已经被有效的索引,因此当 Hibernate 试图更新或删除一行时,可以迅速找到该行数据。

集合(sets)的主键由 <key> 和其他元素字段构成。对于有些元素类型来说,这很低效,特别是组合元素或者大文本、大二进制字段;数据库可能无法有效的对复杂的主键进行索引。另一方面,对于一对多、多对多关联,特别是合成的标识符来说,集合也可以达到同样的高效性能。( 附注:如果你希望 SchemaExport 为你的 创建主键,你必须把所有的字段都声明为 not-null=”true”。)

<idbag> 映射定义了代理键,因此它总是可以很高效的被更新。事实上,<idbag> 拥有着最好的性能表现。

Bag 是最差的。因为 bag 允许重复的元素值,也没有索引字段,因此不可能定义主键。 Hibernate 无法判断出重复的行。当这种集合被更改时,Hibernate 将会先完整地移除 (通过一个(in a single DELETE))整个集合,然后再重新创建整个集合。因此 Bag 是非常低效的。

请注意:对于一对多关联来说,“主键”很可能并不是数据库表的物理主键。但就算在此情况下,上面的分类仍然是有用的。(它仍然反映了 Hibernate 在集合的各数据行中是如何进行“定位”的。)

实例:

<!-------------建立组件类Friends.java---------------->
package com.michael.model;

import java.util.ArrayList;
import java.util.List;


public class Friends {

private String sex;
private String f_name;
private List<String> cars = new ArrayList<String>();
private Person person;

public Friends() {
}

public Friends(String f_name, String sex) {
this.f_name = f_name;
this.sex = sex;
}

public List<String> getCars() {
return cars;
}

public void setCars(List<String> cars) {
this.cars = cars;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getF_name() {
return f_name;
}

public void setF_name(String fName) {
f_name = fName;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj.getClass() == Friends.class) {
Friends target = (Friends) obj;
if (target.getF_name().equals(getF_name())) {
return true;
}
}
return false;
}

@Override
public int hashCode() {
return getF_name().hashCode() * 13 + getSex().hashCode();
}

}
<!-------------建立一个持久化类Person.java---------------->
package com.michael.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

// default package


public class Person {

private String name;
private int age;
private int id;
//list集合
private List<String> schools = new ArrayList<String>();
//set集合
private Set<String> animas = new HashSet<String>();
//map集合
private Map<String, Integer> course = new HashMap<String, Integer>();
//map集合的属性为组件
private Map<String, Friends> friends = new HashMap<String, Friends>();
//组件为map集合的索引
private Map<Friends, Integer> friends2 = new HashMap<Friends, Integer>();
//组件属性为集合
private Friends friends1;

public Friends getFriends1() {
return friends1;
}

public void setFriends1(Friends friends1) {
this.friends1 = friends1;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public List<String> getSchools() {
return schools;
}

public void setSchools(List<String> schools) {
this.schools = schools;
}

public Set<String> getAnimas() {
return animas;
}

public void setAnimas(Set<String> animas) {
this.animas = animas;
}

public Map<String, Integer> getCourse() {
return course;
}

public void setCourse(Map<String, Integer> course) {
this.course = course;
}


public Map<String, Friends> getFriends() {
return friends;
}

public void setFriends(Map<String, Friends> friends) {
this.friends = friends;
}

public Map<Friends, Integer> getFriends2() {
return friends2;
}

public void setFriends2(Map<Friends, Integer> friends2) {
this.friends2 = friends2;
}

}
<!----------建立持久化类对应的映射文件Person.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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.michael.model.Person" table="person">

 <id name="id" type="java.lang.Integer">
 <column name="id"></column>
 <generator class="identity"></generator>
 </id>

     <property name="name" type="java.lang.String">
            <column name="name" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="age" />
        </property>

        <!-- list集合映射 -->
       <list name="schools" table="school">
       <key column="personid" not-null="true"></key>
       <list-index column="list_order"></list-index>
       <element type="string" column="school_name"></element>
       </list>

       <!-- 因为set是无序集合,所以无需配置list-index -->
       <set name="animas" table="animas">
       <key column="person_animas_id"></key>
       <element type="string" column="animas_name"></element>
       </set>

       <!-- map集合映射 要配置map-key -->
       <map name="course"  table="course">
       <key column="person_course_id"></key>
       <map-key type="string" column="course_name"></map-key>
       <element type="int" column="score"></element>
       </map>

        <!--  map集合的属性为组件 -->
        <map name="friends" table="friends">
        <key column="person_friends_id"></key>
        <map-key type="string" column="friend_name"></map-key>
        <composite-element class="com.michael.model.Friends">
        <parent name="person"/>
        <property name="f_name" ></property>
        <property name="sex" ></property>
        </composite-element>
        </map>

<!-- 组件作为Map的索引  必须得重写组件类的equals()和hashCode()-->
        <map name="friends2" table="frindes2">
        <key column="person_friends2_id"></key>
        <composite-map-key class="com.michael.model.Friends">
        <key-property name="f_name"></key-property>
        <key-property name="sex"></key-property>
        </composite-map-key>
        <element type="int" column="num"></element>
        </map>

        <!-- 组件属性为集合 -->
        <component name="friends1" class="com.michael.model.Friends">
        <parent name="person"/>
        <property name="f_name"></property>
        <property name="sex"></property>
        <list name="cars" table="cars">
        <key column="person_cars_id"></key>
        <list-index column="list_order"></list-index>
        <element type="string" column="car_name" />
        </list>
        </component>
     </class>
</hibernate-mapping>
<!------------------建立一个junit测试----------------------->
package com.michael.test;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;


import com.michael.HibernateSessionFactory;
import com.michael.model.Friends;
import com.michael.model.Person;

public class Test extends TestCase {
public void testOrm(){
Session session = HibernateSessionFactory.getSession();
//映射list集合
List<String> schools = new ArrayList<String>();
schools.add("1");
schools.add("2");
schools.add("3");
//映射set集合
Set<String> animas = new HashSet<String>();
animas.add("3");
animas.add("3q");
animas.add("3e");
//映射map集合
Map<String,Integer> course = new HashMap<String,Integer>();
course.put("a", 80);
course.put("b", 90);
course.put("c", 85);
//组件属性为集合
List<String> cars = new ArrayList<String>();
cars.add("bmw");
cars.add("奔驰");
//map集合属性为组件
Friends f = new Friends();
f.setF_name("AA");
f.setSex("男");
f.setCars(cars);
Map<String,Friends> maps = new HashMap<String,Friends>();
maps.put("1", f);
//组件为map集合的索引
Map<Friends,Integer> maps2 = new HashMap<Friends, Integer>();
maps2.put(f, 45);
Person p  = new Person();
p.setSchools(schools);
p.setAnimas(animas);
p.setCourse(course);
p.setFriends1(f);
p.setFriends(maps);
p.setFriends2(maps2);
Transaction tr = session.beginTransaction();
tr.begin();
session.save(p);
tr.commit();
HibernateSessionFactory.closeSession();
}
}

运行junit测试,如果成功,那么在各个数据库表中都会有对应的数据插入。

原文地址:https://www.cnblogs.com/lllini/p/11955355.html