Daejeon IT Developer Conference Hibernate3

1,416 views

Published on

Daejeon IT Developer Conference Hibernate3 Print

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,416
On SlideShare
0
From Embeds
0
Number of Embeds
39
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • 저는 NHN 에 근무하고 있는 이동국입니다 . iBATIS 관련 문서를 번역해서 아마 제 이름이 익숙하신 분들도 꽤 되시리라 생각됩니다 . ^^ 오늘 오신 분들이 모두 원하는 바가 다르기 때문에 일반적인 수준에서 공통적으로 사용하는 부분에 대해 한번 살펴보고 주로 사용하셨던 분들은 한번 다시 되새겨보는 시간이 되었으면 합니다 .
  • Daejeon IT Developer Conference Hibernate3

    1. 1. 본 문서의 배포 및 변경 , 출력 및 활용에 관한 모든 권리는 작성자에 있습니다 . 본 서비스는 제 1 회 대전 IT 개발자 커뮤니티 참석자를 위해 제공됩니다 .
    2. 2. 하이버네이트 프로그래밍 기초 & 객체 지향 지원 최범균 다음커뮤니케이션 September 28 th , 2008
    3. 3. 목차 <ul><li>강의 목적 </li></ul><ul><li>ORM 과 하이버네이트 </li></ul><ul><li>하이버네이트 기초 사용법 </li></ul><ul><li>객체 지향과 하이버네이트 </li></ul><ul><li>하이버네이트 도입절차 </li></ul><ul><li>맺음말 </li></ul><ul><li>참고자료 </li></ul>
    4. 4. 강의 목적 <ul><li>ORM 에 대한 이해와 하이버네이트 소개 </li></ul><ul><li>하이버네이트 기초 사용법 설명 </li></ul><ul><li>하이버네이트의 객체 지향 지원 기능 소개 </li></ul><ul><li>하이버네이트 도입 절차 안내 </li></ul>강의 목적
    5. 5. <ul><li>대다수 웹 프로그래밍은 영속 데이터를 필요로 함 </li></ul><ul><li>회원 정보 , 게시판 , 사진함 등 전체 또는 일부 데이터는 영속성을 가짐 </li></ul><ul><li>데이터의 영속성을 위해 많이 사용되는 것 – 관계형 데이터베이스 (RDBS) </li></ul><ul><li>서버측 개발자 작업 중 높은 비중을 차지하는 것 </li></ul><ul><li>데이터 관리를 위한 SQL 작성 </li></ul><ul><li>SELECT 쿼리를 실행하고 , 실행 결과를 자바 객체에 저장 </li></ul><ul><li>INSERT, UPDATE 쿼리 실행 시 필요한 값 자바 객체에 저장 </li></ul><ul><li>테이블과 객체의 매핑 필요성 </li></ul><ul><li>쿼리 결과를 자바 객체로 변환해주는 코드를 작성하는 것은 성가심 </li></ul><ul><li>자바 객체의 값을 쿼리에 바인딩 시키는 코드를 작성하는 것은 성가심 </li></ul><ul><li>두 과정을 간단한 코드 / 설정 만으로 처리해주는 기능의 필요성 </li></ul>테이블과 객체 매핑의 필요성 ORM 과 하이버네이트
    6. 6. <ul><li>상속과 다형성의 불일치 </li></ul><ul><li>객체 지향에서는 상위 타입을 이용해서 해당 계층에 포함된 객체들의 공통 데이터를 표현할 수 있지만 , 테이블은 상위 테이블 / 하위 테이블 같은 개념을 지원하지 않는다 . </li></ul><ul><li>연관의 불일치 </li></ul><ul><li>RDBMS 의 참조키는 단방향인데 반해 , 객체는 양방향 연관이 가능하다 . </li></ul><ul><li>자바와 같은 객체 지향 언어는 Set, List 와 같은 컬렉션 타입을 지원하지는 RDBMS 는 참조키를 사용할 뿐이다 . </li></ul><ul><li>세밀함의 불일치 </li></ul><ul><li>RDBMS 에서는 테이블을 기준으로 표현 단위가 결정되면 , 객체 지향에서는 객체 단위로 표현 단위가 결정된다 . 1 개의 테이블에 저장된 데이터를 1 개 이상의 클래스를 이용해서 표현할 수 있다 . </li></ul>관계형 데이터베이스와 객체의 불일치 ORM 과 하이버네이트
    7. 7. <ul><li>DB 처리를 위한 코드가 객체 모델링에 제약을 가져옴 </li></ul><ul><li>객체 지향을 지원하는 ORM 도구를 직접 만들기는 쉽지 않음 </li></ul><ul><li>단순 코드의 반복 제거 </li></ul><ul><li>some.setMaxAge(rs.getInt()), pstmt.setString(3, some.getTitle()) 등 객체와 테이블 사이의 매핑을 처리하기 위한 코드의 감소 </li></ul><ul><li>코드 품질의 향상 </li></ul><ul><li>비지니스 로직에 집중하게 됨으로써 코드 품질 향상 </li></ul>ORM 도구의 필요성 ORM 과 하이버네이트
    8. 8. <ul><li>메타 데이터를 통한 매핑 설정이 가능해야 함 </li></ul><ul><li>설정 파일이나 어노테이션을 이용한 매핑 설정이 가능해야 함 </li></ul><ul><li>다양한 연관의 지원 </li></ul><ul><li>1-1, 1-N, N-M 연관 , 양방향 연관의 지원 </li></ul><ul><li>컬렉션 테이블 ( 또는 조인 테이블 ) 을 이용한 연관 매핑 지원 </li></ul><ul><li>Set, List, Map 등 컬렉션 타입 지원 </li></ul><ul><li>상속 및 다형성 지원 </li></ul><ul><li>클래스 상속 계층에 대한 매핑 지원 </li></ul><ul><li>타입을 이용한 조회 지원 </li></ul><ul><li>객체 프로퍼티에 기반한 쿼리 지원 </li></ul><ul><li>객체의 프로퍼티를 이용한 쿼리 지원 </li></ul>ORM 도구의 필수 조건 ORM 과 하이버네이트
    9. 9. <ul><li>풍부한 객체 지향 특징 지원 </li></ul><ul><li>자바의 컬렉션 타입을 이용한 연관 지원 </li></ul><ul><li>다양한 상속 매핑 방식 지원 </li></ul><ul><li>POJO 지원 </li></ul><ul><li>ORM 을 위한 별도의 인터페이스나 클래스를 구현 / 상속할 필요가 없다 . </li></ul><ul><li>자동 영속성 관리 </li></ul><ul><li>객체의 프로퍼티 변경을 자동으로 반영해준다 . </li></ul><ul><li>영속성 전이를 통해 연관된 객체 간의 영속성을 관리해준다 . </li></ul><ul><li>성능 향상 방법 제공 </li></ul><ul><li>늦은 로딩 , 조인 기반 조회 , 네이티브 쿼리 , 캐시 등 성능 개선 방법 제공 </li></ul>하이버네이트인 이유 ORM 과 하이버네이트
    10. 10. <ul><li>하이버네이트를 이용한 프로그래밍 절차 </li></ul><ul><li>1. 영속 클래스 작성 </li></ul><ul><li>2. 데이터베이스 스키마 생성 </li></ul><ul><li>3. 클래스와 테이블의 매핑 파일 작성 </li></ul><ul><li>4. 하이버네이트 설정 파일 작성 </li></ul><ul><li>5. SessionFactory 설정 </li></ul><ul><li>6. 하이버네이트를 이용한 CRUD 작성 </li></ul>프로그램 절차 하이버네이트 기초 사용법
    11. 11. <ul><li>기본 생성자를 제공해야 함 ( 필수 ) </li></ul><ul><li>데이터베이스 식별자 컬럼과 매핑될 필드 제공 ( 추천 ) </li></ul><ul><li>영속 클래스를 final 로 지정하지 않음 ( 추천 ) </li></ul><ul><li>클래스 필드를 위한 Set/Get 메소드를 제공 ( 추천 ) </li></ul><ul><li>equals() 메소드와 hashCode() 메소드 제공 ( 선택 ) </li></ul>영속 클래스 작성법 하이버네이트 기초 사용법
    12. 12. <ul><li><hibernate-mapping> </li></ul><ul><li><class name=&quot;Product&quot; table=&quot;PRODUCT&quot;> </li></ul><ul><li><id name=&quot;id&quot; column=&quot;PRODUCT_ID&quot;> </li></ul><ul><li><generator name=&quot;identity&quot; /> </li></ul><ul><li></id> </li></ul><ul><li><property name=&quot;name&quot; column=&quot;NAME&quot; type=&quot;string&quot; /> </li></ul><ul><li>.... </li></ul><ul><li></class> </li></ul><ul><li></hibernate-mapping> </li></ul><ul><li><class> - 클래스와 테이블의 매핑 설정 </li></ul><ul><ul><li>name – 클래스 이름 , table – 테이블 이름 </li></ul></ul><ul><li><id> - 테이블의 PK 와 매핑될 ( 식별 ) 프로퍼티 매핑 설정 </li></ul><ul><ul><li>name – 프로퍼티 이름 , column – 매핑될 컬럼 이름 </li></ul></ul><ul><ul><li>type – 하이버네이트 매핑 타입 </li></ul></ul><ul><li><generator> - 객체 저장 시 식별 프로퍼티의 값 생성기 설정 </li></ul><ul><li><property> - 객체 프로퍼티와 테이블 컬럼 사이의 매핑 설정 </li></ul><ul><ul><li>name – 프로퍼티 이름 , column – 매핑될 컬럼 이름 </li></ul></ul><ul><ul><li>type – 하이버네이트 매핑 타입 </li></ul></ul>클래스와 테이블 매핑 설정 파일 작성 하이버네이트 기초 사용법
    13. 13. DB 연결 Dialect 설정 매핑파일 설정 <hibernate-configuration> <session-factory> <property name=&quot;hibernate.connection.driver_class&quot;> … </property> <property name=&quot;hibernate.connection.url&quot;>…</property> … <property name=&quot;hibernate.dialect&quot;> org.hibernate.dialect.OracleDialect </property> <mapping resource=&quot;Product.hbm.xml&quot; /> … </session-factory> </hibernate-configuration> 하이버네이트 설정 하이버네이트 기초 사용법
    14. 14. <ul><li>SessionFactory 생성 </li></ul><ul><li>SessionFactory sessionFactory = </li></ul><ul><li>new Configuration().configure().buildSessionFactory(); </li></ul><ul><li>SessionFactory 를 이용하여 Session 참조 </li></ul><ul><li>Session session = sessionFactory.getCurrentSession(); </li></ul><ul><li>Session 을 사용하여 DB 관련 작업 실행 </li></ul><ul><li>session.save(someObject); </li></ul>하이버네이트를 이용한 DB 처리 1 – 세션 초기화 하이버네이트 기초 사용법
    15. 15. <ul><li>Sesstion 이 제공하는 CRUD 관련 메소드 </li></ul>하이버네이트를 이용한 DB 처리 2 – CRUD 처리 하이버네이트 기초 사용법 메서드 설명 Serializable save(Object) 객체를 저장한다 . 저장 시 사용될 키 값을 리턴한다 . void persist(Object) 객체를 저장한다 . Object get(Class, Serializable) 해당 타입의 지정한 키 값을 갖는 객체를 리턴한다 . 존재하지 않을 경우 null 을 리턴 한다 . Object load(Class,Serizliable) 해당 타입의 지정한 키 값에 대한 프록시 객체를 리턴한다 . 프록시 객체는 객체가 실제로 사용될 때 DB 에서 값을 가져온다 . 실세 사용시 DB 에 매핑되는 데이터가 존재하지 않으면 예외를 발생시킨다 . delete(Object) 객체와 매핑되는 테이블의 행을 삭제한다 . update(Object) 객체의 변경된 값을 DB 에 반영한다 .
    16. 16. <ul><li>객체 저장 </li></ul><ul><li>Product product = new Product(); </li></ul><ul><li>... </li></ul><ul><li>Integer newId = (Integer) session.save(product); </li></ul><ul><li>객체 로딩 </li></ul><ul><li>Integer id = new Integer(20); </li></ul><ul><li>Product product = (Product) sesstion.get(Product.class), id); </li></ul><ul><li>if (product != null) { </li></ul><ul><li>... </li></ul><ul><li>} </li></ul><ul><li>... </li></ul><ul><li>객체 삭제 </li></ul><ul><li>sesstion.delete(abuseArticle); </li></ul>CRUD 관련 사용 예 하이버네이트 기초 사용법
    17. 17. 세션에서 로딩한 객체의 프로퍼티가 변경될 경우 , 트랜잭션 커밋 시 자동으로 변경된 내역이 DB 에 반영 <ul><li>세션 범위 내에서 변경된 객체의 값은 자동으로 DB 에 반영된다 . </li></ul><ul><li>코드에서 변경된 값을 반영하기 위해 별도의 코드를 작성할 필요 없음 </li></ul><ul><li>tx = session.beginTransaction(); </li></ul><ul><li>Order order = (Order)session.get(Order.class, orderId); </li></ul><ul><li>order.setState(OrderState.CANCEL); </li></ul><ul><li>… </li></ul><ul><li>tx.commit(); </li></ul>영속성 처리의 투명함 (Transparent Persistence) 하이버네이트 기초 사용법
    18. 18. <ul><li>객체 (Entity) 타입 </li></ul><ul><li>고유의 식별값을 갖는다 . </li></ul><ul><li>부모 객체가 삭제된다고 해서 반드시 삭제되는 것은 아니다 . </li></ul><ul><li>여러 객체에 의해 공유될 수 있다 . </li></ul><ul><li>값 (Value) 타입 </li></ul><ul><li>고유의 식별값을 갖지 않는다 . </li></ul><ul><li>부모 객체가 삭제되면 함께 삭제된다 . </li></ul><ul><li>여러 객체에 공유되지 않는다 . </li></ul><ul><li>예 ) 우편번호 , 주소정보를 담는 Address 클래스 </li></ul>객체 (Entity) 타입과 값 (Value) 타입 객체 지향과 하이버네이트
    19. 19. <ul><li>값 타입에 대한 매핑 지원 </li></ul><ul><li><component> 태그를 이용하여 값 타입에 대한 매핑 지원 </li></ul><ul><li>엔티티 간 매핑 지원 </li></ul><ul><li>1-1, 1-N, N-1, N-M 연관 지원 컬렉션 API 를 통한 1-N, 연관 지원 – Set, List, Map </li></ul><ul><li>컬렉션 테이블을 이용한 1-N, N-1, N-M 연관 지원 </li></ul>객체간 연관 매핑 지원 객체 지향과 하이버네이트
    20. 20. <ul><li><component> 태그를 이용한 컴포넌트 타입 매핑 설정 </li></ul><ul><li><class name=&quot;Employee&quot; table=&quot;EMPLOYEE&quot;> </li></ul><ul><li><component name=&quot;koreanName&quot; class=&quot;Name&quot;> </li></ul><ul><li><property name=&quot;surname&quot; column=&quot;KOR_SURNAME&quot; /> </li></ul><ul><li><property name=&quot;name&quot; column=&quot;KOR_NAME&quot; /> </li></ul><ul><li></compoent> </li></ul><ul><li></class> </li></ul>korName 값 타입 매핑 객체 지향과 하이버네이트
    21. 21. <ul><li><one-to-one> 태그를 이용하여 상호간의 1-1 연관 설정 </li></ul><ul><li><class name=&quot;Employee&quot; table=&quot;EMPLOYEE&quot;> </li></ul><ul><li>… </li></ul><ul><li>< one-to-one name=&quot;detail&quot; class=&quot;EmployeeDetail&quot; … /> </li></ul><ul><li></class> </li></ul><ul><li><class name=&quot;EmployeeDetail&quot; table=&quot;EMPLOYEE_DETAIL&quot;> </li></ul><ul><li><id name=&quot;id&quot; column=&quot;RESUME_ID&quot;> </li></ul><ul><li><generator class=&quot; foreign &quot;> </li></ul><ul><li><param name=&quot;property&quot;>employee</param> </li></ul><ul><li></generator> </li></ul><ul><li></id> </li></ul><ul><li>< one-to-one name=&quot;employee&quot; class=&quot;Employee“ constrained =&quot;true&quot; /> </li></ul><ul><li></class> </li></ul>1-1 연관 : 동일한 키 값 공유 방식 객체 지향과 하이버네이트
    22. 22. <ul><li><many-to-one> 태그를 이용하여 매핑 설정 </li></ul><ul><li><class name=&quot;Comment&quot; table=&quot;COMMENT&quot;> </li></ul><ul><li><id name=&quot;id&quot; column=&quot;ID&quot;> </li></ul><ul><li><generator class=&quot;identity&quot; /> </li></ul><ul><li></id> </li></ul><ul><li>< many-to-one name=&quot;article&quot; class=&quot;Article“ column=&quot;ARTICLE_ID&quot; /> </li></ul><ul><li></class> </li></ul><ul><li><class name=&quot;Article&quot; table=&quot;ARTICLE&quot;> </li></ul><ul><li>… </li></ul><ul><li></class> </li></ul>N-1 연관 객체 지향과 하이버네이트
    23. 23. <ul><li><one-to-one> 과 <many-to-one> 태그를 이용하여 매핑 설정 </li></ul><ul><li><class name=&quot;User&quot; table=&quot;USER&quot;> </li></ul><ul><li>... </li></ul><ul><li><one-to-one name=&quot;resume&quot; class=&quot;Resume&quot; property-ref =&quot;user&quot; … /> </li></ul><ul><li>... </li></ul><ul><li></class> </li></ul><ul><li><class name=&quot;Resume&quot; table=&quot;RESUME&quot;> </li></ul><ul><li>... </li></ul><ul><li>< many-to-one name=&quot;user&quot; class=&quot;User&quot; column=&quot;USER_ID&quot; unique =&quot;true&quot; /> </li></ul><ul><li></class> </li></ul>1-1 연관 : 참조키를 이용한 방식 객체 지향과 하이버네이트
    24. 24. <ul><li>컬렉션 API 를 이용하여 1-N 연관 지원 </li></ul><ul><li>Collection(Bag), Set, List, Map 콜렉션 지원 </li></ul><ul><li><bag>, <set>, <list>, <map> 태그를 이용하여 콜렉션 타입 설정 </li></ul><ul><li><element>, <composite-element>, <one-to-many> 를 이용하여 엘리먼트 , 컴포넌트 , 엔티티에 대한 1-n 관계 설정 </li></ul><ul><li><set> 을 이용한 매핑 설정 예 </li></ul><ul><li><class name=&quot;Item&quot; table=&quot;ITEM&quot;> </li></ul><ul><li>< set name=&quot;bids&quot; table=&quot;BID&quot; > </li></ul><ul><li><key column=&quot;ITEM_ID&quot; /> </li></ul><ul><li>< one-to-many class=&quot;Bid&quot; /> </li></ul><ul><li></set> </li></ul><ul><li></class> </li></ul><ul><li><class name=&quot;Bid&quot; table=&quot;BID&quot;>...</class> </li></ul>컬렉션 프로퍼티를 이용한 1-N 연관 객체 지향과 하이버네이트
    25. 25. <ul><li>기본적으로 영속성 상태의 변화는 연관된 객체에 전파되지 않는다 . </li></ul><ul><li>Order order = new Order(); </li></ul><ul><li>order.addOrderLine(orderLine1); </li></ul><ul><li>session.save(order); // Order 만 저장되고 OrderLine 은 저장되지 않음 </li></ul><ul><li>cascade 속성을 사용하여 연관된 객체에 영속성 변화를 전파한다 . </li></ul><ul><li><class name=&quot;Order&quot; table=&quot;ORDER&quot;> </li></ul><ul><li><set name=&quot;orderLines&quot; cascade=&quot;save-update&quot; > </li></ul><ul><li><key column=&quot;ORDER_ID&quot; /> </li></ul><ul><li><one-to-many class=&quot;OrderLine&quot; /> </li></ul><ul><li></set> </li></ul><ul><li></class> </li></ul><ul><li><class name=&quot;OrderLine&quot; table=&quot;ORDER_LINE&quot;>…</class> </li></ul>엔티티 간 영속성 전이 객체 지향과 하이버네이트
    26. 26. <ul><li>세 가지 방식을 통한 상속 매핑 구현 </li></ul><ul><li>1. 클래스 계층당 1 개의 테이블 매핑 </li></ul><ul><li>매핑이 쉽고 , 성능이 좋다 . </li></ul><ul><li>하위 클래스 프로퍼티와 매핑되는 컬럼의 경우 NOT NULL 로 설정할 수 없다 . </li></ul><ul><li>하위 클래스가 추가시 테이블 변경이 필요하다 . </li></ul><ul><li>2. 클래스 당 1 개의 테이블 매핑 </li></ul><ul><li>데이터가 정규화 된다 . </li></ul><ul><li>계층도가 복잡해지면 성능이 나빠진다 . </li></ul><ul><li>3. 인스턴스 생성 가능한 클래스 당 1 개의 테이블 매핑 </li></ul><ul><li>하위 타입 조회시 조인이 불필요하다 . </li></ul><ul><li>생성기 등 키 값 사용에 제약이 있다 . </li></ul><ul><li>비정규화 되어 있다 . </li></ul>상속 매핑 지원 객체 지향과 하이버네이트
    27. 27. <ul><li>HQL 을 이용한 객체 기반 조회 가능 </li></ul><ul><li>Query query = session.createQuery( </li></ul><ul><li>&quot;from Product p where p.price > :minPrice&quot;); </li></ul><ul><li>query.setInt(&quot;minPrice&quot;, minValue); </li></ul><ul><li>query.setMaxResults(pageSize); </li></ul><ul><li>List productList = query.list(); </li></ul><ul><li>Criteria 를 이용하여 API 를 이용한 객체 기반 조회 가능 </li></ul><ul><li>Criteria crit = session.createCriteria(Product.class); </li></ul><ul><li>crit.add(Restrictions.gt(&quot;price&quot;, minValue)); </li></ul><ul><li>crit.setMaxResults(pageSize); </li></ul><ul><li>List productList = crit.list(); </li></ul>객체에 기반한 쿼리 객체 지향과 하이버네이트
    28. 28. <ul><li>처음부터 하이버네이트의 모든 것을 적용해보려는 욕심은 금물 </li></ul><ul><li>시작은 단순 매핑부터 해야 함 </li></ul><ul><li>예 ) 단순 매핑 방법과 HQL 사용법 습득 후 빠른 개발이 가능했음 </li></ul><ul><li>재사용한 가능한 값 타입을 추가함으로써 모델 정교화 </li></ul><ul><li>하이버네이트 API 가 익숙해지면 아래의 매핑에 대해 적용 </li></ul><ul><li>값 타입에 대한 1-N </li></ul><ul><li>엔티티 타입에 대한 1-1, N-1 연관 </li></ul><ul><li>이후 엔티티 간 1-N, N-M 연관을 적용 </li></ul>하이버네이트 도입 절차 도입 방법 및 맺음말
    29. 29. <ul><li>하이버네이트는 객체 지향 기반 도메인 설계를 도와준다 . </li></ul><ul><li>1. 비즈니스 도메인에 집중할 수 있도록 도와줌 </li></ul><ul><li>퍼시스턴스 영역은 간단한 설정으로 완료 </li></ul><ul><li>2. 모델이 풍부해짐 </li></ul><ul><li>3. 코드의 품질 향상 , 전체 코드 수 감소 </li></ul><ul><li>가독성 향상 , 유지보수 용이성 증가 </li></ul><ul><li>하이버네이트에 대한 오해 </li></ul><ul><li>1. 어렵다 . </li></ul><ul><li>객체 기반의 설계가 어려운 것이지 , 하이버네이트가 어려운 것이 아니다 . </li></ul><ul><li>2. 성능이 나쁘다 . </li></ul><ul><li>성능이 문제가 되는 부분은 전체 코드의 5~10% 에 해당되며 , 1 차 캐시 /2 차 캐시를 통한 성능 향상이 가능 </li></ul><ul><li>전체적인 개발 속도를 향상시키고 , 성능 이슈가 발생하는 곳만 집중하여 해소 가능 </li></ul><ul><li>예 ) 일부 코드는 네이티브 SQL 을 이용하여 쿼리 직접 실행 </li></ul>맺음말 도입 방법 및 맺음말
    30. 30. <ul><li>관련 사이트 </li></ul><ul><li>하이버네이트 - http://www.hibernate.org </li></ul><ul><li>레퍼런스 - http://www.hibernate.org/hib_docs/v3/reference/en/html_single </li></ul><ul><li>위키 - http://www.hibernate.org/37.html </li></ul><ul><li>관련 서적 </li></ul><ul><li>하이버네이트 3 프로그래밍 ( 최범균 , 가메출판사 ) </li></ul><ul><li>Java Persistence API with Hibernate (Christian Bauer 와 Gavin King, Manning) </li></ul><ul><li>Pro EJB 3 Java Persistence API (Mike Keith 와 Merrick Schincariol, APress) </li></ul><ul><li>Domain Driven Design (Eric Evans, Addison-Wesley) </li></ul><ul><li>POJOs in Action (Chris Richardson, Manning) </li></ul>참고 자료 참고자료
    31. 31. 감사합니다 .

    ×