今天调了一下午程序,就是为了弄清为何我在保存视频的时候,除了update语句,莫名其妙地还执行了一句抓取视频所有标签的语句。并且这个语句非常雷,以前见过的无非就是两个表的联合查询,这条语句直接将视频表、标签表和视频标签的关系表 总共三个表做了关联查询。这个查询的效率自然不言而喻。而且查出来的结果集因为是三个表的笛卡尔积,也肯定很惊人。总之就是效率瓶颈了。
说了这么一大堆,其实我的程序很简单,一个视频类(Video),一个标签类(Tag),两个类是单向多对多的关系。因为同一个标签对应的视频可能很多很多,所以就没有必要在标签类中包含视频的set了。
@Entity
@Table(name="vid_video")
public class Video extends BaseEntity {
...
@ManyToMany(
cascade ={CascadeType.PERSIST,CascadeType.MERGE},
fetch=FetchType.LAZY
)
@JoinTable(
name="vid_video_tag",
joinColumns={@JoinColumn(name="video_id")},
inverseJoinColumns={@JoinColumn(name="tag_id")}
)
@OrderBy("created")
public Set<Tag> getTags() {
return tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
}
@Entity
@Table(name="vid_tag")
public class Tag extends BaseEntity {
....
}
就是这么简单的两个类,我在保存视频(就是无非更新了一下视频的标题或描述而已)的时候,打开log一看,竟然有这么一条惊人的语句:
select
video0_.id as id135_1_, video0_.browse_num as browse2_135_1_, video0_.created as created135_1_, video0_.description as descript4_135_1_, video0_.oppose_num as oppose5_135_1_, video0_.original_url as original6_135_1_, video0_.owner_displayname as owner7_135_1_, video0_.owner_id as owner8_135_1_, video0_.privacy_level as privacy9_135_1_, video0_.support_num as support10_135_1_, video0_.thum_url as thum11_135_1_, video0_.title as title135_1_, video0_.url as url135_1_,
tags1_.video_id as video1_3_, tag2_.id as tag2_3_, tag2_.id as id136_0_, tag2_.created as created136_0_, tag2_.name as name136_0_
from vid_video video0_
left outer join vid_video_tag tags1_ on video0_.id=tags1_.video_id
left outer join vid_tag tag2_ on tags1_.tag_id=tag2_.id
where video0_.id=?
order by tag2_.created asc
执行的程序如下:
VideoAction.java:
// 这个get方法会对video表发起一次查询,也如意料之中的并没有对video的tag集合进行关// 联查询,因为video中的tag集合是懒加载的。
Video p = videoManager.getVideo(video.getId());
p.setTitle(video.getTitle());
p.setDescription(video.getDescription());
p.setPrivacyLevel(video.getPrivacyLevel());
// 在调用updateVideo()的时候,并没有只是执行update 语句,而是在update语句之前还向
// 数据库发起了一条查询语句,这个查询语句就是上面那堆让我头大三圈的东西!
p = videoManager.updateVideo(p);
videoManager.getVideo() 无非就是:
getHibernateTemplate().get(id)
videoManager.updateVideo() 无非就是:
getHibernateTemplate().merge(object)
就这么简单的程序,为何会莫名其妙地在执行对video的update操作之前要先执行一个对video的标签集合的抓取操作呢?该集合明明是lazy的,奇怪啊,抓狂了。。。
分享到:
相关推荐
在Java的持久化框架中,Hibernate是一个非常重要的组件,它提供了强大的对象关系映射(ORM)功能,使得开发者可以方便地将数据库操作转化为面向对象的编程。本实例将深入探讨Hibernate中的三种基本关联关系:一对一...
这种关系通常出现在一个实体类拥有多条与另一个实体类相关的记录,而另一个实体类可能只有一条对应的记录。例如,一个员工可以属于多个部门,但一个部门只有一个经理。本压缩包中的"hibernateM2O_Dan"文件包含了实现...
首先,一对多关系在数据库中很常见,例如一个用户可以有多个订单,一个班级可以有多名学生等。在Hibernate中,这种关系通过在实体类和映射文件中设置相应的注解或XML配置来实现。 1. **配置一对多关系**: - 在...
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系映射是一种常见的数据库交互模式,它用于表示两个实体之间复杂的关系。在这个场景中,一个实体可以与多个其他实体相关联,反之亦然。例如,在学生和课程...
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系是数据库中常见的关联类型,它允许一个实体实例对应多个其他实体实例,反之亦然。在本案例中,我们将深入探讨如何使用Hibernate来处理多对多的关系映射,...
在数据库设计中,多对多关联表示两个表之间的关系,如学生和课程的关系,一个学生可以选修多门课程,而一门课程也可以被多个学生选修。在Hibernate中,这种关系需要通过中间表(也称为关联表或连接表)来实现,它...
多对一指的是多个实体(如订单)与一个实体(如客户)之间的关联,而一对多则是指一个实体(如客户)可以拥有多个相关联的实体(如订单)。这种关系在现实世界中普遍存在,例如,一个客户可以下多个订单,但每个订单...
在现实生活中,很多关系都呈现出多对多的特性,例如学生与课程之间的关系,一个学生可以选修多门课程,一门课程也可以被多个学生选修。在数据库设计中,这种关系通过中间表(也称为关联表或连接表)来实现,它包含两...
2. **关系属性**:在两个实体类中,分别定义一个表示多对多关系的集合属性,如`List`或`Set`,并使用`@ManyToMany`注解。 3. **中间表配置**:通过`@JoinTable`注解定义中间表的详细信息,包括表名、连接字段等。 4....
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关联关系是一种常见的实体间关系类型,它表示一个实体可以与多个其他实体相关联,反之亦然。本示例"Hibernate多对多关联关系demo"将深入探讨如何在实际开发中...
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关系是数据库中常见的关联类型,它允许一个实体实例对应多个其他实体实例,反之亦然。本篇将深入探讨Hibernate如何处理这种复杂的数据关联。 一、多对多关系...
这个压缩包文件“HibernateORM”很可能包含了关于如何在实际项目中设置和使用Hibernate一对多双向关联的示例代码、配置文件或者详细教程。通过学习这些材料,开发者能够深入理解如何在Java应用中利用Hibernate来处理...
本篇文章将详细讲解"hibernate一对多与多对一"的关系映射概念,以及如何在实际开发中进行配置和使用。 首先,我们来看一下“一对多”关系。在现实世界中,这种关系可以对应到例如一个班级有多个学生,或者一个人...
本文将深入探讨Hibernate中的一对多和多对一映射关系,并通过一个实际的demo演示它们在增删查改操作中的应用。 首先,我们要理解什么是数据库的关联关系。在数据库设计中,我们经常遇到一种情况,即一个实体可能与...
2. **Java类的双向关联**:在Java类中,使用`@ManyToMany`注解定义多对多关系,并可以通过`mappedBy`属性指定另一个实体的集合属性作为反向引用。 ```java @Entity public class Student { @ManyToMany(mappedBy =...
标题"Hibernate多对多实例+数据库代码"揭示了我们将在讨论一个使用Hibernate框架实现的多对多关系映射的实际案例。在这个实例中,开发人员将两个或多个实体之间的复杂关联转化为简单易懂的数据库操作。描述中提到...
学生和班级的关系可以是多对多,因为一个学生可以属于多个班级,反过来,一个班级也可以有多个学生。为了实现这种关系,我们需要创建一个关联表(通常称为中间表),并使用`@ManyToMany`注解。例如,在`Student`类...
在Java的持久化框架Hibernate中,一对多关系是数据库中常见的关联类型,它表示一个实体可以与多个其他实体相关联。在这个"hibernate 一对多,两个实例项目"中,我们将深入探讨如何在实际开发中应用这种关系,并通过...
标题"Hibernate双向一对多"指的是Hibernate框架中的一个重要关系映射概念,即在一个实体类中,一个实例可以与多个另一个实体类的实例相关联,而在另一个实体类中,每个实例也可以关联到该实体类的一个实例。这种关系...