2015년 10월 13일 화요일

블로그 이사 했습니다.



블로그 이사 했습니다.

https://kimpaper.github.io/

내용도 이전 중입니다.

2015년 10월 8일 목요일

spring jpa의 @NamedQuery, @NamedNativeQuery 연습

jpa에서.. repository를 이용하여 findAll이나.. findOneBy.... 시리즈를 써서 데이타를 조회 할수 있지만
아래와 같이 특정 쿼리를 직접 입력하여 이용도 가능합니다.

/classes/META-INF/orm.xml




    
        select i from Inter i where i.internameko = ?1
    

    
        select a.inter_seq, a.inter_name_ko, a.inter_name_en from tb_inter a where a.inter_name_ko = ?
    




또는.. 아래와 같이 Entity 클래스에 선언가능하다. (전 xml을 선호..)

@Entity @Table(name="tb_inter")
@NamedQuery(name = "User.findByAlal2",
  query = "select i from Inter i where i.internameko = ?1")
public class Inter {
....
}

(비슷한 속성으로는 @Query도 사용가능하고. 이 속성은 Repository에 선언합니다.)

% named-query와 named-native-query의 차이점
- named-query는 현재 코드내에 선언한 Entity를 기준으로 쿼리를 날린다. (Inter.java파일 참고)
- named-native-query는 db에 직접 쿼리를 날린다. (그러므로 result-class를 지정해야 한다.)

Inter.java

@Entity @Table(name="tb_inter")
public class Inter {
    @Id @Column(name = "inter_seq") @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer interseq;
    @Column(name = "inter_name_ko") @Expose
    private String internameko;
    @Column(name = "inter_name_en") @Expose
    private String internameen;
}


2015년 10월 7일 수요일

spring jpa 조회 연습

entity 작업에 조회까지.. 테스트 해봤습니다.

- 테이블의 관계가 아래와 같을때 상황
tb_member -< tb_member_inter >- tb_inter
-< tb_image

조회 조건
1. Member를 가져오면.. member의 이미지들과... inter의 목록을 함께 가져오도록
2. inter의 상세 정보는 tb_inter에 있음 (가져올때 조인해서..)


아래 class들 간략 설명
. MemberInter의 PK가 두개이므로. 위와 같이 클래스를 하나 만들어서 @IdClass를 지정해야 함
. @Expose 는 Gson관련하여 화면에 뿌릴 필드를 정하는 옵션입니다. jpa와는 무관합니다.
. MemberInter.class에서 많이 헷갈렸습니다. (@ManyToOne)
-- @JoinColumn을 추가로.. 써야 합니다.
-- optional을 true로 하면 join시 outer join을 합니다. (false는 inner join)


FetchType.EAGER -> 즉시 조회해서 데이타 채움
FetchType.LAZY -> 필요시 DB조회


##나중에 추가됨
- 필드명은 카멜케이스CamelCase를 꼭 써야 한다. 안그럼 나중에 method named query 시에 곤란해진다...



Member.java

@Entity @Table(name = "tb_member")
public class Member {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer member_seq;

    @Expose
    @OneToMany(
            targetEntity = Image.class
            , cascade = CascadeType.ALL
            , fetch = FetchType.EAGER
            , mappedBy = "member_seq")
    private List<image> imageList;

    @Expose
    @OneToMany(
            targetEntity = MemberInter.class
            , cascade = CascadeType.ALL
            , fetch = FetchType.EAGER
            , mappedBy = "member_seq")
    private List<memberinter> memberInterList;
}


MemberRepository.java

public interface MemberRepository extends JpaRepository<Member, Integer> {

}


Image.java

@Entity
@Table(name = "tb_image")
public class Image {
    @Id
    @GeneratedValue
    private Integer image_seq;
    @Column
    private Integer member_seq;
    @Column @Expose
    private String file_name;
}


Inter.java

@Entity @Table(name="tb_inter") @Embeddable
public class Inter {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer inter_seq;
    @Column @Expose
    private String inter_name_ko;
}


MemberInter.java

@Entity @Table(name="tb_member_inter") @IdClass(MemberInterPk.class)
public class MemberInter {
    @Id @Column
    private Integer member_seq;

    @Id @Column(insertable = false, updatable = false)
    private Integer inter_seq;

