欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hibernate中的Fetch(数据抓取)

程序员文章站 2022-04-25 22:12:47
...

Hibernate抓取策略(fetch)


一、单端关联上的fetch[取值:select(默认)/join]


测试用例:
TBook b = (TBook)session.get(TBook.class,1);

System.out.println("图书名称:"+b.getBName());

System.out.println("图书类别:"+b.getCategory().getCategory());
1)保持默认,相当于fetch="select"
如:<many-to-one name="category" class="cn.bdqn.pojo.Category" cascade="all" fetch="select">
数据抓取过程中,select抓取会另外发送一条select语句来抓取与当前对象相关联的实体或集合。
执行结果:2条语句
Hibernate: select tbook0_.id as id1_1_0_, tbook0_.category_Id as category2_1_0_, tbook0_.author as author3_1_0_, tbook0_.b_name as b_name4_1_0_, tbook0_.b_price as b_price5_1_0_, tbook0_.pubDate as pubDate6_1_0_ from admindb.t_book tbook0_ where tbook0_.id=?
图书名称:红楼梦
Hibernate: select category0_.id as id1_0_0_, category0_.category as category2_0_0_ from admindb.category category0_ where category0_.id=?
图书类别:文学
2)设置fetch="join"
如:<many-to-one name="category" class="cn.bdqn.pojo.Category" cascade="all"fetch="join">
数据抓取过程中,join抓取会通过select语句使用外连接来加载其关联实体或集合。
执行结果:1条语句
Hibernate: 
    select
        tbook0_.id as id1_1_0_,
        tbook0_.category_Id as category2_1_0_,
        tbook0_.author as author3_1_0_,
        tbook0_.b_name as b_name4_1_0_,
        tbook0_.b_price as b_price5_1_0_,
        tbook0_.pubDate as pubDate6_1_0_,
        category1_.id as id1_0_1_,
        category1_.category as category2_0_1_ 
    from
        admindb.t_book tbook0_ 
    left outer join
        admindb.category category1_ 
            on tbook0_.category_Id=category1_.id 
    where
        tbook0_.id=?
图书名称:红楼梦
图书类别:文学
我们发现此时懒加载已经失效。

二、集合端的fetch[取值:select(默认)/join/subselect]


测试用例:
@Test
public void test() {
	Session session = null;
	try {
		session = SessionUtil.getSession();
		
		Category c = (Category)session.load(Category.class,1);
		
		System.out.println("图书类别:"+c.getCategory());
		
		Set<TBook> tBooks = c.getTBooks();
		System.out.println(tBooks.size());
		Iterator<TBook> it = tBooks.iterator();
		while(it.hasNext()){
			System.out.println(it.next().getBName());
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		SessionUtil.close(session);
	}
}
1)保持默认,相当于fetch="select"
如:<set name="TBooks" inverse="true" fetch="select">
数据抓取过程中,select抓取会另外发送一条select语句来抓取与当前对象相关联的实体或集合。
执行结果:2条语句
Hibernate: 
    select
        category0_.id as id1_0_0_,
        category0_.category as category2_0_0_ 
    from
        admindb.category category0_ 
    where
        category0_.id=?
图书类别:文学
Hibernate: 
    select
        tbooks0_.category_Id as category2_0_0_,
        tbooks0_.id as id1_1_0_,
        tbooks0_.id as id1_1_1_,
        tbooks0_.category_Id as category2_1_1_,
        tbooks0_.author as author3_1_1_,
        tbooks0_.b_name as b_name4_1_1_,
        tbooks0_.b_price as b_price5_1_1_,
        tbooks0_.pubDate as pubDate6_1_1_ 
    from
        admindb.t_book tbooks0_ 
    where
        tbooks0_.category_Id=?
2
西游记
红楼梦
2)设置fetch="join"
如:<set name="TBooks" inverse="true" fetch="join">
数据抓取过程中,join抓取会通过select语句使用外连接来加载其关联实体或集合。
执行结果:1条语句
Hibernate: 
    select
        category0_.id as id1_0_0_,
        category0_.category as category2_0_0_,
        tbooks1_.category_Id as category2_0_1_,
        tbooks1_.id as id1_1_1_,
        tbooks1_.id as id1_1_2_,
        tbooks1_.category_Id as category2_1_2_,
        tbooks1_.author as author3_1_2_,
        tbooks1_.b_name as b_name4_1_2_,
        tbooks1_.b_price as b_price5_1_2_,
        tbooks1_.pubDate as pubDate6_1_2_ 
    from
        admindb.category category0_ 
    left outer join
        admindb.t_book tbooks1_ 
            on category0_.id=tbooks1_.category_Id 
    where
        category0_.id=?
