환영합니다. Hibernate Criteria 예제 튜토리얼에 오신 것을 환영합니다. 오늘은 Hibernate에서의 Criteria에 대해 살펴보겠습니다.
Hibernate Criteria
대부분의 경우에는 데이터베이스를 쿼리하고 결과를 얻기 위해 HQL을 사용합니다. 그러나 HQL은 값 업데이트 또는 삭제에는 선호되지 않습니다. 왜냐하면 그러면 테이블 간의 모든 연관 관계를 처리해야 하기 때문입니다. Hibernate Criteria API는 데이터베이스를 쿼리하고 결과를 얻기 위한 객체 지향적인 접근 방식을 제공합니다. Hibernate에서는 Criteria를 사용하여 업데이트 또는 삭제 쿼리 또는 DDL 문을 실행할 수 없습니다. Hibernate Criteria 쿼리는 객체 지향적인 방식을 사용하여 데이터베이스에서 결과를 가져오기 위해서만 사용됩니다. 내 Hibernate criteria 예제에서는 같은 설정을 사용하여 내 HQL 예제와 동일한 방식으로 Criteria를 Hibernate에서 데이터베이스 쿼리에 사용하는 방법을 보여줄 것입니다. Hibernate Criteria API의 일반적인 사용 예시는 다음과 같습니다;
- Hibernate Criteria API는 sum(), min(), max() 등과 같은 집계 함수에 사용할 수 있는 Projection을 제공합니다.
- Hibernate Criteria API는
ProjectionList
과 함께 선택한 열만 검색하는 데 사용할 수 있습니다. - Hibernate에서 조인 쿼리를 위해 여러 테이블을 조인하는 데 사용할 수 있는 기준은 createAlias(), setFetchMode() 및 setProjection()
- 메소드와 같은 유용한 메소드가 있습니다. 조건을 가진 결과를 가져오는 데 Hibernate API에서 사용할 수 있는 기준은 add() 메소드가 있으며, 여기서 제한을 추가할 수 있습니다.
- Hibernate Criteria API는 결과를 정렬하는 데 사용할 수 있는 addOrder() 메소드를 제공합니다.
아래 클래스는 Hibernate Criteria API의 다양한 사용법을 보여줍니다. 이들 대부분은 HQL 튜토리얼의 예제들을 대체하는 것입니다.
package com.journaldev.hibernate.main;
import java.util.Arrays;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateCriteriaExamples {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// 준비 작업
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
// 모든 직원 가져오기
Criteria criteria = session.createCriteria(Employee.class);
List empList = criteria.list();
for(Employee emp : empList){
System.out.println("ID="+emp.getId()+", Zipcode="+emp.getAddress().getZipcode());
}
// ID로 가져오기, 모든 설정을 제거하기 위해 새 Criteria 생성
criteria = session.createCriteria(Employee.class)
.add(Restrictions.eq("id", new Long(3)));
Employee emp = (Employee) criteria.uniqueResult();
System.out.println("Name=" + emp.getName() + ", City="
+ emp.getAddress().getCity());
// 페이징 예제
empList = session.createCriteria(Employee.class)
.addOrder(Order.desc("id"))
.setFirstResult(0)
.setMaxResults(2)
.list();
for(Employee emp4 : empList){
System.out.println("Paginated Employees::"+emp4.getId()+","+emp4.getAddress().getCity());
}
// Like 예제
empList = session.createCriteria(Employee.class)
.add(Restrictions.like("name", "%i%"))
.list();
for(Employee emp4 : empList){
System.out.println("Employees having 'i' in name::"+emp4.getName()+","+emp4.getAddress().getCity());
}
// 프로젝션 예제
long count = (Long) session.createCriteria(Employee.class)
.setProjection(Projections.rowCount())
.add(Restrictions.like("name", "%i%"))
.uniqueResult();
System.out.println("Number of employees with 'i' in name="+count);
// 합계, 최소, 최대 집계 함수를 위한 프로젝션 사용
double sumSalary = (Double) session.createCriteria(Employee.class)
.setProjection(Projections.sum("salary"))
.uniqueResult();
System.out.println("Sum of Salaries="+sumSalary);
// 몇 가지 컬럼을 선택하기 위한 조인 예제
criteria = session.createCriteria(Employee.class, "employee");
criteria.setFetchMode("employee.address", FetchMode.JOIN);
criteria.createAlias("employee.address", "address"); // inner join by default
ProjectionList columns = Projections.projectionList()
.add(Projections.property("name"))
.add(Projections.property("address.city"));
criteria.setProjection(columns);
List
위 Hibernate Criteria 예제 프로그램을 실행하면 다음과 같은 출력을 얻습니다.
May 26, 2014 6:53:32 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 26, 2014 6:53:32 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 26, 2014 6:53:32 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 26, 2014 6:53:32 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
May 26, 2014 6:53:32 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate.cfg.xml
May 26, 2014 6:53:32 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate.cfg.xml
May 26, 2014 6:53:32 PM org.hibernate.internal.util.xml.DTDEntityResolver resolveEntity
WARN: HHH000223: Recognized obsolete hibernate namespace https://hibernate.sourceforge.net/. Use namespace https://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
May 26, 2014 6:53:32 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Hibernate Configuration loaded
Hibernate serviceRegistry created
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=pankaj, password=****}
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
May 26, 2014 6:53:32 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 26, 2014 6:53:32 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 26, 2014 6:53:32 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select this_.emp_id as emp_id1_1_1_, this_.emp_name as emp_name2_1_1_, this_.emp_salary as emp_sala3_1_1_, address2_.emp_id as emp_id1_0_0_, address2_.address_line1 as address_2_0_0_, address2_.city as city3_0_0_, address2_.zipcode as zipcode4_0_0_ from EMPLOYEE this_ left outer join ADDRESS address2_ on this_.emp_id=address2_.emp_id
ID=1, Zipcode=95129
ID=2, Zipcode=95051
ID=3, Zipcode=560100
ID=4, Zipcode=100100
Hibernate: select this_.emp_id as emp_id1_1_1_, this_.emp_name as emp_name2_1_1_, this_.emp_salary as emp_sala3_1_1_, address2_.emp_id as emp_id1_0_0_, address2_.address_line1 as address_2_0_0_, address2_.city as city3_0_0_, address2_.zipcode as zipcode4_0_0_ from EMPLOYEE this_ left outer join ADDRESS address2_ on this_.emp_id=address2_.emp_id where this_.emp_id=?
Name=Lisa, City=Bangalore
Hibernate: select this_.emp_id as emp_id1_1_1_, this_.emp_name as emp_name2_1_1_, this_.emp_salary as emp_sala3_1_1_, address2_.emp_id as emp_id1_0_0_, address2_.address_line1 as address_2_0_0_, address2_.city as city3_0_0_, address2_.zipcode as zipcode4_0_0_ from EMPLOYEE this_ left outer join ADDRESS address2_ on this_.emp_id=address2_.emp_id order by this_.emp_id desc limit ?
Paginated Employees::4,New Delhi
Paginated Employees::3,Bangalore
Hibernate: select this_.emp_id as emp_id1_1_1_, this_.emp_name as emp_name2_1_1_, this_.emp_salary as emp_sala3_1_1_, address2_.emp_id as emp_id1_0_0_, address2_.address_line1 as address_2_0_0_, address2_.city as city3_0_0_, address2_.zipcode as zipcode4_0_0_ from EMPLOYEE this_ left outer join ADDRESS address2_ on this_.emp_id=address2_.emp_id where this_.emp_name like ?
Employees having 'i' in name::David,Santa Clara
Employees having 'i' in name::Lisa,Bangalore
Hibernate: select count(*) as y0_ from EMPLOYEE this_ where this_.emp_name like ?
Number of employees with 'i' in name=2
Hibernate: select sum(this_.emp_salary) as y0_ from EMPLOYEE this_
Sum of Salaries=1000.0
Hibernate: select this_.emp_name as y0_, address1_.city as y1_ from EMPLOYEE this_ inner join ADDRESS address1_ on this_.emp_id=address1_.emp_id
[Pankaj, San Jose]
[David, Santa Clara]
[Lisa, Bangalore]
[Jack, New Delhi]
May 26, 2014 6:53:32 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]
저는 HQL 예제 프로젝트를 사용하고 있기 때문에, 이 클래스를 작동시키려면 그것을 가져와서 추가해야 합니다. 출력에서 실행된 hibernate 쿼리를 주목하세요. 이 방법으로 쿼리를 정제하고 원하는 결과를 얻을 수 있습니다. Hibernate에서 기준에 대한 빠른 요약입니다.
Source:
https://www.digitalocean.com/community/tutorials/hibernate-criteria-example-tutorial