| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- docker
- HttpHeader
- content-type
- junit
- MySQL
- Spring MVC
- ExceptionHandler
- nextjs
- jsonview
- Intellij
- Redis
- Example
- docker-compose
- mock
- RESTful
- Spring
- test
- hibernate
- namedqueries
- Today
- Total
hellokiseok
@NamedQueries Example 본문
NamedQueries Annotation 사용예
쿼리를 이용해 개발을 할경우 한가지 고민 거리가 있다. 그것은 수많은 비즈니스 쿼리들을 어떻게 관리 할것인가 하는것이다, 그중에 JPA 에서 지원하는 @NamedQueries Annotation 을 이용한 방법을 소개하려고 합니다.
@NamedQueries 는 일단 Source Code 와 Document, xml 작성 등, 개발하면서 부가적으로 생기는 문서들에 대한 부담감을 줄이고자 생각해낸 아이디어가 아닌가 생각합니다. 개발 따로 문서작성 따로 작성하면 불편하기때문에 소스코드 문서는 Java Doc 을 사용하고 수많은 설정 파일은 Annotation 으로 처리 하도록 하여 Source Code 안에서 모든것을 해결하는 방법입니다. Spring 에서는 이를 지원하고 있고 Hibernate 또한 이런 개발 방법을 지원합니다. 하지만 이 방법이 최선이라곤 말 못하겠습니다 개인적인 생각은 어디까지나 스타일 문제라고 봅니다.
당신이 만약 쿼리를 작성했고 이것에 대한 테스트나, 문서화를 한번에 해결할수 있을까요?
1.주관적 장점
- 한곳에 Query 를 모아서 관리 할수 있음. (Entity 마다 따로 관리됩니다.)
- 오류 검증이 가능함, 실제로 APP 구동시 Query의 유효성을 검사합니다. 에디터에 따라서는 편집중 오류표시도 됩니다. 즉 자신이 작성한 Query 가 실제로 동작 이 가능한지 개발단계에서 알수있습니다.(직접 쿼리를 실행 안해보고 간단한 Syntax 검사,entity or column 존재 여부, parameter 등 기본적인 검사를 모두 합니다.)
- 별다른 문서화가 필요없다. 이것은 개인적으로 매우 맘에 드는 내용입니다. 해당 Entity Class Source Code 에 작성되기 때문에 인수 인계시 Source Code만 확인하면 되기때문에 번거롭게 문서화 작업이 필요 없습니다.(물론 있으면 좋지만 없는것만 못한 문서보다는 훨씨 좋다고 생각합니다.)
Intellij IDEA 의 오류 표시 화면
2.주관적 단점
- 동적Query 작성불가.
- Source Code영역을 같이 쓰기때문에 Query가 많아질수록 가독성 문제가 생길수 있음.(map 파일을 따로 관리하는것이 더 좋은분께는 독이 될수 있습니다.)
서론이 길었는데 이제 예제를 보여드리겠습니다.
*모델
@NamedQuery - HQL 을 작성합니다.
@NamedNativeQuery - 표준 Query 를 작성합니다.
package com.kskim.model;
import javax.annotation.Generated;
import javax.persistence.*;
@javax.persistence.Table(name = "USER", schema = "", catalog = "test")
@Entity
@NamedQueries({
@NamedQuery(name = "testHql", query = "FROM UserEntity WHERE id=:id")
})
@NamedNativeQueries({
@NamedNativeQuery(name = "testSql",query = "Select * FROM USER WHERE id=:id")
})
public class UserEntity {
private String name;
private String password;
private Integer id;
@javax.persistence.Column(name = "name", nullable = false, insertable = true, updatable = true, length = 100, precision = 0)
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@javax.persistence.Column(name = "password", nullable = false, insertable = true, updatable = true, length = 200, precision = 0)
@Basic
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@GeneratedValue(strategy = GenerationType.AUTO)
@javax.persistence.Column(name = "id", nullable = false, insertable = true, updatable = true, length = 10, precision = 0)
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
return true;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + id;
return result;
}
}
*쿼리 예제
package com.kskim.dao;
import com.kskim.model.UserEntity;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserEntityDAOImpl implements UserEntityDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public UserEntity getUser(Integer id) {
Session session = sessionFactory.getCurrentSession();
Query testHql = session.getNamedQuery("testHql");
testHql.setParameter("id",id);
UserEntity userEntity= (UserEntity) testHql.uniqueResult();
return userEntity;
}
}
저는 이기능을 그닥 쓰진 않고 있습니다. Criteria 를 주로 사용하고 있지만 native query 를 만약 사용한다면 서비스 코드에 뿔뿔이 흩어져있는것보단 좋은 대안이라고 생각합니다.