值类型的集合
让我们在 Person
实体里添加一个电子邮件的集合。这将以 java.lang.String
实例的 java.util.Set
出现:
private Set emailAddresses = new HashSet();
public Set getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(Set emailAddresses) {
this.emailAddresses = emailAddresses;
}
这个 Set
的映射如下:
set name"emailAddresses" table"PERSON_EMAIL_ADDR"
key column"PERSON_ID"
element type"string" column"EMAIL_ADDR"
set
比较这次和此前映射的差别,主要在于 element
部分,这次并没有包含对其它实体引用的集合,而是元素类型为 String
的集合(在映射中使用小写的名字”string“是向你表明它是一个 Hibernate 的映射类型或者类型转换器)。和之前一样,set
元素的 table
属性决定了用于集合的表名。key
元素定义了在集合表中外键的字段名。element
元素的 column
属性定义用于实际保存 String
值的字段名。
你可以看到集合表的主键实际上是个复合主键,同时使用了两个字段。这也暗示了对于同一个 person 不能有重复的 email 地址,这正是 Java 里面使用 Set 时候所需要的语义(Set 里元素不能重复)。
你现在可以试着把元素加入到这个集合,就像我们在之前关联 person 和 event 的那样。其实现的 Java 代码是相同的:
private void addEmailToPerson(Long personId, String emailAddress) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session.load(Person.class, personId);
// adding to the emailAddress collection might trigger a lazy load of the collection
aPerson.getEmailAddresses().add(emailAddress);
session.getTransaction().commit();
}
这次我们没有使用 fetch 查询来初始化集合。因此,调用其 getter 方法会触发另一附加的 select 来初始化集合,这样我们才能把元素添加进去。检查 SQL log,试着通过预先抓取来优化它。