文档章节

如何抓取平行集合

猪刚烈
 猪刚烈
发布于 2014/10/12 11:47
字数 1148
阅读 11
收藏 0
点赞 0
评论 0

join抓取两个以上的平行集合会产生笛卡尔积,而如果使用subselect抓取又会失去动态抓取集合其他依赖对象的机会。要怎样才能动态地抓取平行集合呢?目前我能想到的一种方法就是生成多条select,分别抓取平行集合。我觉得这并不是一个很完美的方案,但是它却实是可行的。

以Forum为例,在某个use case中我们需要加载一个Forum,同时要显示它的所有Thread以及Moderator.Forum的类代码为:

@Entity
@Table
public class Forum implements ForumNode,Serializable{
    @ManyToMany
    private Set<User> moderators;
	
    @OneToMany
    private List<Thread> threads = new ArrayList<Thread>();
}
 

根据ID加载一个Forum,并将这两个集合抓取出来的方法是:

public Forum getForumWithModeratorsAndThreads(final long forumId){
		return (Forum) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {			
			public Object doInHibernate(Session session) throws HibernateException,	SQLException {
				//Get forum.
				String getForuumHql= "from Forum as forum where forum.id=:forumId";
				Forum forum = (Forum) session.createQuery(getForuumHql).setParameter("forumId", forumId).uniqueResult();
				//Fetch threads.
				String fetchForumThreadsHql = "from Forum as forum left join fetch forum.threads as thread left join fetch thread.subject where forum=:forum";
				session.createQuery(fetchForumThreadsHql).setParameter("forum", forum).list();
				//Fetch moderators.
				String fetchForumMorderatorsHql = "from Forum as forum left join fetch forum.moderators as moderator left join fetch moderator.roles where forum=:forum";
				session.createQuery(fetchForumMorderatorsHql).setParameter("forum", forum).list();
				logger.info("The Forum (ID="+forumId+") has loaded with moderators and threads");
				return forum;
			}
		});
	}
 

这段代码做了三个操作,生成三条SQL.第一个操作是加载一个不带任何关联对象的Forum。第二个操作是抓取这个Forum的Thread集合。第三个操作是抓取这个Forum的Moderator集合。

下面是测试代码:

@Test @Transactional
	public void testgetForumWithModeratorsAndThreads(){
		Forum forum = forumRepository.getForumWithModeratorsAndThreads(1L);
		System.out.println("****************************************************");
		System.out.println(forum.getModerators().size());
		System.out.println(forum.getThreads().size());
	}

 

测试的输出结果是:

Hibernate:
    /*
from
    Forum as forum
where
    forum.id=:forumId */ select
        forum0_.id as id2_,
        forum0_.creationTime as creation2_2_,
        forum0_.description as descript3_2_,
        forum0_.groupId as groupId2_,
        forum0_.modifiedTime as modified4_2_,
        forum0_.name as name2_
    from
        Forum forum0_
    where
        forum0_.id=?
Hibernate:
    /*
from
    Forum as forum
left join
    fetch forum.threads as thread
left join
    fetch thread.subject
where
    forum=:forum */ select
        forum0_.id as id2_0_,
        threads1_.id as id5_1_,
        post2_.id as id4_2_,
        forum0_.creationTime as creation2_2_0_,
        forum0_.description as descript3_2_0_,
        forum0_.groupId as groupId2_0_,
        forum0_.modifiedTime as modified4_2_0_,
        forum0_.name as name2_0_,
        threads1_.creationTime as creation2_5_1_,
        threads1_.forumId as forumId5_1_,
        threads1_.modifiedTime as modified3_5_1_,
        threads1_1_.subjectId as subjectId6_1_,
        threads1_.forumId as forumId0__,
        threads1_.id as id0__,
        post2_.authorId as authorId4_2_,
        post2_.creationTime as creation2_4_2_,
        post2_.isSubject as isSubject4_2_,
        post2_.messageBody as messageB4_4_2_,
        post2_.modifiedTime as modified5_4_2_,
        post2_.quotedPostId as quotedPo8_4_2_,
        post2_.threadId as threadId4_2_,
        post2_.title as title4_2_
    from
        Forum forum0_
    left outer join
        Thread threads1_
            on forum0_.id=threads1_.forumId
    left outer join
        Thread_Subject threads1_1_
            on threads1_.id=threads1_1_.threadId
    left outer join
        Post post2_
            on threads1_1_.subjectId=post2_.id
    where
        forum0_.id=?