    @ManyToOne(
            targetEntity = Inter.class
            ,cascade = CascadeType.ALL
            ,fetch = FetchType.EAGER
            ,optional = false
    )
    @JoinColumn(name = "inter_seq")
    @Expose
    private Inter inter;
}


MemberInterPk.java

public class MemberInterPk implements Serializable {
    private Integer member_seq;
    private Integer inter_seq;
}


test 코드...
TestServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
        "classpath:servlet-context.xml",
        "classpath:config/context-datasource.xml"
})
public class TestServiceTest {
    private static final Logger logger = LoggerFactory.getLogger(TestServiceTest.class);

    @Autowired
    private Gson gson;

    @Autowired
    private MemberRepository memberRepository;

    @Test
    public void testGetMemberList() throws Exception {
        logger.info("------------ jpa test starting.... ------------------------");

        List<member> list = memberRepository.findAll();
        logger.info("memberList={}", gson.toJson(list));

        logger.info("------------ jpa test ended....    ------------------------");
    }
}


2015년 10월 5일 월요일

코드 꾸미기 툴 SyntaxHighlighter.js 에서 highlight.js 로 갈아 탐


템플릿> Html편집에 들어가서 아래 코드를 바로 위에 붙여 넣는다.

설치 및 사용법 https://highlightjs.org/


 









!사용법



... xml내용...



만약 html이나 xml의 &lt; 등을 수동으로 하려면... class에 noxml을 넣으면 되요.



... xml내용...



spring jpa 설정 및 테스트 (maven 설정)

거의 대부분 mybatis 를 이용하여 개발을 하는데..
JPA가 대세라고 해서 가벼운 프로젝트에 연동을 해봤습니다.

1. 라이브러리 import....
maven pom.xml


   org.springframework.data
   spring-data-jpa
   1.9.0.RELEASE


   org.hibernate
   hibernate-entitymanager
   4.3.8.Final



2. Entity class를 만들어 줍니다.
참고로 SerializedName, Expose는 jpa와 직접 관련은 없습니다.. (개체를 그대로 JsonView 할때 사용)

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import javax.persistence.*;

@Entity
@Table(name="tb_notice")
public class Notice {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "notice_id")
    @SerializedName(value = "notice_id")
    @Expose
    private Integer noticeId;

    @Column(name="title", nullable = false)
    @Expose
    private String title;

    @Column(name="content", nullable = false)
    @Expose
    private String content;

    @Column(name="reg_date", nullable = false)
    @SerializedName(value = "reg_date")
    @Expose
    private String regDate;

    @Column(name="del_yn", nullable = false)
    @Expose(serialize = false, deserialize = false)
    private String delYn;

    public Integer getNoticeId() {
        return noticeId;
    }

    public void setNoticeId(Integer noticeId) {
        this.noticeId = noticeId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getRegDate() {
        return regDate;
    }

    public void setRegDate(String regDate) {
        this.regDate = regDate;
    }

    public String getDelYn() {
        return delYn;
    }

    public void setDelYn(String delYn) {
        this.delYn = delYn;
    }
}



3. repository 를 만들어줍니다. (아무것도 없는게.. 인상적)

public interface NoticeRepository extends JpaRepository<Notice, Integer> {

}



4. context-jpa.xml 설정합니다. (txManager2인 이유는 기존에 mybatis에 영향을 주지 않기 위해서입니다. , mybatis를 한번에 다 걷어낼 자신이 없...)




    
    
        
        
    

    
        
            
            
        
    

    
        
            
            
        
    

    
        
        
    

    
    
        
            
                
                
            
        
    

    
    





5. 사용 예제

@Service
public class NoticeService extends ServiceBase  {
    private static final Logger logger = LoggerFactory.getLogger(NoticeService.class);

    @Autowired
    private NoticeRepository noticeRepository;

    public void srXX(RequestData req, ResponseData res) throws Exception {
        List<Notice> list = noticeRepository.findAll();
        res.put("notice_list", list);
    }
}


인터넷상에 자료가 많아서 설정은 어렵지 않았습니다.
하지만 실제로 사용에 요령이 필요하다고 하네요.. (제대로 이해를 하지 않고 사용하면 성능에도 영향을 준다고 함)