JPA 및 최대 절전 모드 - 기준 대 JPQL 또는 HQL
기준 또는 HQL을 사용할 때의 장단점은 무엇인가?기준 API는 최대 절전 모드에서 쿼리를 표현할 수 있는 개체 지향적인 방법이지만, 때때로 기준 쿼리는 HQL보다 이해/구축하기가 더 어렵다.
기준 및 HQL을 언제 사용하십니까?사용 사례 중 어떤 것을 선호하십니까?아니면 그저 취향의 문제일까?
동적 쿼리는 대부분 기준 쿼리를 선호한다.예를 들어 일부 주문을 동적으로 추가하거나 일부 부품(예: 제한)을 일부 파라미터에 따라 제외하는 것이 훨씬 쉽다.
반면에 나는 정적 질의와 복잡한 질의에 HQL을 사용하고 있는데, HQL을 이해/읽기가 훨씬 쉽기 때문이다.또한, HQL은 예를 들어 다른 조인 유형에 대해 좀 더 강력하다고 생각한다.
HQL과 기준Query의 성능 차이가 있으며, 기준Query를 사용하여 쿼리를 실행할 때마다 DB에 대한 마지막 쿼리 캐시에 반영되지 않는 테이블 이름에 대한 새 별칭을 생성한다.이로 인해 생성된 SQL을 컴파일하는 오버헤드가 발생하여 실행 시간이 더 소요된다.
가져오기 전략 관련 [http://www.hibernate.org/315.html]
- 기준은 매핑의 게으름 설정을 존중하며 로드할 항목이 로드되도록 보장한다.즉, 하나의 기준 쿼리로 인해 매핑되지 않은 모든 연결 및 컬렉션과 함께 하위 그래프를 가져오는 몇 개의 SQL 즉시 선택 문이 발생할 수 있다.방법 및 "무엇"을 변경하려면 setFetchMode()를 사용하여 특정 컬렉션 또는 연결에 대해 외부 조인 가져오기를 사용하거나 사용하지 않도록 설정하십시오.기준 쿼리는 또한 가져오기 전략(조인 대 선택 대 하위 선택)을 완전히 존중한다.
- HQL은 매핑의 게으름 설정을 존중하며 로드할 항목이 로드되도록 보장한다.즉, 하나의 HQL 쿼리로 인해 매핑되지 않은 모든 연결 및 컬렉션과 함께 하위 그래프를 가져오는 몇 개의 SQL 즉시 선택 문이 발생할 수 있다."방법" 및 "무엇"을 변경하려면 왼쪽 조인 FETCH를 사용하여 특정 컬렉션에 대해 외부 조인 가져오기를 사용하거나 무효인 다대일 또는 일대일 연결에 대해 조인 FETCH를 사용하여 내부 조인 가져오기를 활성화하십시오.HQL 쿼리는 매핑 문서에 정의된 fetch="join"을 고려하지 않는다.
기준은 객체 지향 API인 반면 HQL은 문자열 연결을 의미한다.즉, 객체 지향성의 모든 이점이 다음과 같이 적용된다.
- 다른 모든 것은 동일하지만, OO 버전은 오류가 발생하기 쉽다.유효한 기준 개체만 기준 트리로 만들 수 있는 반면 이전 문자열은 HQL 쿼리에 추가될 수 있다.사실상, 기준 등급은 더 제한적이다.
- 자동 완성을 통해 OO는 더 쉽게 찾을 수 있다(따라서 적어도 내게는 사용하기 쉽다).쿼리의 어느 부분이 어디로 가는지 반드시 기억할 필요는 없다. IDE가 도움이 될 수 있다.
- 구문의 세부 사항도 기억할 필요가 없다(어떤 기호가 어디로 가는지 등).당신이 알아야 할 것은 메소드를 호출하고 객체를 만드는 방법뿐이다.
HQL은 (대부분의 개발자들이 이미 잘 알고 있는) SQL과 매우 비슷하기 때문에, 이러한 "기억할 필요가 없다"는 주장은 그다지 큰 비중을 차지하지 않는다.만약 HQL이 더 다르다면, 이것은 더 많은 수입일 것이다.
어떤 데이터에 어떤 입력을 사용할지 모를 때는 보통 기준을 사용한다.사용자가 1개에서 50개의 항목을 입력할 수 있는 검색 양식처럼 어떤 항목을 검색할지 모르겠다.사용자가 무엇을 검색하는지 확인하는 과정을 거치면서 기준에 더 추가하기 쉽다.그런 상황에서 HQL 질의를 하는 것은 좀 더 귀찮을 것 같아.HQL은 내가 원하는 것을 정확히 알 때 좋다.
HQL은 읽기 훨씬 쉽고, Eclipse Brievenatter 플러그인과 같은 도구를 사용하여 디버깅하기 쉽고, 로그가 더 쉽다.기준 쿼리는 많은 동작이 런타임에 결정되는 동적 쿼리를 구축하는 데 더 효과적이다.SQL을 모르면 Criteria 쿼리를 사용하여 이해할 수 있지만, 전체적으로 내가 원하는 것을 미리 알면 HQL을 선호한다.
기준은 2단계 쿼리 캐시에서 특별한 최적화를 활용하는 자연 키 검색을 지정하는 유일한 방법이다.HQL은 필요한 힌트를 지정할 방법이 없다.
자세한 내용은 다음에서 확인하십시오.
Criteria Api는 겨울잠의 좋은 개념 중 하나이다.내가 보기에 HQL과 Criteria Api를 다르게 할 수 있는 몇 안 되는 지점이다.
- HQL은 데이터에 대해 선택 연산과 선택되지 않은 연산을 모두 수행하는 것이지만, 기준은 데이터 선택만을 위한 것이므로 기준을 사용하여 선택 연산을 수행할 수 없다.
- HQL은 동적 쿼리를 실행하기에 적합하며, 여기서 기준은 동적 쿼리를 실행하기에 적합하다.
- HQL은 페이지 지정 개념을 지원하지 않지만 기준 페이지 지정을 달성할 수 있다.
- HQL보다 실행하는 데 더 많은 시간이 걸리는 데 사용되는 기준.
- Criteria를 사용하면 동적 쿼리 생성으로 인해 SQL Injection이 안전하지만 HQL에서는 쿼리가 고정 또는 파라메트릭화되어 SQL Injection으로부터 안전하지 않음
기준 API
기준 API는 동적으로 생성된 쿼리에 더 적합하다.따라서 WHERE 절 필터, JINE 절을 추가하거나 ORDER BY 절 또는 투영 열을 변경하려는 경우 기준 API를 통해 SQL 주입 공격을 방지하는 방법으로 동적 쿼리를 생성할 수 있다.
반면에 기준 쿼리는 표현력이 떨어지고 심지어 매우 복잡하고 비효율적인 SQL 쿼리로 이어질 수 있다.
JPQL 및 HQL
JPQL은 JPA 표준 엔터티 쿼리 언어인 반면, HQL은 JPQL을 확장하고 일부 최대 절전 모드별 기능을 추가한다.
JPQL과 HQL은 표현력이 뛰어나며 SQL과 닮았다.기준 API와 달리 JPQL과 HQL은 JPA 제공자가 생성하는 기본 SQL 질의를 쉽게 예측할 수 있도록 한다.또한 기준 질의보다 HQL 질의를 검토하는 것이 훨씬 쉽다.
JPQL이나 Criteria API로 엔티티를 선택하는 것은 수정할 필요가 있을 때 이치에 맞는다는 점에 유의할 필요가 있다.그렇지 않다면, DTO 투영이 훨씬 더 나은 선택이다.
결론
도면요소 쿼리 구조를 변경할 필요가 없는 경우 JPQL 또는 HQL을 사용하십시오.필터링 또는 정렬 기준을 변경하거나 투영을 변경해야 하는 경우 기준 API를 사용하십시오.
그러나 JPA나 최대 절전 모드를 사용하고 있다고 해서 네이티브 SQL을 사용하지 말라는 뜻은 아니다.SQL 쿼리는 매우 유용하며 JPQL과 Criteria API는 SQL을 대체하지 않는다.
두 세계의 장점을 모두 사용하려면 HQL의 표현성과 구체성, 그리고 기준의 동적 특성이 Querydsl의 사용을 고려한다.
Querydsl은 JPA/하이버네이트, JDO, SQL 및 컬렉션을 지원한다.
나는 Querydsl의 유지자여서 이 대답은 편파적이다.
나에게 있어 기준이란 상당히 이해하기 쉽고 동적 쿼리를 만드는 것이다.그러나 지금까지 내가 말하는 결함은 우리가 PetchModes의 세 가지 유형(예: Select, Proxy, Default)만 있고 이 모든 경우 다수를 로딩하기 때문에 모든 다-하나 등 관계를 로딩한다는 것이다(만약 그렇다면 내가 잘못한 것일 수도 있다).
기준의 두 번째 문제는 완전한 개체를 로드한다는 것이다. 즉, 직원의 EmpName만 로드하려면 전체 직원 개체를 로드해야 하며, 이 개체로 인해 EmpName을(를) 얻을 수 있기 때문에 보고에 매우 문제가 있다는 것이다.여기서 HQL은 당신이 원하는 것을 로딩(연결/관계를 로드하지 않음)하여 성능을 여러 번 증가시킨다.
Criteria의 한 가지 특징은 동적 쿼리 생성으로 인해 SQL Injection으로부터 u를 보호할 수 있다는 것이다. 동적 쿼리 생성은 HQL과 같이 고정되거나 매개 변수가 되어 SQL Injection으로부터 안전하지 않다.
또한 당신이 당신의 aspx.cs 파일에 HQL을 쓴다면 당신은 당신의 DAL과 긴밀하게 결합된다.
전반적으로 내 결론은 리포트처럼 HQL 없이는 살 수 없는 곳이 있으니 그 외에는 기준 관리가 더 쉽다는 것이다.
내게 있어 기준에서 가장 큰 승리는 예제 API인데, 여기서 객체를 통과하면 최대 절전 모드에서는 해당 객체 속성에 기반한 쿼리가 구축된다.
그 외에도 기준 API에는 다음과 같은 기발한 (동면 팀이 api를 재작업하고 있다고 믿는다)가 있다.
- a criteria.createAlias("obj")는 가능한 외부 결합 대신 내부 결합을 강제한다.
- 동일한 별칭을 두 번 만들 수 없음
- 일부 sql 절에는 단순한 기준 상대(예: 하위 선택)가 없다.
- 등
나는 sql과 유사한 쿼리를 원할 때 HQL을 사용하는 경향이 있고(상태='차단된' 사용자에서 삭제), 문자열 첨가를 사용하지 않을 때는 기준을 사용하는 경향이 있다.
HQL의 또 다른 이점은 당신이 모든 쿼리를 미리 정의할 수 있고, 심지어 파일이나 그 밖의 다른 것들로도 외부화할 수작업 전에 모든 쿼리를 정의할 수 있다는 것이다.
criteria api는 SQL이나 HQL 모두 제공하는 하나의 뚜렷한 특징을 제공한다.즉, 쿼리의 컴파일 시간 확인을 허용한다.
초기에는 주로 Criteria를 사용했지만 성능 문제로 인해 HQL로 교체된 후였습니다.
주로 기준에서는 여러 개의 쿼리를 유도하지만 HQL에서는 매우 최적화된 여러 조인과 함께 매우 복잡한 쿼리를 사용하고 있다.
그 경우는 우리가 단지 몇 가지 예절을 특정 물체에 사용하고 완전한 물체는 사용하지 않는다는 것이다.기준과 함께 문제는 또한 끈 연결이었다.
사용자의 이름과 성을 HQL에 표시해야 할 경우 매우 쉽다고 합시다.(name || ' ' || surname)
하지만 크로테리아에서는 이것이 가능하지 않다.
이를 극복하기 위해 우리는 ResultTransormer를 사용했는데, 여기에는 필요한 결과를 위해 그러한 결합이 구현되는 방법이 있었다.
오늘날 우리는 주로 다음과 같이 HQL을 사용한다.
String hql = "select " +
"c.uuid as uuid," +
"c.name as name," +
"c.objective as objective," +
"c.startDate as startDate," +
"c.endDate as endDate," +
"c.description as description," +
"s.status as status," +
"t.type as type " +
"from " + Campaign.class.getName() + " c " +
"left join c.type t " +
"left join c.status s";
Query query = hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();
그래서 우리의 경우에 반환된 기록들은 필요한 재산의 지도들이다.
- HQL은 데이터에 대해 선택 연산과 선택되지 않은 연산을 모두 수행하는 것이지만, 기준은 데이터 선택만을 위한 것이므로 기준을 사용하여 선택 연산을 수행할 수 없다.
- HQL은 동적 쿼리를 실행하기에 적합하며, 여기서 기준은 동적 쿼리를 실행하기에 적합하다.
- HQL은 페이지 지정 개념을 지원하지 않지만 기준 페이지 지정은 수행할 수 있다.
- HQL보다 실행 시간이 더 오래 걸리는 데 사용되는 기준
- Criteria를 사용하면 동적 쿼리 생성으로 인해 SQL Injection이 안전하지만 HQL에서는 쿼리가 고정되거나 파라메트릭화되어 SQL Injection으로부터 안전하지 않다.
동적 조건 쿼리는 입력에 기반하여 쿼리를 구성할 수 있다.Hql 쿼리의 경우 일단 구성하면 정적 쿼리의 구조를 변경할 수 없다.
나는 여기서 죽은 말을 걷어차고 싶지는 않지만, 기준 질의가 이제 더 이상 사용되지 않는다는 것을 언급하는 것이 중요하다.HQL을 사용하십시오.
나는 또한 동적 쿼리에 대한 기준 쿼리를 선호한다.그러나 나는 삭제 쿼리에 hql을 선호한다. 예를 들어, 부모 ID 'xyz'의 하위 테이블에서 모든 레코드를 삭제하면 HQL로 쉽게 얻을 수 있다. 그러나 기준 API의 경우 먼저 n은 하위 테이블 레코드 수인 n개의 삭제 쿼리를 실행해야 한다.
여기 있는 대부분의 답변은 오해의 소지가 있으며, 라고 언급하고 있다.Criteria Queries
보다 느리다HQL
사실은 그렇지 않다.
If you delve deep and perform some tests you will see Criteria Queries perform much better that regular HQL.
And also with Criteria Query you get Object Oriented control which is not there with HQL.
For more information read this answer here.
There is another way. I ended up with creating a HQL parser based on hibernate original syntax so it first parse the HQL then it could dynamically inject dynamic parameters or automatically adding some common filters for the HQL queries. It works great!
This post is quite old. Most answers talk about Hibernate criteria, not JPA criteria. JPA 2.1 added CriteriaDelete/CriteriaUpdate, and EntityGraph that controls what exactly to fetch. Criteria API is better since Java is OO. That is why JPA is created. When JPQL is compiled, it will be translated to AST tree(OO model) before translated to SQL.
Another point is that, I see Criteria is more suited for building on top of it and not to be used ditectly in the end-code.
It is more suited to build liberaries using it more than using jpql or hql.
For example I've build spring-data-jpa-mongodb-expressions using Criteria API (the same way spring data QBE do).
I think spring data query generations are using jpaql rather criteria which I don't understand why.
HQL can cause security concerns like SQL injection.
ReferenceURL : https://stackoverflow.com/questions/197474/jpa-and-hibernate-criteria-vs-jpql-or-hql
'Programing' 카테고리의 다른 글
최대 절전 모드에서의 서로 다른 저장 방법의 차이점은? (0) | 2022.04.26 |
---|---|
이 항목에 대한 액세스.Vuex 스토어에서 $apollo, NUXT에서 vue-apollo? (0) | 2022.04.26 |
렌더 오류: "TypeError: 정의되지 않은 속성 '길이'를 읽을 수 없음" (0) | 2022.04.25 |
단일 방법을 사용하는 클래스 - 최상의 접근 방식? (0) | 2022.04.25 |
VueJs - $ref에서 요소의 DOM 속성에 액세스하는 방법 (0) | 2022.04.25 |