今天调了一下午程序,就是为了弄清为何我在保存视频的时候,除了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的,奇怪啊,抓狂了。。。
分享到:
相关推荐
这里包含了hibernate多对一单向关联关系实现源码,希望对你有用。
hibernate一对一的关系hibernate一对一的关系hibernate一对一的关系hibernate一对一的关系hibernate一对一的关系hibernate一对一的关系
Hibernate一对一,一对多,多对多实例
Hibernate映射一对多关联关系
hibernate(多对多关系映射)实现存储,内附sql脚本和详细的注释,适合初学者
Hibernate关于注解的一对多,多对多,一对一案例。。。。
hibernate多对多的关系实例hibernate多对多的关系实例hibernate多对多的关系实例
hibernate一对一外键关系,很适合入门者学习.
Hibernate多对多关联关系demo
hibernate多对多关系映射案例,配有对应的jar包。
Hibernate 多对一 一对多 操作实例
hibernate实现多对多关联关系源码
后面的hibernate代码,我会慢慢的上传上去,这些资源都是免费的,希望可以帮到大家。
免积分的资源,希望可以帮到大家,这是我学习hibernate时候,自己写的代码。希望大家学业有成。
加入了hibernate框架的javaWeb项目,里面包含了一对多的典型配置
hibernate one to one一对一关系示例,包括数据库备份文件。
Hibernate多对多关系
hibernate 一对多和多对一的理解 自己的个人看法 大家也来看看
hibernate 映射关系学习入门 多对多实体映射 源码