在开发中我们可能会遇到对象的集合属性,这是我们可能在对象层面上使用collection子类来满足我们应用的需求,但是在数据库层面上我们可能就会需用第二张表来时我们的集合映射,hibernate在这个方面做了很大的优化,是我们可以不用关注数据库层面上的操作,直接从对象的角度来考虑开发:
代码的解释都在代码中:大家可以仔细看看:
下面就是结合映射的详解(代码有些许的不足,还希望各位大神指正:):
注意:
使用集合属性时,一定要使用接口,而不能声明为具体的实现类。
因为经过Session操作后,集合就变成了Hibernate自己的集合实现类。
1:创建User对象,里面包含所需集合:
package hibernate_collection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class User {
private Integer id;
private String name;
//hibernate集合映射hashset为无序不可重复,set底层是基于hashmap实现
//集合不是必须实例化,但是这样写是为了在外部直接调用省去不必要的代码,增加可读性
private Set<String> addressSet=new HashSet<String>();//hashset是无序的,有时候我们需要列表是有序的
private List<String> addressList=new ArrayList<String>();//arrayList为有序可重复,底层是数组,需要频繁增删时建议不要使用
private Map<String,String> addressMap=new HashMap<String,String>();//存放key-value形式的键值对
private String[] addressArray;//数组的集合映射方式和list一样
//bag的映射方式和set差不多,但是bag是无序可重复的,但是我们在引用的时候是list
private List<String> addressBag=new ArrayList<String>();
public List<String> getAddressBag() {
return addressBag;
}
public void setAddressBag(List<String> addressBag) {
this.addressBag = addressBag;
}
public Map<String, String> getAddressMap() {
return addressMap;
}
public void setAddressMap(Map<String, String> addressMap) {
this.addressMap = addressMap;
}
public String[] getAddressArray() {
return addressArray;
}
public void setAddressArray(String[] addressArray) {
this.addressArray = addressArray;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getAddressSet() {
return addressSet;
}
public void setAddressSet(Set<String> addressSet) {
this.addressSet = addressSet;
}
public List<String> getAddressList() {
return addressList;
}
public void setAddressList(List<String> addressList) {
this.addressList = addressList;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", addressSet="
+ addressSet + "]";
}
}
2:对象映射,实现对象到表的映射关系:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-3-31 21:15:29 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hibernate_collection.User" table="user">
<!-- 指定主键,column对应表的列 -->
<id name="id" type="int" column="userID">
<generator class="native"></generator>
</id>
<!-- propertiy对应表的属性
在配置时ctrl加alt加/是提示快捷键
-->
<property name="name" type="string" column="name"/>
<!-- set无序,不可重复 -->
<set name="addressSet" table="address_Set">
<!-- 集合默认以对象的主键为集合表的外键key的column不必要完全和id一致 -->
<key column="userID"></key>
<!-- element用于指定集合表的属性 -->
<element type="string" column="address"></element>
</set>
<!-- 注意所有有序集合list和数组,都必须把list-index属性写到key和elemnet属性中间,不然会报建表sql语句错误,
不知道为什么,mysql亲测 ,还亲大神告知-->
<!-- 有序集合和无序集合配置操作差不多,但是多了一个list-index属性,是用来确定数据库表中插入的先后顺序,有时候我们需要这个顺序
例如,购物时的默认收货地址 -->
<!-- list,array 有序,可重复 -->
<list name="addressList" table="address_List">
<key column="userID"></key>
<list-index column="idx" ></list-index>
<element type="string" column="address"></element>
</list>
<!-- array和list配置一样,但是所用的格式不一样
注意集合默认是懒加载的,就是说当你需要使用的时候才会去查询数据库不是立即查询
所有type小写为hibernate属性,类型权限定名是java类型如java.lang.String
-->
<array name="addressArray" table="address_Array">
<key column="userID"></key>
<list-index column="idx" ></list-index>
<element type="string" column="address"></element>
</array>
<!-- map和set的配置基本差不多,就多了一个需要配置map-key的属性,map是键值对的形式 -->
<map name="addressMap" table="address_Map">
<key column="userID"></key>
<map-key type="string" column="key_"></map-key>
<element type="string" column="address"></element>
</map>
<!-- bag和set的配置是基本一样,但是bag是无序可重复的, set是无序不可重复,list是有序可重复-->
<bag name="addressBag" table="address_bag" >
<key column="userID"></key>
<element type="string" column="address"></element>
</bag>
</class>
</hibernate-mapping>
3:测试类
package hibernate_collection;
import static org.junit.Assert.*;
import java.nio.channels.SeekableByteChannel;
import org.hibernate.Session;
import org.junit.Test;
/**
* @author 测试类
*
*/
public class UserTest {
@Test
public void testSave() {
//获取session,由于是测试代码,这里就不再使用标准格式,但是大家要记住标准格式try-catch-finally
Session session=HibernateUtils.getSession();
session.beginTransaction();
User user=new User();
user.setName("leige2");
user.getAddressBag().add("zhuamdian1");
user.getAddressBag().add("leige");
session.save(user);
session.getTransaction().commit();
session.close();
}
@Test
public void testGet(){
Session session=HibernateUtils.getSession();
session.beginTransaction();
User user=(User) session.get(User.class, 1);
System.out.println(user);;
System.out.println(user.getAddressBag());
session.getTransaction().commit();
session.close();
}
}