`
yezi
  • 浏览: 279292 次
  • 来自: 北京
社区版块
存档分类
最新评论

关于多对多关系的hibernate实现例子

阅读更多
通过一个简单的例子描述一下在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例子”表明这是一个关于如何使用Hibernate进行数据库操作的实际代码示例集合。 **文件名称解析:** - Hibernate_1to1:这个文件可能包含了关于一对一关联关系的示例代码。在Hibernate中,一对一关联通常...

    Hibernate关于注解的一对多,多对多,一对一

    `@OneToMany`、`@ManyToMany`和`@OneToOne`注解分别对应了一对多、多对多和一对一的关系映射,通过合理的配置,可以实现数据的高效管理和操作。在实际开发中,根据业务需求灵活运用这些注解,可以构建出稳定、可扩展...

    hibernate多对多映射的例子

    本例子主要关注的是Hibernate中的多对多映射,这是一个复杂但常见的关系类型,适用于表示两个实体之间没有主次之分的关系。 在数据库设计中,多对多关系意味着一个表的记录可以对应另一个表中的多个记录,反之亦然...

    hibernate多对多的简单实现

    在本项目"hibernate多对多的简单实现"中,我们看到的是学生(Student)与课程(Course)之间的多对多关系。SSH指的是Struts、Spring、Hibernate这三个流行开源框架的组合,它们常常被用于构建企业级的Java应用。 1....

    hibernate实现数据库表的多种关系

    本示例着重于如何利用Hibernate来实现不同类型的数据库表之间的关联,包括一对一、一对多、多对一以及多对多的关系。 **一对一关系:** 一对一关联通常发生在两个表之间有唯一对应关系时,比如一个用户只有一个账号...

    hibernate例子(多对一)

    标题"hibernate例子(多对一)"表明我们将探讨的是一个关于Hibernate框架的实例,特别关注的是“多对一”的关系映射。在数据库设计中,“多对一”关系指的是一个实体(如表)的多个记录可以与另一个实体的一个记录相...

    Hibernate使用 Map实现多对多映射

    在这个例子中,我们看到的是`Team`(团队)与`Member`(成员)之间的多对多关系,通过`Map`数据结构来实现。以下是关于Hibernate使用Map实现多对多映射的具体知识点: 1. **数据库结构**: - `team2`表存储团队...

    hibernate常用一对一、一对多、多对一、多对多映射关系真实例子(华南银行项目)

    本教程将基于“华南银行项目”这一实例,深入探讨Hibernate中的四种基本映射关系:一对一、一对多、多对一以及多对多。我们将从实际应用的角度出发,通过具体的代码示例来理解这些概念。 **一对一映射(One-to-One...

    hibernate 多对多源代码

    在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系是数据库中常见的关联类型,它允许一个实体实例对应多个其他实体实例,反之亦然。本篇将深入探讨Hibernate如何处理这种复杂的数据关联。 一、多对多关系...

    hibernate基于主外键的一对多/多对一关联

    总结起来,Hibernate中的一对多/多对一关联是通过主外键映射来实现的,通过注解和配置文件定义实体间的关联关系,利用懒加载或立即加载策略控制数据获取,同时要注意双向关联的维护和级联操作的设置,以确保数据的...

    hibernate一对多与多对一

    本篇文章将详细讲解"hibernate一对多与多对一"的关系映射概念,以及如何在实际开发中进行配置和使用。 首先,我们来看一下“一对多”关系。在现实世界中,这种关系可以对应到例如一个班级有多个学生,或者一个人...

    hibernate一对多项目

    本项目“hibernate一对多项目”旨在演示如何在JavaWeb应用中使用Hibernate处理一对多的关系映射。这里我们将深入探讨 Hibernate 的一对多关系、配置以及在实际项目中的应用。 首先,一对多关系在数据库中很常见,...

    Hibernate ORM - 一对多双向关联关系

    这个压缩包文件“HibernateORM”很可能包含了关于如何在实际项目中设置和使用Hibernate一对多双向关联的示例代码、配置文件或者详细教程。通过学习这些材料,开发者能够深入理解如何在Java应用中利用Hibernate来处理...

    Hibernate ORM - 多对多双向连接表关联关系

    这种关联关系在实际业务场景中非常常见,比如用户与角色、课程与学生等例子,都需要用到多对多的关系来描述它们之间的复杂联系。 首先,让我们理解什么是多对多关系。在数据库设计中,多对多关系意味着一个实体可以...

    hibernate外键实现一对一双向关联关系源码

    本主题将深入探讨如何使用Hibernate实现一对一双向关联关系,并通过源码解析这一过程。 一对一双向关联关系指的是两个实体类之间存在一对一的关系,且在各自的类中都可以直接访问对方。这种关联可以通过注解或XML...

    Hibernate多对多关联添加及查询示例

    在Hibernate中,这种关系通过`@ManyToMany`注解来实现。 首先,我们需要在相关的实体类中定义这种关系。假设我们有`Student`和`Course`两个实体类,它们之间的多对多关联可以通过以下方式声明: ```java @Entity ...

    Hibernate 经典例子全

    这种关系在数据库中通常通过主键外键关联实现,Hibernate提供了多种方式来建立和维护这种关系,例如使用`@OneToOne`注解。 **五、懒加载和乐观锁** `hibernate_lazy_for_single_end`和`hibernate_optimistic_...

    hibernate多对多关系

    在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系是数据库中常见的关联类型,它表示两个实体类之间可以有多个对应的关系。例如,学生和课程就是一个典型的多对多关系,一个学生可以选修多个课程,而一个...

    hibernate关系映射多对多关系

    综上所述,这个压缩包提供了关于Hibernate关系映射的全面教程,包括多对多、一对一和一对多的关系配置,以及如何在Spring+Hibernate+Struts环境中应用这些关系。对于想要深入理解Hibernate并提升开发效率的Java...

Global site tag (gtag.js) - Google Analytics