通过一个简单的例子描述一下在hibernate中如何实现多对多的关系。
系统环境:Webwork + spring + hibernate
逻辑描述:实现一个用户(User)和组(Group)的逻辑关系。系统中的用户可以自行创建组,同时每个组中可以添加不同的成员。这个环境是一个典型的多对多的关系,唯一的一个区别是,每个组是有从属的,也是说每个组隶属于一个用户,在这一点上是一个一对多的关系。
系统目标,可以灵活创建用户、组,同时组中可以添加用户。
数据库表:User(用户表)、groups(用户组),用过powerdesign可以设计一个数据逻辑模型,将其转化为屋里模型后,实际我们可以看到,系统自动创建了另外一个表,就是usergroups,在这张表中记录的是user和groups的对应关系。为了表明group的从属关系,我们在group中定义一个字段ownerid,然后通过一对多的关系来描述用户和组之间的关系。
user:
create table user
(
id varchar(32) not null,
email varchar(100) not null,
username varchar(50) not null
);
groups:
create table groups
(
id varchar(32) not null,
ownerid varchar(32) not null,
name varchar(100) not null
);
usergroups
create table usergroups
(
userid varchar(32) not null,
groupid varchar(32) not null
);
alter table groups add constraint FK_Reference_3 foreign key (ownerid)
references user (id) on delete restrict on update restrict;
alter table usergroups add constraint FK_Reference_1 foreign key (userid)
references user (id) on delete cascade on update cascade;
alter table usergroups add constraint FK_Reference_2 foreign key (groupid)
references groups (id) on delete cascade on update cascade;
hibernate实现:
对于hibernate的实现,我们可以通过hibernate的工具来生成基本的映射文件和bean,但是在这里面需要注意以下一些问题:
1、对于saveOrUpdate的设置:当DAO更新数据库的时候,我们可以采用save、update两种方式去区分insert、update两种数据库操作,当然一种更方便的方法是调用HibernateTemplate.saveOrUpdate()通用方法,系统将根据主键来判断是insert操作,还是update操作。这时候就要在bean的映射文件中表明,否则系统将无法正确处理。例如User.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="com.example.dao.model.User" table="user" catalog="many" >
<id name="id" type="java.lang.String" unsaved-value="null">
<column name="id" length="32" />
<generator class="uuid.hex"></generator>
</id>
<property name="email" type="java.lang.String">
<column name="email" length="100" not-null="true" />
</property>
<property name="username" type="java.lang.String">
<column name="username" length="50" not-null="true" />
</property>
<set name="groupses" table="usergroups" catalog="many" cascade="none" lazy="true">
<key>
<column name="userid" length="32" not-null="true" />
</key>
<many-to-many entity-name="com.example.dao.model.Groups">
<column name="groupid" length="32" not-null="true" />
</many-to-many>
</set>
<set name="ownergroupses" inverse="true" cascade="delete" lazy="true" order-by="createtime desc">
<key>
<column name="ownerid" length="32" not-null="true" unique="false" />
</key>
<one-to-many class="com.example.dao.model.Groups" />
</set>
</class>
</hibernate-mapping>
在xml中我们可以看到,id设置了unsaved-value="null",这样系统就会通过对象的id来决定是insert还是update,如果user的id为null,那么系统将按照insert处理,反之将按照update处理。这里有个注意的问题,当使用BeanUtils来转换formbean到bean的时候,将把null值处理为“”,这样系统在保存的时候,认为id不是null,数据库将进行update处理,就会出现错误,这时就要求我们强制设置一下,保证系统的正确处理
2、关于lazy=true(延迟加载)的使用
在使用hibernate时,如果碰到一对一、一对多、多对多的关系,经常需要使用延迟加载来提高系统的性能,否则每次系统调用一个bean的时候都需要将关联的对象也同时load出来,系统的效能是很低的。hibernate通过延迟加载的方法来提高性能。但是如果我们通过spring来管理系统里面的bean,就会遭遇到一个常见的问题,就是当使用了延迟加载后,我们如果在load一个对象后,还需要load关联的对象,系统经常会抛出session已经关闭的异常,这时候就需要使用OpenSessionInView来延缓session关闭的时间,系统将在request完全load结束后关闭session。着也随之带来一个问题,如果用户网络状况比较差的情况下,request load的时间会非常长,就会造成session迟迟不能关闭,那么就会保持一个很长的Connection,当访问量增大的时候,就会造成系统性能下降(数据连接池中链接迟迟不能回收)。解决这一问题的办法是使用aop的拦截器,来处理这种延迟加载。但方法相对比较复杂。就目前的情况来讲,暂时使用OpenSessionInView是一个折衷的办法,其具体配置如下,在需要延迟加载的hbm.xml中设置lazy=true,然后在web.xml中添加OpenSessionInView:
<filter>
<filter-name>opensession</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>mySessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>opensession</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
这里注意不要在filter中设置singleSession=false,否则会造成多session的异常
3、关于inverse,cascade的设置
对于hibernate中inverse的设置,实际是表明哪一端对系统数据发生的变化不做处理,也就是谁来维护关系。例如本例中user和group,usergroups是user和group的对应关系,从实际上来讲,当组被删除时,用户和组的关系发生变化,那么实际应该是groups来维护usergroups的关系,也就应该在user.hbm.xml设置为inverse=true,这样关系就交有groups来维护了。
对于cascade,实际标识的是级联的操作,例如user删除的时候,实际需要将groups中相应的组删除,那么这里就需要在user.hbm.xml中标识cascade="delete"
分享到:
相关推荐
本文将深入探讨Hibernate如何实现多对多关联映射,并通过实际例子解析相关配置和操作。 一、多对多关联概述 在数据库设计中,多对多关联表示两个表之间的关系,如学生和课程的关系,一个学生可以选修多门课程,而...
“Hibernate例子”表明这是一个关于如何使用Hibernate进行数据库操作的实际代码示例集合。 **文件名称解析:** - Hibernate_1to1:这个文件可能包含了关于一对一关联关系的示例代码。在Hibernate中,一对一关联通常...
`@OneToMany`、`@ManyToMany`和`@OneToOne`注解分别对应了一对多、多对多和一对一的关系映射,通过合理的配置,可以实现数据的高效管理和操作。在实际开发中,根据业务需求灵活运用这些注解,可以构建出稳定、可扩展...
本例子主要关注的是Hibernate中的多对多映射,这是一个复杂但常见的关系类型,适用于表示两个实体之间没有主次之分的关系。 在数据库设计中,多对多关系意味着一个表的记录可以对应另一个表中的多个记录,反之亦然...
在本项目"hibernate多对多的简单实现"中,我们看到的是学生(Student)与课程(Course)之间的多对多关系。SSH指的是Struts、Spring、Hibernate这三个流行开源框架的组合,它们常常被用于构建企业级的Java应用。 1....
本示例着重于如何利用Hibernate来实现不同类型的数据库表之间的关联,包括一对一、一对多、多对一以及多对多的关系。 **一对一关系:** 一对一关联通常发生在两个表之间有唯一对应关系时,比如一个用户只有一个账号...
标题"hibernate例子(多对一)"表明我们将探讨的是一个关于Hibernate框架的实例,特别关注的是“多对一”的关系映射。在数据库设计中,“多对一”关系指的是一个实体(如表)的多个记录可以与另一个实体的一个记录相...
在这个例子中,我们看到的是`Team`(团队)与`Member`(成员)之间的多对多关系,通过`Map`数据结构来实现。以下是关于Hibernate使用Map实现多对多映射的具体知识点: 1. **数据库结构**: - `team2`表存储团队...
本教程将基于“华南银行项目”这一实例,深入探讨Hibernate中的四种基本映射关系:一对一、一对多、多对一以及多对多。我们将从实际应用的角度出发,通过具体的代码示例来理解这些概念。 **一对一映射(One-to-One...
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系是数据库中常见的关联类型,它允许一个实体实例对应多个其他实体实例,反之亦然。本篇将深入探讨Hibernate如何处理这种复杂的数据关联。 一、多对多关系...
总结起来,Hibernate中的一对多/多对一关联是通过主外键映射来实现的,通过注解和配置文件定义实体间的关联关系,利用懒加载或立即加载策略控制数据获取,同时要注意双向关联的维护和级联操作的设置,以确保数据的...
本篇文章将详细讲解"hibernate一对多与多对一"的关系映射概念,以及如何在实际开发中进行配置和使用。 首先,我们来看一下“一对多”关系。在现实世界中,这种关系可以对应到例如一个班级有多个学生,或者一个人...
本项目“hibernate一对多项目”旨在演示如何在JavaWeb应用中使用Hibernate处理一对多的关系映射。这里我们将深入探讨 Hibernate 的一对多关系、配置以及在实际项目中的应用。 首先,一对多关系在数据库中很常见,...
这个压缩包文件“HibernateORM”很可能包含了关于如何在实际项目中设置和使用Hibernate一对多双向关联的示例代码、配置文件或者详细教程。通过学习这些材料,开发者能够深入理解如何在Java应用中利用Hibernate来处理...
这种关联关系在实际业务场景中非常常见,比如用户与角色、课程与学生等例子,都需要用到多对多的关系来描述它们之间的复杂联系。 首先,让我们理解什么是多对多关系。在数据库设计中,多对多关系意味着一个实体可以...
本主题将深入探讨如何使用Hibernate实现一对一双向关联关系,并通过源码解析这一过程。 一对一双向关联关系指的是两个实体类之间存在一对一的关系,且在各自的类中都可以直接访问对方。这种关联可以通过注解或XML...
在Hibernate中,这种关系通过`@ManyToMany`注解来实现。 首先,我们需要在相关的实体类中定义这种关系。假设我们有`Student`和`Course`两个实体类,它们之间的多对多关联可以通过以下方式声明: ```java @Entity ...
这种关系在数据库中通常通过主键外键关联实现,Hibernate提供了多种方式来建立和维护这种关系,例如使用`@OneToOne`注解。 **五、懒加载和乐观锁** `hibernate_lazy_for_single_end`和`hibernate_optimistic_...
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系是数据库中常见的关联类型,它表示两个实体类之间可以有多个对应的关系。例如,学生和课程就是一个典型的多对多关系,一个学生可以选修多个课程,而一个...
综上所述,这个压缩包提供了关于Hibernate关系映射的全面教程,包括多对多、一对一和一对多的关系配置,以及如何在Spring+Hibernate+Struts环境中应用这些关系。对于想要深入理解Hibernate并提升开发效率的Java...