Hibernate:
    /*
from
    Forum as forum
left join
    fetch forum.moderators as moderator
left join
    fetch moderator.roles
where
    forum=:forum */ select
        forum0_.id as id2_0_,
        user2_.id as id0_1_,
        role4_.id as id1_2_,
        forum0_.creationTime as creation2_2_0_,
        forum0_.description as descript3_2_0_,
        forum0_.groupId as groupId2_0_,
        forum0_.modifiedTime as modified4_2_0_,
        forum0_.name as name2_0_,
        user2_.accountNonExpired as accountN2_0_1_,
        user2_.accountNonLocked as accountN3_0_1_,
        user2_.credentialsNonExpired as credenti4_0_1_,
        user2_.email as email0_1_,
        user2_.enabled as enabled0_1_,
        user2_.password as password0_1_,
        user2_.username as username0_1_,
        user2_.version as version0_1_,
        moderators1_.forumId as forumId0__,
        moderators1_.moderatorId as moderato2_0__,
        role4_.description as descript2_1_2_,
        role4_.name as name1_2_,
        roles3_.userId as userId1__,
        roles3_.roleId as roleId1__
    from
        Forum forum0_
    left outer join
        Forum_Moderator moderators1_
            on forum0_.id=moderators1_.forumId
    left outer join
        User user2_
            on moderators1_.moderatorId=user2_.id
    left outer join
        User_Role roles3_
            on user2_.id=roles3_.userId
    left outer join
        Role role4_
            on roles3_.roleId=role4_.id
    where
        forum0_.id=?
INFO - ForumHibernateRepository$1.doInHibernate(38) | The Forum (ID=1) has loaded with moderators and threads
****************************************************
1
2

 

从运行结果来看,getForumWithModeratorsAndThreads方法返回的Forum是一个已经将moderator和thread抓取出来的Forum实例。当我们在测试代码中访问这两个集合时,并没有任何sql打出,说明它们都已经被抓取出来了。

 

我觉得这个方案不好的地方在于抓取两个平行集合的hql有些怪异,它们select的是Forum,但实际上我们并不是要这个Forum,而是要抓取它的集合。因此执行些hql后,我们也没有要得到查询结果的意思。另外,每次查询都要从Forum开始进行join也觉得多做一些事情。 通过验证我发现, 如果直接select这个forum的thread和moderator集合,再访问这个forum的这两个集合时,它还是要去查DB,这说明, 直接select它们不会导致forum的 thread和 moderator集合(应该是hibernate的colletcion wapper)被加载。我想原因是因为hibernate无法确认我们通过select查出的这些元素一定是forum的全部thread集合。hibernate必须重新执行一次以确保全部的集合被加载出来。因此目前来说,也只有这种方式还算可行。我想以后可能会找到更好的解决方法吧。

本文转载自:http://blog.csdn.net/bluishglc/article/details/5581546

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
快速构建实时抓取集群

本文转载自搜淘宝索技术博客,描述了实时抓取集群的架构。其架构中使用Redis作为核心的LinkBase存储,包括了使用List结构来存储抓取队列,使用Hash结构来存储链接表及使用Sorted Sets结构来存...

红薯 ⋅ 2011/07/31 ⋅ 0

从零开始打造一个新闻订阅APP之爬虫篇(一、背景介绍&需求分析)

我开发的就是一个类似于Zaker和鲜果等新闻订阅服务的APP;接下来的一个系列,我都将是围绕这一个主题,按照一定的逻辑,介绍如何一步步地开发出一个新闻订阅APP。 首先,将会是第一部分:爬虫...

会飞柚子 ⋅ 2015/11/20 ⋅ 0

hibernate fetch属性

Hibernate的fetch="join"和fetch="select" 的一点分析 fetch参数指定了关联对象抓取的方式是select查询还是join查询,select方式时先查询返回要查询的主体对象(列表),再根据关联外键id,每...

zdatbit ⋅ 2016/07/18 ⋅ 0

Hibernate性能优化1( 转)

有很多人认为Hibernate天生效率比较低,确实,在普遍情况下,需要将执行转换为SQL语句的 Hibernate的效率低于直接JDBC存取,然而,在经过比较好的性能优化之后,Hibernate的性能还是让人相当...

九爷 ⋅ 2011/05/14 ⋅ 0

Hibernate提升性能

导读:   20.1. 抓取策略(Fetching strategies)   抓取策略(fetching strategy)是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对...

wsl_Mr ⋅ 2013/07/24 ⋅ 1

Hibernate抓取策略

6、抓取策略:抓取策略主要是指获取连接对象的策略。 6.1、基于XML的抓取 1.1、基于XML抓取many-to-one 1.2、设置fetch="join" 存在问题:延迟加载失效 1.3、但是fetch="join"无法抓取HQL中的...

