Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Archives
Today
Total
관리 메뉴

hellokiseok

@NamedQueries Example 본문

Hibernate

@NamedQueries Example

hellokiseok 2013. 7. 30. 14:58

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 를 만약 사용한다면 서비스 코드에 뿔뿔이 흩어져있는것보단 좋은 대안이라고 생각합니다.