select * from tbl_zipcode
Criteria crit = sess.createCriteria(Zipcode.class);
List<Zipcode> zipcodeList = crit.list();
List<Zipcode> zipcodeList = crit.list();
select seq, zipcode, st_bunji, ed_bunji from tbl_zipcode
Criteria crit = sess.createCriteria(Zipcode.class);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.id().as("seq"));
projectionList.add(Projections.property("zipcode").as("zipcode"));
projectionList.add(Projections.property("stBunji").as("stBunji"));
projectionList.add(Projections.property("edBunji").as("edBunji"));
crit.setProjection(projectionList);
crit.setResultTransformer(new AliasToBeanResultTransformer(Zipcode.class));
List<Zipcode> zipcodeList = crit.list();
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.id().as("seq"));
projectionList.add(Projections.property("zipcode").as("zipcode"));
projectionList.add(Projections.property("stBunji").as("stBunji"));
projectionList.add(Projections.property("edBunji").as("edBunji"));
crit.setProjection(projectionList);
crit.setResultTransformer(new AliasToBeanResultTransformer(Zipcode.class));
List<Zipcode> zipcodeList = crit.list();
원하는 칼럼을 뽑아낼 때 쓰는 ProjectionList와 Projections을 사용합니다.(테이블 하나 조회하면서는 안쓸듯...)
해보니까 Projections 에서 꼭 as() 를 사용해서 Zipcode 클래스의 필드명과 이름을 맞춰줘야 하더군요... -0-/
Projections.id() 와 Projections.property() 는 뭐가 다른지 아시겠죠? ㅎㅎ;; id() 가 PK가 되는 필드 입니다.
select count(*) from tbl_zipcode
Criteria crit = sess.createCriteria(Zipcode.class);
crit.setProjection( Projections.rowCount() );
List<Integer> zipcodeList = crit.list();
System.out.println("count : " + zipcodeList.get(0));
crit.setProjection( Projections.rowCount() );
List<Integer> zipcodeList = crit.list();
System.out.println("count : " + zipcodeList.get(0));
select count(seq) as count from tbl_zipcode
Criteria crit = sess.createCriteria(Zipcode.class);
crit.setProjection(Projections.count("seq").as("count"));
List<Integer> zipcodeList = crit.list();
System.out.println("count : " + zipcodeList.get(0));
crit.setProjection(Projections.count("seq").as("count"));
List<Integer> zipcodeList = crit.list();
System.out.println("count : " + zipcodeList.get(0));
ORDER BY
select * from tbl_zipcode order by seq desc
Criteria crit = sess.createCriteria(Zipcode.class);
crit.addOrder(Order.desc("seq"));
List<Zipcode> zipcodeList = crit.list();
crit.addOrder(Order.desc("seq"));
List<Zipcode> zipcodeList = crit.list();
Order.asc(String propertyName) 도 있습니다~ +_+
Criteria crit = sess.createCriteria(Zipcode.class);
List<Zipcode> zipcodeList = crit.list();
생략하겠습니다~
List<Zipcode> zipcodeList = crit.list();
생략하겠습니다~
WHERE
where문은 Restrictions을 사용합니다. 내용이 많으니 자세한것은 API를 봐주세요~
select * from tbl_zipcode where seq = 1555
crit.add(Restrictions.eq("seq", 1555));
select * from tbl_zipcode where seq = 45
crit.add(Restrictions.idEq(45)); // idEq() 를 사용하면 PK 칼럼으로 검색합니다.
select * from tbl_zipcode where dong like '방화%'
crit.add(Restrictions.like("dong", "방화", MatchMode.START)); // '방화%'
MatchMode 종류는 ANYWHERE, END, EXACT, START 4가지 종류가 있습니다.
딱 보면 아시겠지만 '%방화%', '방화%', '방화', '%방화' 이렇게 됩니다.
select * from tbl_zipcode where sido = '서울' and zipcode like '157%'
crit.add(Restrictions.eq("sido", "서울"));
crit.add(Restrictions.like("zipcode", "157", MatchMode.START));
crit.add(Restrictions.like("zipcode", "157", MatchMode.START));
여러개의 조건을 사용할 때에는 계속 .add() 해주면 됩니다.
select * from tbl_zipcode where where (st_bunji = '514' and sido = '서울' and dong = '방화2동')
Map<String, String> m = new Hashtable<String, String>();
m.put("sido", "서울");
m.put("dong", "방화2동");
m.put("stBunji", "514");
crit.add(Restrictions.allEq(m));
m.put("sido", "서울");
m.put("dong", "방화2동");
m.put("stBunji", "514");
crit.add(Restrictions.allEq(m));
여러개의 eq를 사용할 경우 Map 을 사용할 수 있습니다.
select * from tbl_zipcode where seq >= 5300
crit.add(Restrictions.ge("seq", new Integer(50300)));
주의 해야 할 것은 2번째 인자는 Object 형태라는 것입니다. +_+;
ge(>=), gt(>), le(<=), lt(<) 가 있습니다.
select * from tbl_zipcode where sido in ('서울', '부산')
String[] in = {"서울", "부산"};
crit.add(Restrictions.in("sido", in)); // Collection 또는 Object[] 사용 가능
crit.add(Restrictions.in("sido", in)); // Collection 또는 Object[] 사용 가능
select * from tbl_zipcode where ( sido = '서울' and zipcode like '157%' )
crit.add(
Restrictions.conjunction() // and 연산으로 그룹
.add( Restrictions.eq("sido", "서울") )
.add( Restrictions.like("zipcode", "157", MatchMode.START) )
);
Restrictions.conjunction() // and 연산으로 그룹
.add( Restrictions.eq("sido", "서울") )
.add( Restrictions.like("zipcode", "157", MatchMode.START) )
);
and 조건을 여러개 사용할 경우 그냥 계속 .add() 해도 되지만 Restrictions.conjunction() 로 그룹할 수 있습니다.
Restrictions.conjunction() 은 and 로 그룹하고, Restrictions.disjunction() 은 or 로 그룹합니다.
select * from tbl_zipcode where ( (dong like '방화%' or dong like '%1동') and (zipcode like '157%' or zipcode like '431') )
crit.add(
Restrictions.conjunction()
.add(
Restrictions.disjunction()
.add(Restrictions.like("dong", "방화", MatchMode.START))
.add(Restrictions.like("dong", "1동", MatchMode.END))
)
.add(
Restrictions.disjunction()
.add(Restrictions.like("zipcode", "157", MatchMode.START))
.add(Restrictions.like("zipcode", "431", MatchMode.START))
)
);
Restrictions.conjunction()
.add(
Restrictions.disjunction()
.add(Restrictions.like("dong", "방화", MatchMode.START))
.add(Restrictions.like("dong", "1동", MatchMode.END))
)
.add(
Restrictions.disjunction()
.add(Restrictions.like("zipcode", "157", MatchMode.START))
.add(Restrictions.like("zipcode", "431", MatchMode.START))
)
);
- 동이 '방화'로 시작하거나 '1동'으로 끝나고 우편번호가 157로 시작하거나 431로 시작하는 데이터를 조회 합니다.
- (동이 '방화'로 시작 or 동이 '1동'으로 끝) and (우편번호가 '157'로 시작 or 우편번호가 '431'로 시작)
정도가 되겠네요... (헷갈리.. ㅠㅠ)
select * from tbl_zipcode where st_bunji between '157' and '158'
crit.add(Restrictions.between("stBunji", "157", "158"));
select * from tbl_zipcode where ( dong like '방%' and dong like '%1동' )
crit.add( Restrictions.and( Restrictions.eq("sido", "서울"), Restrictions.like("dong", "1동", MatchMode.END) ) );
Restrictions.and(조건, 조건) 은 두개의 조건을 and 로 그룹합니다.
Restrictions.or(조건, 조건) 은 두개의 조건을 or 로 그룹합니다.
select * from tbl_zipcode where not ( sido in ('서울', '부산') )
crit.add( Restrictions.not( Restrictions.in("sido", new String[] { "서울", "부산" }) ) );
INNER JOIN
키를 기준으로 일치하는 데이터만 가져옵니다. (다 아시졍? +_+)
Criteria crit = sess.createCriteria(Emp.class);
Session.createCriteria(클리스명) 를 통해서 생성한 Critereria 객체에 다시 createCriteria(String associationPath, String alias) 를 사용해서 JOIN 을 하면 됩니다.
이렇게 JOIN 한 결과는 Emp 객체도 Dept 객체도 아니기 때문에, Criteria의 setResultTransformer 메소드를 사용하여 Criteria를 이용한 조회 결과를 별도 정의한 객체 형태나 Map 형태로로 전달받아야 하겠습니다.
근데 전 객체로 변형하는 법은 잘 안되서... 걍 Map 으로 ㄱㄱㄱ!
여기서 두번째 인자로 넣는 엘리어스명은 쿼리에서 쓰는 엘리어스명도 되지만 나중에 Map 에서 꺼 낼때의 키도 되기 때문에 꼭 지정해줘야 할 것입니다....
실행 되는 쿼리는 아래와 같습니다.
이러면 당연히 부서가 없는 'TOM' 은 목록에 나오지가 않겠죠? 만약 사원 목록을 본다면 부서가 없는 사원이 나오면 안되겠죠?
LEFT JOIN
두개의 테이블을 조인할 때 왼쪽 테이블을 기분으로 오른쪽 테이블을 조인 시키는 LEFT JOIN 을 해봅시다...
createCriteria(String associationPath, String alias, int joinType) 를 사용하면 됩니다.
실행되는 쿼리는 아래와 같습니다. 엘리어스 사용에 주의 하세요~
키를 기준으로 일치하는 데이터만 가져옵니다. (다 아시졍? +_+)
// select * from tbl_emp e
Criteria crit = sess.createCriteria(Emp.class, "e");
// join tbl_dept d on this.deptno = d.deptno
crit.createCriteria("dept", "d");
// Result 를 Map 형태로 변환
crit.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List<Map<String, Object>> joinList = crit.list();
int size = joinList.size();
for(int i=0 ; i < size ; i++) {
Map<String, Object> map = joinList.get(i);
Emp emp = (Emp) map.get("e");
Dept dept = (Dept) map.get("d");
System.out.println("row: " + (i+1));
System.out.println(emp);
System.out.println(dept);
}
Criteria crit = sess.createCriteria(Emp.class, "e");
// join tbl_dept d on this.deptno = d.deptno
crit.createCriteria("dept", "d");
// Result 를 Map 형태로 변환
crit.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List<Map<String, Object>> joinList = crit.list();
int size = joinList.size();
for(int i=0 ; i < size ; i++) {
Map<String, Object> map = joinList.get(i);
Emp emp = (Emp) map.get("e");
Dept dept = (Dept) map.get("d");
System.out.println("row: " + (i+1));
System.out.println(emp);
System.out.println(dept);
}
Criteria crit = sess.createCriteria(Emp.class);
Session.createCriteria(클리스명) 를 통해서 생성한 Critereria 객체에 다시 createCriteria(String associationPath, String alias) 를 사용해서 JOIN 을 하면 됩니다.
이렇게 JOIN 한 결과는 Emp 객체도 Dept 객체도 아니기 때문에, Criteria의 setResultTransformer 메소드를 사용하여 Criteria를 이용한 조회 결과를 별도 정의한 객체 형태나 Map 형태로로 전달받아야 하겠습니다.
근데 전 객체로 변형하는 법은 잘 안되서... 걍 Map 으로 ㄱㄱㄱ!
여기서 두번째 인자로 넣는 엘리어스명은 쿼리에서 쓰는 엘리어스명도 되지만 나중에 Map 에서 꺼 낼때의 키도 되기 때문에 꼭 지정해줘야 할 것입니다....
실행 되는 쿼리는 아래와 같습니다.
select
this_.empno as empno0_1_,
this_.ename as ename0_1_,
this_.job as job0_1_,
this_.hire_date as hire4_0_1_,
this_.deptno as deptno0_1_,
d1_.deptno as deptno1_0_,
d1_.dname as dname1_0_,
d1_.loc as loc1_0_
from
tbl_emp this_
inner join
tbl_dept d1_
on this_.deptno=d1_.deptno
this_.empno as empno0_1_,
this_.ename as ename0_1_,
this_.job as job0_1_,
this_.hire_date as hire4_0_1_,
this_.deptno as deptno0_1_,
d1_.deptno as deptno1_0_,
d1_.dname as dname1_0_,
d1_.loc as loc1_0_
from
tbl_emp this_
inner join
tbl_dept d1_
on this_.deptno=d1_.deptno
이러면 당연히 부서가 없는 'TOM' 은 목록에 나오지가 않겠죠? 만약 사원 목록을 본다면 부서가 없는 사원이 나오면 안되겠죠?
LEFT JOIN
두개의 테이블을 조인할 때 왼쪽 테이블을 기분으로 오른쪽 테이블을 조인 시키는 LEFT JOIN 을 해봅시다...
createCriteria(String associationPath, String alias, int joinType) 를 사용하면 됩니다.
// select * from tbl_emp e
Criteria crit = sess.createCriteria(Emp.class, "e");
// join tbl_dept d on this.deptno = d.deptno
crit.createCriteria("dept", "d", Criteria.LEFT_JOIN);
// Result 를 Map 형태로 변환
crit.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List<Map<String, Object>> joinList = crit.list();
int size = joinList.size();
for(int i=0 ; i < size ; i++) {
Map<String, Object> map = joinList.get(i);
Emp emp = (Emp) map.get("e");
Dept dept = (Dept) map.get("d");
System.out.println("row: " + (i+1));
System.out.println(emp);
System.out.println(dept);
}
Criteria crit = sess.createCriteria(Emp.class, "e");
// join tbl_dept d on this.deptno = d.deptno
crit.createCriteria("dept", "d", Criteria.LEFT_JOIN);
// Result 를 Map 형태로 변환
crit.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List<Map<String, Object>> joinList = crit.list();
int size = joinList.size();
for(int i=0 ; i < size ; i++) {
Map<String, Object> map = joinList.get(i);
Emp emp = (Emp) map.get("e");
Dept dept = (Dept) map.get("d");
System.out.println("row: " + (i+1));
System.out.println(emp);
System.out.println(dept);
}
실행되는 쿼리는 아래와 같습니다. 엘리어스 사용에 주의 하세요~
select
this_.empno as empno0_1_,
this_.ename as ename0_1_,
this_.job as job0_1_,
this_.hire_date as hire4_0_1_,
this_.deptno as deptno0_1_,
d1_.deptno as deptno1_0_,
d1_.dname as dname1_0_,
d1_.loc as loc1_0_
from
tbl_emp this_
left outer join
tbl_dept d1_
on this_.deptno=d1_.deptno
this_.empno as empno0_1_,
this_.ename as ename0_1_,
this_.job as job0_1_,
this_.hire_date as hire4_0_1_,
this_.deptno as deptno0_1_,
d1_.deptno as deptno1_0_,
d1_.dname as dname1_0_,
d1_.loc as loc1_0_
from
tbl_emp this_
left outer join
tbl_dept d1_
on this_.deptno=d1_.deptno
Pagination
많은 자료를 조회할 때 일정한 양의 자료를 한 페이지만 보여주도록 하는 기능입니다.
꼭 필요한 기능이고, 그다지 복잡할 것도 없지만, 막상 쿼리 날리려면 DBMS 마다 쿼리도 틀리고... 쉽지 안쵸 ㅠ_ㅠ
하지만 하이버네이트에서는
setFirstResult(int firstResult) 과 setMaxResults(int maxResults) 메소드 두개면 해결 됩니다! ㅋㅋㅋ
전부터 해오던 우편번호 테이블 가지고 해봅시다...
한 페이지에 10개씩 보여준다고 하고 4페이지의 내용을 보여주게 됩니다.
페이징 처리가 되있는 우편번호 검색 페이지를 만들어봤습니다.
몇개의 DMBS 에서 돌려보니까 아래와 같은 쿼리가 나오네요
MySQL 5.1.38
Oracle 10g Express Edition
Microsoft SQL Server 2005
많은 자료를 조회할 때 일정한 양의 자료를 한 페이지만 보여주도록 하는 기능입니다.
꼭 필요한 기능이고, 그다지 복잡할 것도 없지만, 막상 쿼리 날리려면 DBMS 마다 쿼리도 틀리고... 쉽지 안쵸 ㅠ_ㅠ
하지만 하이버네이트에서는
setFirstResult(int firstResult) 과 setMaxResults(int maxResults) 메소드 두개면 해결 됩니다! ㅋㅋㅋ
전부터 해오던 우편번호 테이블 가지고 해봅시다...
Criteria crit = sess.createCriteria(Zipcode.class);
crit.setFirstResult(40); // 시작 로우 라인 번호(?)
crit.setMaxResults(10); // 시작 로우 라인 번호로 부터 몇개?!
List<Zipcode> list = crit.list();
int size = list.size();
for(int i=0 ; i < size ; i++) {
Zipcode z = list.get(i);
System.out.println(z.toString());
}
crit.setFirstResult(40); // 시작 로우 라인 번호(?)
crit.setMaxResults(10); // 시작 로우 라인 번호로 부터 몇개?!
List<Zipcode> list = crit.list();
int size = list.size();
for(int i=0 ; i < size ; i++) {
Zipcode z = list.get(i);
System.out.println(z.toString());
}
한 페이지에 10개씩 보여준다고 하고 4페이지의 내용을 보여주게 됩니다.
페이징 처리가 되있는 우편번호 검색 페이지를 만들어봤습니다.
pagination.war |
몇개의 DMBS 에서 돌려보니까 아래와 같은 쿼리가 나오네요
MySQL 5.1.38
select
this_.seq as seq0_0_,
this_.zipcode as zipcode0_0_,
this_.sido as sido0_0_,
this_.gugun as gugun0_0_,
this_.dong as dong0_0_,
this_.ri as ri0_0_,
this_.bldg as bldg0_0_,
this_.st_bunji as st8_0_0_,
this_.ed_bunji as ed9_0_0_
from
tbl_zipcode this_ limit ?,
?
this_.seq as seq0_0_,
this_.zipcode as zipcode0_0_,
this_.sido as sido0_0_,
this_.gugun as gugun0_0_,
this_.dong as dong0_0_,
this_.ri as ri0_0_,
this_.bldg as bldg0_0_,
this_.st_bunji as st8_0_0_,
this_.ed_bunji as ed9_0_0_
from
tbl_zipcode this_ limit ?,
?
Oracle 10g Express Edition
select
*
from
( select
row_.*,
rownum rownum_
from
( select
this_.seq as seq0_0_,
this_.zipcode as zipcode0_0_,
this_.sido as sido0_0_,
this_.gugun as gugun0_0_,
this_.dong as dong0_0_,
this_.ri as ri0_0_,
this_.bldg as bldg0_0_,
this_.st_bunji as st8_0_0_,
this_.ed_bunji as ed9_0_0_
from
tbl_zipcode this_ ) row_
where
rownum <= ?
)
where
rownum_ > ?
*
from
( select
row_.*,
rownum rownum_
from
( select
this_.seq as seq0_0_,
this_.zipcode as zipcode0_0_,
this_.sido as sido0_0_,
this_.gugun as gugun0_0_,
this_.dong as dong0_0_,
this_.ri as ri0_0_,
this_.bldg as bldg0_0_,
this_.st_bunji as st8_0_0_,
this_.ed_bunji as ed9_0_0_
from
tbl_zipcode this_ ) row_
where
rownum <= ?
)
where
rownum_ > ?
Microsoft SQL Server 2005
select
top 20 this_.seq as seq0_0_,
this_.zipcode as zipcode0_0_,
this_.sido as sido0_0_,
this_.gugun as gugun0_0_,
this_.dong as dong0_0_,
this_.ri as ri0_0_,
this_.bldg as bldg0_0_,
this_.st_bunji as st8_0_0_,
this_.ed_bunji as ed9_0_0_
from
tbl_zipcode this_
top 20 this_.seq as seq0_0_,
this_.zipcode as zipcode0_0_,
this_.sido as sido0_0_,
this_.gugun as gugun0_0_,
this_.dong as dong0_0_,
this_.ri as ri0_0_,
this_.bldg as bldg0_0_,
this_.st_bunji as st8_0_0_,
this_.ed_bunji as ed9_0_0_
from
tbl_zipcode this_