pmos ⋅ 2016/10/22 ⋅ 0

[Hibernate]一对多和多对一中各个参数的说明

many-to-one节点有以下属性(摘自Hibernate文档): 序号 属性 说明 1 name 属性名 2 column (可选): 外间字段名。它也可以通过嵌套的 <column> 元素指定。 3 class (可选 - 默认是通过反射得...

彪大大 ⋅ 2016/01/22 ⋅ 0

Hibernate中的抓取策略

抓取策略是指我们需要在关联对象间进行导航的时候,Hibernate如何获取关联对象的策略。 select抓取策略:当我们查询某个对象时,hibernate会另外发出一条select语句查询与之关联的实体或者集...

叶欢欢 ⋅ 2016/11/12 ⋅ 0

Beautiful Soup库入门

Beautiful Soup简介与安装 简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下: Beautiful Soup提供一些简单的python式的函数用来处理导航、搜索...

zengxiantao1994 ⋅ 2017/10/16 ⋅ 0

网络爬虫的抓取策略:深度抓取策略、广度优先遍历策略、Partial PageRank策略、OCIP策略、大站优先策略

前言 遍历策略是爬虫的核心问题,在爬虫系统中,待抓取URL队列是很重要的一部分。待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面...

扶七 ⋅ 05/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Nginx服务架构初探(四):nginx服务器的rewrite功能

nginx服务器的rewrite功能 1.nginx后端服务器组的配置 1>upstream name {…} name是给服务器组限的组名 2>server address [parameters]; address为服务器地址 parame......

余温灬未存 ⋅ 今天 ⋅ 0

layer.prompt使文本框为空的情况下也能点击确定

最近一直在使用layui,但是用到弹出层layer.prompt时,如果文本框是空的话点击确定没有反应,不能向下执行。 但是我又需要空值,看看我原来的代码。 123456789 layer.prompt...

孟飞阳 ⋅ 今天 ⋅ 0

Linux普通文件压缩工具gzip、Bzip2、xz

第六章 文件压缩和打包 6.1 压缩打包介绍 Linux环境常见压缩文件类型: .zip,.gz,.bz2,.xz, .tar.gz,.tar.bz2,.tar.xz 压缩打包的目的 方便文件传输 节省磁盘空间 减少传输花费的时间 ...

弓正 ⋅ 今天 ⋅ 0

移动弹窗基础知识浅析——IOS弹窗体系

摘要: 最为常见的【弹窗】反而是最“捉摸不定”的东西。各种类型的弹窗傻傻分不清楚,不知道在什么场景下应该用哪种弹窗。尤其是遇到“二次确认”等场景…… 因此,打算从头整理移动弹窗的基...

阿里云云栖社区 ⋅ 今天 ⋅ 0

zabbix短信报警统计以及报表展示

一、需求 由于我们的业务报警比较频繁,之前是针对每个报警进行具体处理,但是有时还会重复出现,或者后续处理有时忘记跟进等,因此进行报警短信的统计,可以针对一些问题与业务跟进,明确后...

o翡翠谷o ⋅ 今天 ⋅ 0

JNI 输出LOG

1、导入log头文件。在你使用的 .c/ .cpp 文件中,导入 log.h 头文件。 #include<android/log.h> 2、在android.mk 加上 LOCAL_LDLIBS := -llog 或 LOCAL_SHARED_LIBRARIES := liblog 3、定义L......

国仔饼 ⋅ 今天 ⋅ 0

主线程pthread_exit 作用

#include <iostream>#include <pthread.h>#include <unistd.h>using namespace std;#define NUM_THREADS 10void* say_hello(void* args){ int i = *((int*)args);/......

xxdd ⋅ 今天 ⋅ 0

崛起于Springboot2.X之Mybatis-xml方式操作mysql数据库(3)

序言:当第一篇讲道Mybatis的时候,只要使用过mybatis的java程序员100%都会知道这种方式,因为这是最广泛最全面的编写sql操作mysql数据库的方式,高级sql的编写往往通过xml方式,接下来进入正...

木九天 ⋅ 今天 ⋅ 1

移动弹窗基础知识浅析——IOS弹窗体系

摘要: 最为常见的【弹窗】反而是最“捉摸不定”的东西。各种类型的弹窗傻傻分不清楚,不知道在什么场景下应该用哪种弹窗。尤其是遇到“二次确认”等场景…… 因此,打算从头整理移动弹窗的基...

猫耳m ⋅ 今天 ⋅ 0

spring elasticsearch 2.4 date 日期

1.mappingPUT user_behavior { "mappings": { "user_behavior": { "properties": { "date": { "type": "createDate", ......

xiaomin0322 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部