Hibernate Set集合映射简单例子

本文详细阐述了如何使用Hibernate框架实现用户与多个电子邮件地址之间的关系管理,包括表设计、实体类实现、映射文件创建及数据库操作流程,并通过实例展示了添加、修改、查询和删除数据的操作。

用户表(user_set)和电子邮件表(email_set)之间的关系:每个用户可以有多个不同的电子邮件地址,对用户来说,电子邮件就是一个集合,则在用户的实体类中就可以通过定义一个集合类型的属性来表达。

创建两个对应表:

email_set:

create table email_set(
id int(11) not null,
address varchar(100) not null
)engine=innodb default charset=gbk;

user_set:

create table user_set(
id int(11) not null auto_increment,
name varchar(100) not null default '',
primary key(id)
)engine=innodb default charset=gbk;

建立角色实体类UserSet.java:

package collect.set;

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

public class UserSet implements java.io.Serializable {

	// Fields

	private Integer id;
	private String name;
	private Set emails = new HashSet();

	// Constructors

	/** default constructor */
	public UserSet() {
	}

	/** full constructor */
	public UserSet(String name) {
		this.name = name;
	}

	// Property accessors

	public Integer getId() {
		return this.id;
	}

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

	public String getName() {
		return this.name;
	}

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

	public Set getEmails() {
		return emails;
	}

	public void setEmails(Set emails) {
		this.emails = emails;
	}

	public void addEmail(String email) {
		this.emails.add(email);
	}

	public void removeEmail(String email) {
		this.emails.remove(email);
	}
}

解析:由于一个user可以有多个电子邮件,而且每个电子邮件不能重复。所以在UserSet类中定义了Set类型的变量,用来保存电子邮件。

建立Set类型的映射文件UserSet.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="collect.set.UserSet" table="user_set" catalog="ssh">
		<id name="id" type="java.lang.Integer">
			<column name="id" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="name" length="100" not-null="true" />
		</property>
		<!--Set类型映射-->
		<set name="emails" table="email_set">
			<key column="id"></key>
			<element type="java.lang.String">
				<column name="address"></column></element>
		</set>
	</class>
</hibernate-mapping>

解析:使用set映射元素来关联email_set表,set映射元素的上面几个配置:

name:集合属性的名字。

table:这个集合对应表的名称(在此指定了Set元素对应的表为email_set)。

嵌套的标签<key>和<element>对应表"email_set"中的字段,其中<key>即表email_set的外键(取值为表user_set的主键值)。

对于List集合的话,要多加一个<index>标签来配置List索引。

通过此Set类型映射,当在表user_set中INSERT一条记录时,user_set表中多了一条记录如('1' , 'user1'),这时集合属性emails中添加的元素如email1、email2就会自动对应地(以id='1')INSERT到表email_set中去。对于“修改、删除数据”操作是一样的道理,两表同步完成UPDATE、DELETE操作。

将该映射文件加入到Hibernate配置文件中,建立测试类Test.java:

package collect.set;

import java.util.Iterator;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {

	public static void main(String[] args) {
		// Configuration管理Hibernate配置
		Configuration config = new Configuration().configure();
		// 根据Configuration建立 SessionFactory
		// SessionFactory用来建立Session
		SessionFactory sessionFactory = config.buildSessionFactory();

		// 创建实例
		UserSet user1 = new UserSet();
		user1.setName("user1");
		user1.addEmail("email1");
		user1.addEmail("email2");
		user1.addEmail("email2");
		        
		UserSet user2 = new UserSet();
		user2.setName("user2");
		user2.addEmail("email3");

		// 定义主键变量
		Integer pid;

		// 添加数据
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			// 创建主键变量
			pid = (Integer) session.save(user1);
			session.save(user2);
			tx.commit();
		} catch (RuntimeException e) {
			if (tx != null)
				tx.rollback();
			throw e;
		} finally {
			session.close();
		}

				
		// 修改数据
		session = sessionFactory.openSession();
		tx = null;
		try {
			tx = session.beginTransaction();
			user1 = (UserSet) session.get(UserSet.class, pid);
			//修改user名字
			user1.setName("user1 update");
			user1.removeEmail("email1");
			user1.addEmail("email4");
			session.update(user1);
			tx.commit();
		} catch (RuntimeException e) {
			if (tx != null)
				tx.rollback();
			throw e;
		} finally {
			session.close();
		}
		
		
		// 查询数据
		session = sessionFactory.openSession();
		user1 = (UserSet) session.get(UserSet.class, pid);
		System.out.println("user name:" + user1.getName());
		Iterator iter = user1.getEmails().iterator();
		while (iter.hasNext()) {
			System.out.println("email name:" + (String) iter.next());
		}
		session.close();
		
		
		// 删除数据
		session = sessionFactory.openSession();
		tx = null;
		try {
			tx = session.beginTransaction();
			user1 = (UserSet) session.get(UserSet.class, pid);
			session.delete(user1);
			tx.commit();
		} catch (RuntimeException e) {
			if (tx != null)
				tx.rollback();
			throw e;
		} finally {
			session.close();
		}
			
		// 关闭sessionFactory
		sessionFactory.close();

	}

}

注意:添加、修改、查询、删除数据,这几步要一步一步来进行测试,即在添加数据时,其他代码先注释掉;添加完后在数据库里查询结果,然后再解除"修改数据"部分的注释,就这样一步步完成测试工作。否则出现意想不到的结果。

只完成"添加数据"后的数据库中结果:

清空数据库,同时完成“添加、修改数据”,数据库中结果:

(可见在修改数据时,删除了email1,增加了email4)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzyjr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值