Criteria 또는 HQL 사용의 장단점은 무엇입니까 ? Criteria API는 Hibernate에서 쿼리를 표현하는 훌륭한 객체 지향 방법이지만, 때로는 Criteria Queries가 HQL보다 이해 / 빌드하기가 더 어렵습니다.
언제 기준을 사용하고 언제 HQL을 사용합니까? 어떤 사용 사례에서 무엇을 선호합니까? 아니면 맛의 문제일까요?
Criteria 또는 HQL 사용의 장단점은 무엇입니까 ? Criteria API는 Hibernate에서 쿼리를 표현하는 훌륭한 객체 지향 방법이지만, 때로는 Criteria Queries가 HQL보다 이해 / 빌드하기가 더 어렵습니다.
언제 기준을 사용하고 언제 HQL을 사용합니까? 어떤 사용 사례에서 무엇을 선호합니까? 아니면 맛의 문제일까요?
답변:
나는 주로 동적 쿼리에 대한 기준 쿼리를 선호합니다. 예를 들어, 일부 매개 변수에 따라 일부 순서를 동적으로 추가하거나 일부 부품 (예 : 제한 사항)을 제외하는 것이 훨씬 쉽습니다.
반면에 HQL을 이해하고 읽기가 훨씬 쉽기 때문에 정적 쿼리와 복잡한 쿼리에 HQL을 사용하고 있습니다. 또한 HQL은 조금 더 강력합니다. 예를 들어 다른 조인 유형에 적합합니다.
HQL과 criteriaQuery간에 성능면에서 차이가 있습니다. criteriaQuery를 사용하여 쿼리를 실행할 때마다 테이블 이름에 대한 새 별칭이 생성되어 DB의 마지막 쿼리 캐시에 반영되지 않습니다. 이로 인해 생성 된 SQL을 컴파일하는 데 오버 헤드가 발생하여 실행 시간이 더 걸립니다.
가져 오기 전략에 관하여 [http://www.hibernate.org/315.html]
- 기준은 매핑의 게으름 설정을 존중하며로드하려는 항목이로드되도록 보장합니다. 이는 하나의 기준 쿼리로 인해 지연되지 않은 모든 맵핑 된 연관 및 콜렉션이있는 서브 그래프를 페치하기 위해 여러 개의 SQL 즉시 SELECT 문이 발생할 수 있음을 의미합니다. "how"및 "what"을 변경하려면 setFetchMode ()를 사용하여 특정 콜렉션 또는 연관에 대한 외부 조인 페치를 활성화하거나 비활성화하십시오. 기준 쿼리는 페치 전략 (join vs select vs subselect)도 완전히 존중합니다.
- HQL은 매핑의 게으름 설정을 존중하며로드하려는 항목이로드되도록합니다. 이는 하나의 HQL 쿼리로 인해 지연되지 않은 모든 맵핑 된 연관 및 콜렉션이있는 서브 그래프를 페치하기 위해 여러 개의 SQL 즉시 SELECT 문이 발생할 수 있음을 의미합니다. "how"및 "what"을 변경하려면 LEFT JOIN FETCH를 사용하여 특정 콜렉션 또는 널 입력 가능 다 대일 또는 일대일 연관에 대해 외부 조인 페치를 사용하거나 JOIN FETCH를 사용으로 설정하십시오. 널이 불가능한 다 대일 또는 일대일 연관을위한 내부 결합 페치. HQL 쿼리는 매핑 문서에 정의 된 fetch = "join"을 존중하지 않습니다.
기준은 객체 지향 API이며 HQL은 문자열 연결을 의미합니다. 즉, 객체 지향의 모든 이점이 적용됩니다.
HQL은 SQL과 매우 유사하기 때문에 (대부분의 개발자는 이미 잘 알고 있음) 이러한 "기억할 필요가 없습니다"라는 주장은 그다지 중요하지 않습니다. HQL이 더 다르다면 더 중요 할 것입니다.
일반적으로 입력이 어떤 데이터에 사용 될지 알지 못하는 경우 기준을 사용합니다. 사용자가 1에서 50 개 항목 중 하나를 입력 할 수있는 검색 양식과 마찬가지로 검색 대상을 숨 깁니다. 사용자가 무엇을 검색하는지 확인하는 동안 기준에 더 많은 것을 추가하는 것은 매우 쉽습니다. 그 상황에서 HQL 쿼리를 넣는 것이 조금 더 번거로울 것이라고 생각합니다. HQL은 내가 원하는 것을 정확히 알면 훌륭합니다.
기준은 두 번째 수준 쿼리 캐시의 특수 최적화를 활용하는 자연 키 조회를 지정하는 유일한 방법입니다. HQL은 필요한 힌트를 지정할 방법이 없습니다.
여기에서 더 많은 정보를 찾을 수 있습니다.
기준 Api는 최대 절전 모드의 좋은 개념 중 하나입니다. 내 관점에 따르면 이것들은 HQL 과 Criteria Api를 변화시킬 수있는 몇 가지 요점입니다.
limit offset:rows
hql에서 당신은 사용 하여 SQL 주입을 피할 수 있습니다setParameter
나를 위해 기준은 동적 쿼리를 이해하고 만드는 것이 매우 쉽습니다. 그러나 내가 지금까지 말하는 결함은 Select, Proxy 및 Default의 세 가지 유형의 FetchMode 만 있기 때문에 모든 one-one 등의 관계를로드한다는 것입니다.이 모든 경우에는 many-one을로드합니다 (도움이된다면 잘못 될 수 있습니다) 나에게 :))
기준의 두 번째 문제는 완전한 객체를로드한다는 것입니다. 즉, 직원의 EmpName을로드하려는 경우이 insted와 함께 나오지 않습니다. 완전한 Employee 객체가 나오고 EmpName을 얻을 수 있습니다 . 보고 . 여기서 HQL은 원하는로드 (연결 / 관계를로드하지 않았 음)로 성능을 여러 번 향상시킵니다.
Criteria의 한 가지 특징은 ur 쿼리가 고정되거나 매개 변수화되어 HQL에서와 같이 SQL 쿼리에서 안전하지 않은 동적 쿼리 생성으로 인해 SQL 주입에서 안전하다는 것입니다.
또한 ur aspx.cs 파일에 HQL을 작성하면 ur DAL과 밀접하게 연결됩니다.
전반적으로 결론은 보고서와 같이 HQL 없이는 살 수없는 곳이 있다는 것입니다. 그렇지 않으면 기준을 관리하기가 더 쉽습니다.
기준 API는 동적으로 생성 된 쿼리에 더 적합합니다. 따라서 WHERE 절 필터, JOIN 절을 추가하거나 ORDER BY 절 또는 프로젝션 열을 변경하려는 경우 Criteria API를 사용 하면 SQL 주입 공격을 방지 하는 방식으로 쿼리를 동적으로 생성 할 수 있습니다 .
반면에 기준 쿼리는 표현력 이 떨어지며이 기사 에서 설명하는 것처럼 매우 복잡하고 비효율적 인 SQL 쿼리로 이어질 수도 있습니다. .
JPQL은 JPA 표준 엔터티 쿼리 언어이며 HQL은 JPQL을 확장하고 일부 Hibernate 관련 기능을 추가합니다.
JPQL과 HQL은 매우 표현력이 뛰어나며 SQL과 유사합니다. Criteria API와 달리 JPQL 및 HQL을 사용하면 JPA 제공자가 생성 한 기본 SQL 쿼리를 쉽게 예측할 수 있습니다. 또한 기준 쿼리보다 HQL 쿼리를 검토하는 것이 훨씬 쉽습니다.
JPQL 또는 Criteria API를 사용하여 엔티티를 선택하면 엔티티를 수정해야하는 경우 의미가 있습니다. 그렇지 않으면 DTO 투영 이 훨씬 더 나은 선택입니다.
엔터티 쿼리 구조를 변경할 필요가 없으면 JPQL 또는 HQL을 사용하십시오. 필터링 또는 정렬 기준을 변경하거나 프로젝션을 변경해야하는 경우 Criteria API를 사용하십시오.
그러나 JPA 또는 최대 절전 모드를 사용한다고해서 기본 SQL을 사용해서는 안된다는 의미는 아닙니다. SQL 쿼리는 매우 유용하며 JPQL 및 Criteria API는 SQL을 대체하지 않습니다. 이 주제에 대한 자세한 내용은 이 기사 를 확인하십시오 .
나를 위해 Criteria에서 가장 큰 승리는 Example API입니다. 여기서 객체를 전달할 수 있으며 최대 절전 모드는 해당 객체 속성을 기반으로 쿼리를 작성합니다.
그 외에도 기준 API에는 다음과 같은 단점이 있습니다 (최대 절전 모드 팀이 API를 다시 작성한다고 생각합니다).
sql과 비슷한 쿼리를 원할 때 HQL을 사용하는 경향이 있으며 (state = 'blocked'인 사용자에서 삭제) 문자열 추가를 사용하지 않으려는 경우 기준을 사용하는 경향이 있습니다.
HQL의 또 다른 장점은 미리 모든 쿼리를 정의하고 파일 등으로 외부화 할 수 있다는 것입니다.
기준 API는 SQL 또는 HQL이 제공하지 않는 고유 한 기능을 제공합니다. 즉. 쿼리의 컴파일 시간 검사를 허용합니다.
우리는 처음에는 응용 프로그램에서 기준을 주로 사용했지만 성능 문제로 인해 HQL로 대체 된 후에 사용했습니다.
주로 여러 조인으로 매우 복잡한 쿼리를 사용하여 Criteria에서 여러 쿼리를 생성하지만 HQL에서 매우 최적화되었습니다.
경우는 특정 객체에 대해 몇 가지 속성 만 사용하고 완전한 객체는 사용하지 않는 것입니다. 기준으로 문제는 문자열 연결이었습니다.
HQL에서 사용자의 이름과 성을 표시 해야하는 경우 매우 쉽지만 (name || ' ' || surname)
Crteria에서는 불가능합니다.
이를 극복하기 위해 ResultTransormers를 사용했는데, 필요한 결과를 위해 그러한 연결이 구현 된 방법이있었습니다.
오늘날 우리는 주로 다음과 같이 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();
따라서이 경우 반환 된 레코드는 필요한 속성의 맵입니다.
CriteriaUpdate<T>
및 CriteriaDelete<T>
참조.
동적에 대한 기준 쿼리는 입력을 기반으로 쿼리를 생성 할 수 있습니다. Hql 쿼리의 경우 정적 쿼리는 일단 생성 한 후에는 쿼리 구조를 변경할 수 없습니다.
또한 동적 쿼리에 대한 기준 쿼리를 선호합니다. 그러나 부모 쿼리 'xyz'의 자식 테이블에서 모든 레코드를 삭제하는 경우와 같이 쿼리 삭제에 hql을 선호합니다 .HQL로 쉽게 달성 할 수 있지만 기준 API의 경우 먼저 n 개의 자식 쿼리를 실행해야합니다. 여기서 n은 자식 수입니다 테이블 기록.
여기에 대한 답변 대부분이 오해하고 언급하는 Criteria Queries
속도가 느린보다HQL
은 실제로는 그렇지 않습니다.
심도를 조사하고 일부 테스트를 수행하면 기준 쿼리가 일반 HQL보다 훨씬 더 나은 성능을 볼 수 있습니다. 냅니다.
또한 Criteria Query 를 사용하면 HQL 에는없는 객체 지향 제어 를 얻습니다. 있습니다.
HQL은 SQL 삽입과 같은 보안 문제 를 일으킬 수 있습니다 .