作者cyclone350 (老子我最神)
看板java
标题[问题] hibernate 新手问题
时间Wed Jan 9 00:08:40 2013
最近利用空档在练习 hibernate (进度缓慢)
因为这问题想了很久,在网路上也不知道关键字是甚麽,看了一些 document 也没头绪
所以就上来请教各位前辈
我使用的是 spring + hibernate
首先 hibernate 是一个 ORM framework。
如果我们要 select,利用他提供的 libery 就可以直接存取。
要查询物件也很简单,例如:
String hql = "from people";
List<people> peoplesss = this.getSessionTemplete().creatQuery(hql).list();
就可以得到这些Entity,相反的 insert 跟 delete 也类似
问题来啦,假设这是美食猎人世界的系统资料库,如果只是用 from people,
则这个 List 的 size 可能好几百亿,这下不得了。
不过 hibernate 可以设定 pageSize 跟 pageNum 之类的东西,可以设定一次只拿到 n 笔
问题是 spring 提供的 hibernateTemplete 并没有这个功能‧‧‧
好家在 google 大神跟我说 hibernateTemplete 有一个 callbackHibernate 方法,
所以此问题就解决了。
接下来要设定关联资料库
假设美食世界的人有三种,美食猎人,厨师,一般人,
我们可以增加一个 Table 名为 FOOD_TAG。
并且在 PEOPLE 的 table 增加一个 FK 名为 TAG,对应到 FOOD_TAG 的 PK,
所以我们在 PEOPLE 的 Entity 要设定一个 @ManyToOne 对应到 FOOD_TAG
而 FOOD_TAG 的 Entity 要设定一个 @OneToMany 对应到 PEOPLE。
这样想要知道属於美食猎人Tag的人有哪些,只需要从 FOOD_TAG 的 Entity 拿到 people
的 list 就好了。
问题来了,如果我只需要拿到 Tag 的名称,例如:
Tag tag = getHibernateTemplete().
createQuery("from tag t where t.name = '一般人'");
String tagName = tag.getName();
那这样还需要抓取 people List 吗?
还好可以设定 fetch lazy 来解决这问题,我可以等到要 getPeopleList 时才 query
(不过 session 不能关啦,或是要设定其他的)
不过又有问题了,假设我要 getPeopleList,他会一次给我全部的人,
假设分类在 "一般人" 的 People 有 60 亿人,那我的 memory 岂不就爆掉了。
於是我翻书,请 google 搜寻此类问题,皆找不到 OneToMany 的限制用法
我想要 OneToMany 可以想一般平常的 query 可以设定 maxSize 或是 page 的概念
不过 google 似乎也没找到 ...
另外本来想用 FK 当 where 条件当 query,然後就用一开始的方法。
可是在 entity 的 FK 是隐藏的 (joinColumn)。
想请问有没有此类方法可以解? Annotation 要怎麽设定才会有这样的效果
看过很多网站都没讲这问题
有看到一个网页有用 @Size(max=30) 这样,但是我的专案根本没有 @Size
另外还有一个问题,我还没自己试过,请问 Entity 的 @oneToMany 之类的会有
连锁效应吗?
例如 A -> B -> C -> D <- A
A 对 B , 一对多
B 对 C , 一对多
C 对 D , 一对多
A 对 D , 一对多
假设我都是 fetch eager 的话
会在 query A 的时候,把 B 一起 query。
因为 B -> C,hibernate 会顺便 query C 吗?
然後 C -> D 再 query D ?
假设我要拿到D
就直接 a.getB().get(0).getC().get(0).getD() ?
这样找一个资料,数量级大一点的话,hibernate 不就死掉了吗?
文有点长,看不董跟我说我再解释一下,文笔有点不顺。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.198.167.187
1F:推 LaPass:翻过hibernate,但也没实务经验,我也想问这些问题.... 01/09 00:21
2F:推 joetsai:ORM的Paging应该都是用Memory 这样不会爆掉吗!? 01/09 00:25
3F:推 phstudy:@LazyCollection(LazyCollectionOption.EXTRA) 01/09 01:34
4F:→ phstudy:JPA2据我所知应没有,但可用JPQL或Criteria自己写 01/09 01:37
5F:推 phstudy:fetch eager理论上会全载入,你可以设定show_sql验证 01/09 01:40
6F:推 swpoker:怎麽会想要一次拿到全部的资料呢? 01/09 09:41
7F:→ cyclone350:就是希望不要一次拿全部的资料,但是在 hibernate 01/09 09:53
8F:→ cyclone350:OneToMany 找不到限制资料量的方法或设定 01/09 09:54
9F:推 swpoker:HIBERNATE想要跨资料库平台~可惜每家厂商都不太一样 01/09 10:38
10F:→ swpoker:自己下SQL或许会好点~也要小心DB的负荷~AP跟DB都要注意 01/09 10:41
11F:推 LaPass:我有另外一个问题想问..... 万一有使用丛集,多个伺服器使 01/09 10:45
12F:→ LaPass:用同个资料库,会有问题吗? (hibernate好像会先存在记忆?) 01/09 10:47
13F:→ swpoker:HIBERNET有内坎在DB里面吗?(误) ~ 还是要看DB拉 XD 01/09 11:47
14F:→ cyclone350:结论是在 Hibernate 内无解吗? 我知道可以用 JPQL 或是 01/09 18:04
15F:→ cyclone350:PL/SQL 或 Criteria,不过感觉是在避开问题,这样 01/09 18:12
16F:→ cyclone350:@OneToMany 不就形同虚设了吗? 01/09 18:14
17F:推 Curapikt:fetch eager是最下策,hibernate有个design pattern叫 01/10 01:09
18F:推 Curapikt:openSessionInView ;OneToMany的意义也不是让你只抓少 01/10 01:12
19F:推 Curapikt:数几个Entity,你看文件时他都会写说那些方法不建议使用 01/10 01:14
20F:推 Curapikt:你要抓少数用查询做就好啦... 01/10 01:17
21F:→ swpoker:其实我觉得你想的太过发散了~不过这个是好事~ 01/10 11:38
22F:→ swpoker:建议你写出一下整个流程~重新整理思绪~会很有帮助的 01/10 11:40