今天学习了hibernate集合映射中many-to-one的用法,现将一些体会写下来。
还是采用教程中的例子:两个实体类person和Address
package eg;
public class Person{
private Long id;
private Address address;
public Person() {
}
public Long getId(){
return this.id;
}
private void setId(Long id){
this.id = id;
}
public void setAddress(Address address){
this.address = address;
}
public Address getAddress(){
return this.address;
}
}
package eg;
import java.util.*;
public class Address{
private Long addressId;
private List people = new ArrayList();
public Address(){}
public Long getId(){
return this.addressId;
}
private void setId(Long addressId){
this.addressId = addressId;
}
public void setPeople(List people){
this.people = people;
}
public List getPeople(){
return this.people;
}
}
映射文件:Person.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="eg">
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
class="Address"
column="addressId"
not-null="true"
insert="false"
update="false"
/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<list name="people" inverse="false" lazy="true" cascade="all">
<key column="addressId" not-null="true"/>
<list-index column="peopleidx" base="0"/>
<one-to-many class="Person" />
</list>
</class>
</hibernate-mapping>
测试代码:
package eg;
import org.hibernate.Session;
import org.hibernate.impl.SessionImpl;
import org.hibernate.Hibernate;
import java.util.*;
import org.hibernate.tutorial.util.HibernateUtil;
public class Manager {
public static void main(String[] args) throws Throwable{
Manager mgr = new Manager();
if (args[0].equals("store")) {
mgr.createAndStorePerson();
}else if (args[0].equals("storel")) {
mgr.createAndStorePerson(3L);
}else if (args[0].equals("loadA")) {
List s = mgr.loadAddress(3L);
}
HibernateUtil.getSessionFactory().close();
}
private Long createAndStorePerson(){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person p = new Person();
Address a = new Address();
p.setAddress(a);
Integer i = Integer.valueOf(new Random().nextInt(20));
a.getPeople().add(p);
session.save(a);
session.getTransaction().commit();
return p.getId();
}
private void createAndStorePerson(Long l){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person p = new Person();
Address a = (Address)session.load(Address.class,l);
a.getPeople().add(p);
p.setAddress(a);
session.save(a);
session.getTransaction().commit();
}
private List loadAddress(Long l) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Address a = (Address)session.load(Address.class,l);
List s = a.getPeople();
Hibernate.initialize(s);
session.getTransaction().commit();
return s;
}
}
在整个测试的过程中有几点需要记住:
1、单向映射时:只在多端声明many-to-one即可单端不用知道映射,也只在多端维护关系。
<many-to-one name="address"
column="addressId"
not-null="true"/>
如上面的address是指向实体类Person中引用的实体对象address,在程序中通过设定对Address实体的引用而建立关系的。
Person p = new Person();
Address a = new Address();
p.setAddress(a);
session.save(a);
2、双向映射时,须在两端设置,也要让单端知道关系,而哪一端来维护关系要看具体的情形。一般情况下,单端要通过一个集合来引用对应的多端实体对象。可用的集合有map、set、list、array、bag、idbag.
Hibernate要求持久化集合值字段必须声明为接口。
private List people = new ArrayList();
实际的接口可能是java.util.Set
,
java.util.Collection
, java.util.List
,
java.util.Map
, java.util.SortedSet
,
java.util.SortedMap
或者...任何你喜欢的类型!("任何你喜欢的类型" 代表你需要编写 org.hibernate.usertype.UserCollectionType
的实现.)
注意我们是如何用一个HashSet
实例来初始化实例变量的.这是用于初始化新创建(尚未持久化)的类实例中集合值属性的最佳方法。当你持久化这个实例时——比如通过调用persist()
——Hibernate 会自动把HashSet
替换为Hibernate自己的Set
实现。
根据不同的接口类型,被Hibernate注射的持久化集合类的表现类似HashMap
, HashSet
,
TreeMap
, TreeSet
or
ArrayList
。
集合类实例具有值类型的通常行为。当被持久化对象引用后,他们会自动被持久化,当不再被引用后,自动被删除。假若实例被从一个持久化对象传递到另一个,它
的元素可能从一个表转移到另一个表。两个实体不能共享同一个集合类实例的引用。因为底层关系数据库模型的原因,集合值属性无法支持空值语
义;Hibernate对空的集合引用和空集合不加区别。
如果你使用List
(或者其他有序集合类),你需要设置外键对应的key
列为 not null
(
假若集合映射的<key>
元素对应的底层外键字段是NOT NULL
的,那么为这一key元素定义not-null="true"
是很重要的。不要仅仅为可能的嵌套<column>
元素定义not-null="true"
,<key>
元素也是需要的。
),让Hibernate来从集合端管理关联,维护每个元素的索引(通过设置update="false"
and insert="false"
来对另一端反向操作)。同时由于list要在多端维护一个索引列,所以list映射应该设为在集合端具有inverse="false" cascade="save-update"属性。
通过list-index指定的索引字段所起的作用是保证list中可同时出现多个相同的外关键值,当hebernate自动维护索引时,只有在产生了多值的情况下才增加索引值。刚开始测试时不知道这点,见其值一直是0(没有产生多对一的值)还以为没有配合适,浪费了好多时间。这种情况下关系的维护应在集合端。
Person p = new Person();
Address a = new Address();
p.setAddress(a);
a.getPeople().add(p);
session.save(a);
但是相同的设置在换成array后只能存储实体值,list-index字段的值却不能自动生成,不知道在哪里解决。真是好像看懂了,拿到手里就傻了。
分享到:
相关推荐
"Hibernate one-to-many / many-to-one关系映射"是两个基本的关系类型,用于表示实体间的关联。在这个主题中,我们将深入探讨这两种关系映射的原理、配置和实际应用。 一、一对一(one-to-one)与一对多(one-to-...
在双向关联中,一方(通常是one-to-many的一方)需要通过`@OneToMany(mappedBy="")`来指定关联的另一方的属性,而另一方(many-to-one)则无需指定`mappedBy`,直接使用`@ManyToOne`即可。 4. 外键的处理 在one-to-...
在这些映射文件中,使用`<many-to-many>`标签来定义关系。例如: ```xml <!-- Student.hbm.xml --> <many-to-many class="Course" column="course_id" foreign-key="fk_student_course"/> <!-- Course.hbm.xml -->...
关联映射的本质: 将关联关系映射到数据库,所谓的...<many-to-one>会在多的一端加入一个外键,指向一的一端,这个外键是由<many-to-one> 中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致
在提供的代码示例中,`<many-to-one>` 标签中包含了 `cascade` 属性的注释示例,但是没有真正使用它。如果使用 `cascade="save-update"`,那么当保存 `User` 对象时,其关联的 `Group` 对象也会被保存或更新。 ####...
本程序包含: hibenate 上传图片,二进制数据,大文本,集合映射的多种关系,onetoone,ontomany,manytomany等关系详细代码示例以及注释,全部由本人测试通过,对理解hibernate配置有极大帮助。
对于`Department`,映射文件中会有一个`<class>`标签,其中包含`<set>`标签来定义员工集合,并且使用`<many-to-many>`或`<one-to-many>`标签来映射与`Employee`的关系。对于`Employee`,我们使用`<class>`标签,并在...
为了使用 `publisher` 属性,我们需要在 `Book` 类的 Hibernate 映射文件中添加 `<many-to-one>` 映射。这将在 `BOOK` 表中添加一个名为 `PUBLISHER_ID` 的列,并存储关联出版商的 ID。 ```xml <!-- 其他属性的...
在Hibernate中,一对一唯一外键关联映射可以通过 `<many-to-one>` 标签来配置。例如,以下是Person实体与IdCard实体的一对一唯一外键关联映射配置: ```xml <many-to-one name="idCard" column="card_id...
在Java的持久化框架Hibernate中,Many-to-Many映射是一种常见的关系模型,它用于表示两个实体类之间多对多的关系。在这个主题中,我们将深入探讨如何使用注解来实现这种映射,以及其背后的数据库原理和实际应用。 ...
本文将深入探讨“Hibernate关联映射中的Many-to-One关系”。 Many-to-One关联是现实世界中常见的关系类型,比如一个学生可以对应多个课程,而一个课程可能被多个学生选修。在数据库中,这通常表现为一对多(One-to-...
在数据库世界中,一对多(One-to-Many)关系是一种常见的关联类型,其中一个表(父表)可以与多个其他表(子表)相关联。在NHibernate中,配置这种映射关系对于理解和使用ORM至关重要。 一对多关系意味着一个实体...
标题"Hibernate one to many(many to one) 配置"涉及到的是关系型数据库在Java中的持久化框架Hibernate中的两种关联映射关系:一对一(One-to-One)和多对一(Many-to-One)。在数据库设计中,这种关系很常见,例如...
在配置双向一对多关联时,我们通常在"多"一端(这里是`Student`)的集合属性上使用`<many-to-one>`标签,将`Classes`对象映射到数据库中的外键。同时,在"一"端(`Classes`)使用`<set>`标签,表示班级可以包含多个...
今天我们要讨论的是Hibernate框架中的一个关键概念——抓取策略,特别是针对"many-to-one"关系的抓取策略。这篇博客将深入剖析这个主题,帮助你更好地理解和应用Hibernate。 Hibernate是Java领域中最流行的对象关系...
内网映射工具--UPnP自动端口映射工具
在映射文件中,我们使用`<one-to-one>`标签,并通过`constrained`属性来指定约束。例如,Person和IdCard的单向关联映射可以通过以下方式配置: ```xml <!-- Person映射 --> <param name="property">idCard ...
3. 在对应的映射文件中,使用`<set>`和`<one-to-many>`或`<many-to-one>`元素配置映射关系。 4. 如有必要,可以考虑将多对多关系转换为一对多,以优化性能和操作性。 理解并熟练掌握这些概念和实践,将有助于在使用...
在Hibernate中,我们可以使用`<many-to-many>`标签来配置多对多映射。下面是一个简单的例子: ```xml <many-to-many column="USER_ID" foreign-key="FK_USER_ROLE" entity-name="com.example.Role" table="USER...