Hibernate Union 대안
최대 절전 모드를 사용하여 통합 쿼리를 구현하려면 어떤 대안이 필요합니까? 나는 최대 절전 모드가 현재 통합 쿼리를 지원하지 않는다는 것을 알고 있습니다. 지금 당장은 통합을 만드는 유일한 방법은 뷰 테이블을 사용하는 것입니다.
다른 옵션은 일반 jdbc를 사용하는 것이지만이 방법을 사용하면 테이블 / 열에 대해 최대 절전 모드가 수행하는 최대 절전 모드 매핑 유효성 검사뿐만 아니라 모든 예제 / 기준 쿼리 기능을 잃게됩니다.
VIEW를 사용하십시오. 엔티티 이름을 사용하여 동일한 클래스를 다른 테이블 / 뷰에 매핑 할 수 있으므로 중복이 많지 않습니다. 거기에 있으면 잘 작동합니다.
Plain JDBC에는 또 다른 숨겨진 문제가 있습니다. Hibernate 세션 캐시를 인식하지 못하므로 트랜잭션이 끝날 때까지 캐시되고 Hibernate 세션에서 플러시되지 않은 경우 JDBC 쿼리에서 찾을 수 없습니다. 때때로 매우 혼란 스러울 수 있습니다.
당신은 사용할 수 있습니다 id in (select id from ...) or id in (select id from ...)
예 : 작동하지 않는 대신
from Person p where p.name="Joe"
union
from Person p join p.children c where c.name="Joe"
당신은 할 수 있습니다
from Person p
where p.id in (select p1.id from Person p1 where p1.name="Joe")
or p.id in (select p2.id from Person p2 join p2.children c where c.name="Joe");
적어도 MySQL을 사용하면 나중에 성능 문제가 발생합니다. 때로는 두 쿼리에 대해 가난한 사람의 조인을 수행하는 것이 더 쉽습니다.
// use set for uniqueness
Set<Person> people = new HashSet<Person>((List<Person>) query1.list());
people.addAll((List<Person>) query2.list());
return new ArrayList<Person>(people);
복잡한 쿼리 하나보다 간단한 쿼리 두 개를 수행하는 것이 더 낫습니다.
편집하다:
예를 들어, 다음은 subselect 솔루션의 결과 MySQL 쿼리의 EXPLAIN 출력입니다.
mysql> explain
select p.* from PERSON p
where p.id in (select p1.id from PERSON p1 where p1.name = "Joe")
or p.id in (select p2.id from PERSON p2
join CHILDREN c on p2.id = c.parent where c.name="Joe") \G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: a
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 247554
Extra: Using where
*************************** 2. row ***************************
id: 3
select_type: DEPENDENT SUBQUERY
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Impossible WHERE noticed after reading const tables
*************************** 3. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: a1
type: unique_subquery
possible_keys: PRIMARY,name,sortname
key: PRIMARY
key_len: 4
ref: func
rows: 1
Extra: Using where
3 rows in set (0.00 sec)
가장 중요한 것은 1. 행은 인덱스를 사용하지 않고 20 만 개 이상의 행을 고려한다는 것입니다. 나쁜! 이 쿼리를 실행하는 데 0.7 초가 걸렸으며 두 하위 쿼리가 모두 밀리 초 단위입니다.
나는 블라디미르에 동의해야합니다. 나도 HQL에서 UNION을 사용하는 방법을 살펴 보았지만 그 방법을 찾지 못했습니다. 이상한 점은 UNION이 지원되지 않는다는 것을 (Hibernate FAQ에서) 찾을 수 있다는 것, UNION과 관련된 버그 보고서가 '수정 됨'으로 표시, UNION에서 문장이 잘릴 것이라고 말하는 사람들의 뉴스 그룹 및 작동한다고보고하는 사람들의 다른 뉴스 그룹 괜찮아요 ... 하루를 보낸 후 HQL을 일반 SQL로 다시 이식했지만 데이터베이스의보기에서 수행하는 것이 좋은 옵션이 될 것입니다. 필자의 경우 쿼리의 일부가 동적으로 생성되었으므로 대신 코드에서 SQL을 빌드해야했습니다.
나는 HQL의 결합과 함께 (내가 많이 고생 한) 하나의 중요한 시나리오에 대한 해결책을 가지고 있습니다.
예 : 작동하지 않는 대신 :-
select i , j from A a , (select i , j from B union select i , j from C) d where a.i = d.i
또는
select i , j from A a JOIN (select i , j from B union select i , j from C) d on a.i = d.i
Hibernate HQL에서 할 수 있습니다->
Query q1 =session.createQuery(select i , j from A a JOIN B b on a.i = b.i)
List l1 = q1.list();
Query q2 = session.createQuery(select i , j from A a JOIN C b on a.i = b.i)
List l2 = q2.list();
그런 다음 두 목록을 모두 추가 할 수 있습니다->
l1.addAll(l2);
A view is a better approach but since hql typically returns a List or Set... you can do list_1.addAll(list_2). Totally sucks compared to a union but should work.
Perhaps I had a more straight-forward problem to solve. My 'for instance' was in JPA with Hibernate as the JPA provider.
I split the three selects (two in a second case) into multiple select and combined the collections returned myself, effectively replacing a 'union all'.
I too have been through this pain - if the query is dynamically generated (e.g. Hibernate Criteria) then I couldn't find a practical way to do it.
The good news for me was that I was only investigating union to solve a performance problem when using an 'or' in an Oracle database.
The solution Patrick posted (combining the results programmatically using a set) while ugly (especially since I wanted to do results paging as well) was adequate for me.
As Patrick said, appending the LISTs from each SELECT would be a good idea but remember that it acts like UNION ALL. To avoid this side effect, just control if the object is already added in final collection or not. If no, then add it.
Something else that you should care about is that if you have any JOIN in each SELECT, the result would be a list of object array(List<Objetc[]>
) so you have to iterate over it to only keep the object that you need.
Hope it works.
Here is a special case, but might inspire you to create your own work around. The goal here is to count the total number of records from two different tables where records meet a particular criteria. I believe this technique will work for any case where you need to aggregate data from across multiple tables/sources.
I have some special intermediate classes setup, so the code which calls the named query is short and sweet, but you can use whatever method you normally use in conjunction with named queries to execute your query.
QueryParms parms=new QueryParms();
parms.put("PROCDATE",PROCDATE);
Long pixelAll = ((SourceCount)Fetch.row("PIXEL_ALL",parms,logger)).getCOUNT();
As you can see here, the named query begins to look an aweful lot like a union statement:
@Entity
@NamedQueries({
@NamedQuery(
name ="PIXEL_ALL",
query = "" +
" SELECT new SourceCount(" +
" (select count(a) from PIXEL_LOG_CURR1 a " +
" where to_char(a.TIMESTAMP, 'YYYYMMDD') = :PROCDATE " +
" )," +
" (select count(b) from PIXEL_LOG_CURR2 b" +
" where to_char(b.TIMESTAMP, 'YYYYMMDD') = :PROCDATE " +
" )" +
") from Dual1" +
""
)
})
public class SourceCount {
@Id
private Long COUNT;
public SourceCount(Long COUNT1, Long COUNT2) {
this.COUNT = COUNT1+COUNT2;
}
public Long getCOUNT() {
return COUNT;
}
public void setCOUNT(Long COUNT) {
this.COUNT = COUNT;
}
}
Part of the magic here is to create a dummy table and insert one record into it. In my case, I named it dual1 because my database is Oracle, but I don't think it matters what you call the dummy table.
@Entity
@Table(name="DUAL1")
public class Dual1 {
@Id
Long ID;
}
Don't forget to insert your dummy record:
SQL> insert into dual1 values (1);
ReferenceURL : https://stackoverflow.com/questions/201023/hibernate-union-alternatives
'UFO ET IT' 카테고리의 다른 글
.NET Core는 Windows 1252에 대해 알지 못합니다. 어떻게 해결합니까? (0) | 2021.01.11 |
---|---|
pip는 TLS / SSL이 필요한 위치로 구성되지만 Python의 SSL 모듈을 사용할 수 없습니다. (0) | 2021.01.11 |
JSON 파일 (POST, GET 포함)을 제공하기 위해 IIS6를 가져 오시겠습니까? (0) | 2021.01.11 |
jQuery Dialog 및 Datepicker 플러그인 문제 (0) | 2021.01.11 |
jQuery 선택기 값 이스케이프 (0) | 2021.01.11 |