일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Redis
- hibernate
- RESTful
- Spring
- docker-compose
- ExceptionHandler
- test
- nextjs
- Example
- HttpHeader
- Spring MVC
- content-type
- namedqueries
- mock
- MySQL
- docker
- Intellij
- junit
- jsonview
- 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 를 만약 사용한다면 서비스 코드에 뿔뿔이 흩어져있는것보단 좋은 대안이라고 생각합니다.