图书类别:文学
2
西游记
红楼梦
3)设置fetch="subselect"
如:<set name="TBooks" inverse="true" fetch="subselect">
使用subselect进行数据抓取过程中, 抓取数据相关联的集合数据时会一次性完成数据的抓取,也就是说会另外发送一条select语句抓取在前面查询到的所有实体对象的关联集。
测试用例:
@Test
public void testSubSelect() {
	Session session = null;
	Transaction tran = null;
	try {
		session = SessionUtil.getSession();
		tran = session.beginTransaction();
		List<Category> list = session.createQuery("from Category where id in (1,2,3)").list();
		for (Category c : list) {
			System.out.println("图书类别:" + c.getCategory());
			System.out.println("图书数量:" + c.getTBooks().size());
		}

		tran.commit();
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		SessionUtil.close(session);
	}
}
当不设置fetch="subselect"时,也就是默认,或者设置成select。
结果如下:会产生额外的三条sql
Hibernate: 
    select
        category0_.id as id1_0_,
        category0_.category as category2_0_ 
    from
        admindb.category category0_ 
    where
        category0_.id in (
            1 , 2 , 3
        )
图书类别:文学
Hibernate: 
    select
        tbooks0_.category_Id as category2_0_0_,
        tbooks0_.id as id1_1_0_,
        tbooks0_.id as id1_1_1_,
        tbooks0_.category_Id as category2_1_1_,
        tbooks0_.author as author3_1_1_,
        tbooks0_.b_name as b_name4_1_1_,
        tbooks0_.b_price as b_price5_1_1_,
        tbooks0_.pubDate as pubDate6_1_1_ 
    from
        admindb.t_book tbooks0_ 
    where
        tbooks0_.category_Id=?
图书数量:2
图书类别:历史
Hibernate: 
    select
        tbooks0_.category_Id as category2_0_0_,
        tbooks0_.id as id1_1_0_,
        tbooks0_.id as id1_1_1_,
        tbooks0_.category_Id as category2_1_1_,
        tbooks0_.author as author3_1_1_,
        tbooks0_.b_name as b_name4_1_1_,
        tbooks0_.b_price as b_price5_1_1_,
        tbooks0_.pubDate as pubDate6_1_1_ 
    from
        admindb.t_book tbooks0_ 
    where
        tbooks0_.category_Id=?
图书数量:1
图书类别:武侠
Hibernate: 
    select
        tbooks0_.category_Id as category2_0_0_,
        tbooks0_.id as id1_1_0_,
        tbooks0_.id as id1_1_1_,
        tbooks0_.category_Id as category2_1_1_,
        tbooks0_.author as author3_1_1_,
        tbooks0_.b_name as b_name4_1_1_,
        tbooks0_.b_price as b_price5_1_1_,
        tbooks0_.pubDate as pubDate6_1_1_ 
    from
        admindb.t_book tbooks0_ 
    where
        tbooks0_.category_Id=?
图书数量:1
当设置成fetch="subselect",即:<set name="TBooks" inverse="true" fetch="subselect">时:
结果如下:只会额外产生一条sql(一条包含子查询的sql)
Hibernate: 
    select
        category0_.id as id1_0_,
        category0_.category as category2_0_ 
    from
        admindb.category category0_ 
    where
        category0_.id in (
            1 , 2 , 3
        )
图书类别:文学
Hibernate: 
    select
        tbooks0_.category_Id as category2_0_1_,
        tbooks0_.id as id1_1_1_,
        tbooks0_.id as id1_1_0_,
        tbooks0_.category_Id as category2_1_0_,
        tbooks0_.author as author3_1_0_,
        tbooks0_.b_name as b_name4_1_0_,
        tbooks0_.b_price as b_price5_1_0_,
        tbooks0_.pubDate as pubDate6_1_0_ 
    from
        admindb.t_book tbooks0_ 
    where
        tbooks0_.category_Id in (
            select
                category0_.id 
            from
                admindb.category category0_ 
            where
                category0_.id in (
                    1 , 2 , 3
                )
        )
图书数量:2
图书类别:历史
图书数量:1
图书类别:武侠
图书数量:1