hibernate 映射 set 值对象 简单映射
应用场景:
两个对象间是一对多的关系,且多的一方是值对象,一的一方是实体对象(什么是值对象什么是实体对象,请参见本博客的《hibernate 误区1 正确区分值对象和实体对象》),这时候不能使用组件映射,因为组件映射通常暗示着一对一的关联如(本博客的《hibernate 映射 组件映射》中举得例子一样,一个人通常只有或者我们的应用系统通常只关注一个家庭地址,一个人也只有一个账单地址),这时候就要使用set的值对象映射
示例实体:
User 对一个user,可以在一生中有多份工作,我们的User实体需要保存这些工作的名称(其他的暂不关注),根据set的语义:不同的 无序的集合。(如果你需要关注顺序,请参见本博客的其他文章)我们定义实体如下:
注:如果我们允许用户不停的添加同一工作到user中的话请参见下篇文章《hibernate 映射 bag/idbag值对象 简单映射》;
一、XML实现
package com.ccay.test.valueCollection.set;
import java.util.HashSet;
import java.util.Set;
public class User {
private long userId;
private String firstname;
private String lastname;
private Set<String> tasks = new HashSet<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 Set<String> getTasks() {
return tasks;
}
public void setTasks(Set<String> tasks) {
this.tasks = tasks;
}
}
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">
<hibernate-mapping>
<class name="com.ccay.test.valueCollection.set.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>
<set name="tasks" table="VAL_COLLECTION_SIMPLE_SET_TASKS">
<key column="USER_ID"/>
<element type="string" column="TASKS" not-null="true"/>
</set>
</class>
</hibernate-mapping>
测试代码如下:
package com.ccay.test.valueCollection.set;
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();
Set<String> tasks = new HashSet<String>();
tasks.add("student");
tasks.add("programer");
User user= new User();
user.setFirstname("firstName");
user.setLastname("lastName");
user.setTasks(tasks);
session.save(user);
transaction.commit();
HibernateSessionFactory.closeSession();
}
}
hibernate自动的schema如下
create table VAL_COLLECTION_SIMPLE_SET_TASKS (
USER_ID bigint not null,
TASKS varchar(255) not null,
primary key (USER_ID, TASKS)
)
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 FK839C9A27309B6B8 (USER_ID),
add constraint FK839C9A27309B6B8
foreign key (USER_ID)
references VAL_COLLECTION_SIMPLE_SET_USER (USER_ID)
注解实现
package com.ccay.test.valueCollection.set.annotation;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
import org.hibernate.annotations.CollectionOfElements;
@Entity
@Table(name="VAL_COLLECTION_SIMPLE_SET_USER")
public class User {
@Id
@GeneratedValue
private long userId;
@Column(name="FIRSTNAME",nullable=false)
private String firstname;
@Column(name="LASTNAME",nullable=false)
private String lastname;
//已经废弃的注解
//@CollectionOfElements(targetElement=java.lang.String.class)
@ElementCollection(targetClass=java.lang.String.class)
@JoinTable(
name="VAL_COLLECTION_SIMPLE_SET_TASKS",
joinColumns = {@JoinColumn(name="USER_ID")}
)
@Column(name="TASKS",nullable=false)
private Set<String> tasks = new HashSet<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 Set<String> getTasks() {
return tasks;
}
public void setTasks(Set<String> tasks) {
this.tasks = tasks;
}
}
测试代码
package com.ccay.test.valueCollection.set.annotation;
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();
Set<String> tasks = new HashSet<String>();
tasks.add("student");
tasks.add("programer");
User user= new User();
user.setFirstname("firstName");
user.setLastname("lastName");
user.setTasks(tasks);
session.save(user);
transaction.commit();
HibernateSessionFactory.closeSession();
}
}
自动ddl
create table VAL_COLLECTION_SIMPLE_SET_TASKS (
USER_ID bigint not null,
TASKS varchar(255) not null,
primary key (USER_ID, TASKS)
)
create table VAL_COLLECTION_SIMPLE_SET_USER (
userId bigint not null auto_increment,
FIRSTNAME varchar(255) not null,
LASTNAME varchar(255) not null,
primary key (userId)
)
alter table VAL_COLLECTION_SIMPLE_SET_TASKS
add index FK839C9A2794AB95DB (USER_ID),
add constraint FK839C9A2794AB95DB
foreign key (USER_ID)
references VAL_COLLECTION_SIMPLE_SET_USER (userId)
逆向工程