hibernate 映射 bag/idbag值对象 简单映射

 接上篇《hibernate 映射 set 值对象 简单映射》

如果我们允许用户不停的添加同一工作到user中改如何处理?

    允许重复元素的无序集合称为包(bag),javaCollections框架并没有具体的实现,仅有此集合的语义定义,因此需要一种匹配的实现。

可以有两种做法

1、用java.util.Collection接口编写集合属性,并在声明中用jak的一个ArrayList对其初始化,在hibernate中用<bag><idbag>元素映射即可。Hibernate有一个内建的PersistentBag可以处理列表;但与包的预定一致,它忽略元素在ArrayList中的位置。也就是说你得到了一个持久化的Collection.

2、用java.util.List接口编写属性即可,并在声明中用JDK的一个ArrayList把它初始化,像像前面一样去映射他,但是在领域模型类中公开了一个不同的集合接口。这样很有效,但不建议使用,因为使用这个集合属性的客户端可能认为元素的顺序会始终被保存,其实如果把它作为<bag>或<idbag>映射,就并非如此。

建议使用第一个选项。

由于我们需要存储不同的task,表必须需要一个不同的主键而<idbag>映射添加了一个黛绿列到集合表,很像用于实体的合成标示符;

修改的User类如下:

package com.ccay.test.valueCollection.idbag.xml;

import java.util.ArrayList;
import java.util.Collection;


public class User {
	private long userId;
	private String firstname;
	private String lastname;
	private Collection<String> tasks = new ArrayList<String>();
	public long getUserId() {
		return userId;
	}
	public void setUserId(long userId) {
		this.userId = userId;
	}
	public String getFirstname() {
		return firstname;
	}
	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}
	public String getLastname() {
		return lastname;
	}
	public void setLastname(String lastname) {
		this.lastname = lastname;
	}
	public Collection<String> getTasks() {
		return tasks;
	}
	public void setTasks(Collection<String> tasks) {
		this.tasks = tasks;
	}
}


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.ccay.test.valueCollection.idbag.xml.User" table="VAL_COLLECTION_SIMPLE_SET_USER" >
        <id name="userId" type="long">
            <column name="USER_ID"/>
            <generator class="native" />
        </id>
        <property name="firstname" type="string">
            <column name="FIRSTNAME" length="40" />
        </property>
        <property name="lastname" type="string">
            <column name="LASTNAME" length="50" />
        </property>
        <idbag name="tasks" table="VAL_COLLECTION_SIMPLE_SET_TASKS">
        	<collection-id type="long" column="USER_TASK_ID">
        	<!-- 注意这里的主键生成策略不同于user,当指定native后会报错具体原因未找到 -->
        		<generator class="increment"/>
        	</collection-id>
        	<key column="USER_ID"/>
        	<element type="string" column="TASK" not-null="true"></element>
        </idbag>
    </class>
</hibernate-mapping>


测试类

package com.ccay.test.valueCollection.idbag.xml;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

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

import com.ccay.test.HibernateSessionFactory;

public class Test {
	@org.junit.Test
	public void testDDL(){
		Session session = HibernateSessionFactory.getSession();
		Transaction transaction = session.beginTransaction();
		ArrayList<String> tasks = new ArrayList<String>();
		tasks.add("student");
		tasks.add("student");
		tasks.add("student");
		tasks.add("student");
		User user= new User();
		user.setFirstname("firstName");
		user.setLastname("lastName");
		//虽然此方法接收所有实现Collection的接口,但最好使用ArratList,hibernate内部也是将其转换为ArrayList了。
		user.setTasks(tasks);
		
		session.save(user);
		transaction.commit();
		HibernateSessionFactory.closeSession();
	}
}


自动ddl如下

    create table VAL_COLLECTION_SIMPLE_SET_TASKS (
        USER_ID bigint not null,
        TASK varchar(255) not null,
        USER_TASK_ID bigint not null,
        primary key (USER_TASK_ID)
    )
    create table VAL_COLLECTION_SIMPLE_SET_USER (
        USER_ID bigint not null auto_increment,
        FIRSTNAME varchar(40),
        LASTNAME varchar(50),
        primary key (USER_ID)
    )
    alter table VAL_COLLECTION_SIMPLE_SET_TASKS 
        add index FK839C9A2737A11A64 (USER_ID), 
        add constraint FK839C9A2737A11A64 
        foreign key (USER_ID) 
        references VAL_COLLECTION_SIMPLE_SET_USER (USER_ID)


方向工程

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值