개발관련/Spring 2015. 12. 17. 11:50

hibernate의 HQL을 알아보자. 

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
32
33
34
35
package com.zest.hibernate.chapter10.crud;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.Table;
 
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
 
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int userId;
    private String userName;
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    
    
}
 
 
cs


위와 같은 테이블을 생성한다. 

먼저 데이터를 insert 한다. 이 부분은 기존에 만들어 놓은 코드를 조금 수정해서 insert를 한다. 


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
 
@Test
    public void insertTest() {
 
        // hibernate의 persitst를 위한 클래스
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(UserDetails.class);
        // db 접속 정보들을 저장.
        config.configure("hibernate.cfg.xml");
 
        // db 접속후 여러개의 테이블을 자동으로 제너레이트 해주는 객체.
        // <property name="hibernate.default_schema">TESTSCHEMA</property> 이구문역시
        // 마찬가지임.
        new SchemaExport(config).create(truetrue);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        for (int i = 0; i < 10; i++) {
            UserDetails user = new UserDetails();
            user.setUserName("user " + i);
            session.save(user);
        }
 
        session.getTransaction().commit();
        // session.close();
    }
cs


user0, user1 ...........  이런 user를 총 10개를 만들었다. 그럼 기존에 사용했던 방식으로 select의 결과물을 가져와보자. 


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
@Test
    public void getTest() {
 
        // hibernate의 persitst를 위한 클래스
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(UserDetails.class);
        // db 접속 정보들을 저장.
        config.configure("hibernate.cfg.xml");
 
        // db 접속후 여러개의 테이블을 자동으로 제너레이트 해주는 객체.
        // <property name="hibernate.default_schema">TESTSCHEMA</property> 이구문역시
        // 마찬가지임.
//        new SchemaExport(config).create(true, true);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        
        UserDetails user = (UserDetails) session.get(UserDetails.class6); 
        System.out.println("name\t"+user.getUserName());
 
        session.getTransaction().commit();
//         session.close();
    }
cs


session.get이라는 함수를 통해 파라미터로 어느 테이블(객체), 기본키를 넣어서 값을 가져오는 예제이다. 


그럼 hql를 해보자. 

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
@Test
    public void hsqlTest1() {
 
        // hibernate의 persitst를 위한 클래스
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(UserDetails.class);
        // db 접속 정보들을 저장.
        config.configure("hibernate.cfg.xml");
 
        // db 접속후 여러개의 테이블을 자동으로 제너레이트 해주는 객체.
        // <property name="hibernate.default_schema">TESTSCHEMA</property> 이구문역시
        // 마찬가지임.
//        new SchemaExport(config).create(true, true);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        //hibernate 용으로. 
        Query query=  session.createQuery("from UserDetails");
        List users = query.list();
        
 
        session.getTransaction().commit();
//         session.close();
        System.out.println("list size==>"+users.size());
    }
cs


위의 내용은 전체 리스트를 가져오는 예제이다. 이때 중요한 메소드는 createQuery라는 메소드인데 이 뒤는 sql문과 매우 흡사하다. 여기서 중요한 점은 UserDetails는 table명이 아니라 객체 라는 점이다. jpa에서는 jpa ql 이라는 것과 거의 비슷하게 맵핑이 될것이다. 


한개더 예제를 해보자. 


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
@Test
    public void hsqlWhereTest() {
 
        // hibernate의 persitst를 위한 클래스
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(UserDetails.class);
        // db 접속 정보들을 저장.
        config.configure("hibernate.cfg.xml");
 
        // db 접속후 여러개의 테이블을 자동으로 제너레이트 해주는 객체.
        // <property name="hibernate.default_schema">TESTSCHEMA</property> 이구문역시
        // 마찬가지임.
//        new SchemaExport(config).create(true, true);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        //hibernate 용으로. 
        Query query=  session.createQuery("from UserDetails where userId >5");
        List users = query.list();
        
 
        session.getTransaction().commit();
//         session.close();
        System.out.println("list size==>"+users.size());
    }
cs


위의 예제는 where절이 추가 되었으며 마찬가지로 UserDetails의 멤버 변수의 값을 5보다 큰 값을 가져오는 예제이다. 

이번엔 게시판 또는 그리드에서 많이 쓰는 paging에 대해 보자. 

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
32
33
34
35
@Test
    public void hsqlpageingTest2() {
 
        // hibernate의 persitst를 위한 클래스
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(UserDetails.class);
        // db 접속 정보들을 저장.
        config.configure("hibernate.cfg.xml");
 
        // db 접속후 여러개의 테이블을 자동으로 제너레이트 해주는 객체.
        // <property name="hibernate.default_schema">TESTSCHEMA</property> 이구문역시
        // 마찬가지임.
//        new SchemaExport(config).create(true, true);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        //hibernate 용으로. 
        Query query=  session.createQuery("from UserDetails ");
        //시작 row를 설정. 
        query.setFirstResult(5);
        //결과 개수
        query.setMaxResults(4);
        
        List<UserDetails> users = (List<UserDetails>)query.list();
        
 
        session.getTransaction().commit();
//         session.close();
        for(UserDetails u : users){
            System.out.println(u.getUserName());
        }
    }
cs


setFirstResult 메소드와 setMaxResults가 추가 되었다. 이 메소드를 이용해 paging을 쉽게 구현할 것이다. 


이번엔 preparedstatement와 비슷한 binding에 대해 알아보자. 

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
32
33
34
@Test
    public void hsqlBindingTest2() {
 
        // hibernate의 persitst를 위한 클래스
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(UserDetails.class);
        // db 접속 정보들을 저장.
        config.configure("hibernate.cfg.xml");
 
        // db 접속후 여러개의 테이블을 자동으로 제너레이트 해주는 객체.
        // <property name="hibernate.default_schema">TESTSCHEMA</property> 이구문역시
        // 마찬가지임.
//        new SchemaExport(config).create(true, true);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        String minUserId= "5";
        //hibernate 용으로.
        
        
        Query query=  session.createQuery("from UserDetails where userId > ?");
        query.setInteger(0, Integer.parseInt(minUserId));
        List<UserDetails> users = (List<UserDetails>)query.list();
        
 
        session.getTransaction().commit();
//         session.close();
        for(UserDetails u : users){
            System.out.println(u.getUserName());
        }
    }
cs


hql에 ? 라는 바인딩 변수가 있다. 이 값을 setInteger로 바인딩 하는 메소드를 추가하고 리스트를 가져오는 예제이다. preparedstatement와 매우 흡사하다. 


여기까지 하이버네이트는 끝낸다. 


모든 예제는 https://github.com/zest133/hibernateTest.git 에서 있다. 



posted by 제스트
:
개발관련/Spring 2015. 12. 7. 17:57

다대다에 대해서 알아보자. 


바로 소스 공개...

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.zest.hibernate.chapter8.manytomanymapping;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
 
@Entity
public class Delegate {
 
    
    private int delegateId;
    private String delegateName;
    private List<Event> events = new ArrayList<Event>();
 
    
    @Id
    @GeneratedValue
    public int getDelegateId() {
        return delegateId;
    }
 
    public void setDelegateId(int delegateId) {
        this.delegateId = delegateId;
    }
 
    public String getDelegateName() {
        return delegateName;
    }
 
    public void setDelegateName(String delegateName) {
        this.delegateName = delegateName;
    }
 
    // 결과를 담을 테이블명을 정의 .
    @ManyToMany
    @JoinTable(name = "JOIN_DELEGATE_EVENT", joinColumns = { @JoinColumn(name = "delegateId") }, inverseJoinColumns = { @JoinColumn(name = "eventId") }    )
    public List<Event> getEvents() {
        return events;
    }
 
    public void setEvents(List<Event> events) {
        this.events = events;
    }
 
}
 
cs



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 
package com.zest.hibernate.chapter8.manytomanymapping;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
 
@Entity
public class Event {
 
    
    private int eventId;
    private String eventName;
    private List<Delegate> delegates = new ArrayList<Delegate>();
 
    @Id
    @GeneratedValue
    public int getEventId() {
        return eventId;
    }
 
    public void setEventId(int eventId) {
        this.eventId = eventId;
    }
 
    public String getEventName() {
        return eventName;
    }
 
    public void setEventName(String eventName) {
        this.eventName = eventName;
    }
 
    @ManyToMany
    @JoinTable(name = "JOIN_DELEGATE_EVENT", joinColumns = { @JoinColumn(name = "eventId") }, inverseJoinColumns = { @JoinColumn(name = "delegateId") })
    public List<Delegate> getDelegates() {
        return delegates;
    }
 
    public void setDelegates(List<Delegate> delegates) {
        this.delegates = delegates;
    }
 
}
 
cs


두개의 객체를 선언하였다. 여기도 마찬가지로 새로운 어노테이션이 등장한다. 

@ManyToMany 이다. 그리고 JoinColumn이 아닌 JoinTable이다. 

@ManyToMany는 두개의 객체 두군데 다 선언을 한다. 그리고 필연적으로 @JoinTable을 사용해야한다. 각 속성을 알아보자. name은 m:n에 대한 데이터를 저장하는 테이블 이며, jonColumns와 inverseJoinColumkns가 존재한다. joinColumns는 join이 되는 컬럼 여기선 상호간의 컬럼 아이디를 써준다. 



결과 쿼리를 보자. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
Hibernate: insert into TESTSCHEMA.Delegate (delegateName, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Delegate (delegateName, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Delegate (delegateName, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Delegate (delegateName, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Event (eventName, eventId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Event (eventName, eventId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Event (eventName, eventId) values (?, ?)
Hibernate: insert into TESTSCHEMA.JOIN_DELEGATE_EVENT (eventId, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.JOIN_DELEGATE_EVENT (eventId, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.JOIN_DELEGATE_EVENT (eventId, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.JOIN_DELEGATE_EVENT (eventId, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.JOIN_DELEGATE_EVENT (eventId, delegateId) values (?, ?)
Hibernate: insert into TESTSCHEMA.JOIN_DELEGATE_EVENT (eventId, delegateId) values (?, ?)
cs


JOIN_DELEGATE_EVENT 테이블 생성되며 각 각의 정보가 m:n으로 맵핑이 된다.


하이버네이트 모든 코드는 https://github.com/zest133/hibernateTest.git 여기에 저장되어 있다.

posted by 제스트
:
개발관련/Spring 2015. 12. 7. 13:32

이번엔 1:N 관계를 살펴보자. 


바로 소스를 보자. 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.zest.hibernate.chapter7.onetomanymapping;
 
import java.util.List;
 
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
 
@Entity
public class College {
 
    @Id
    @GeneratedValue
    private int collegeId;
    private String collegeName;
    
    @OneToMany(targetEntity=Student.class, mappedBy="college"
            ,cascade= CascadeType.ALL,fetch=FetchType.EAGER)
    private List<Student> students ;
    
    
    public int getCollegeId() {
        return collegeId;
    }
    public void setCollegeId(int collegeId) {
        this.collegeId = collegeId;
    }
    public String getCollegeName() {
        return collegeName;
    }
    public void setCollegeName(String collegeName) {
        this.collegeName = collegeName;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    
    
}
 
cs



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
32
33
34
35
36
37
38
39
40
41
42
43
 
package com.zest.hibernate.chapter7.onetomanymapping;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
 
@Entity
public class Student {
 
    @Id
    @GeneratedValue
    private int studentId;
    private String studentName;
    
    @ManyToOne
    @JoinColumn(name="college_id")
    private College college;
    
    public int getStudentId() {
        return studentId;
    }
    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }
    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
    public College getCollege() {
        return college;
    }
    public void setCollege(College college) {
        this.college = college;
    }
    
    
}
 
cs


몇가지 새로운 어노테이션이 등장했다. @OneToMany, @ManyToOne

OneToMany가 선언되있는 클래스는 One을 지칭하고 targetEntity는 many가 된다. 


mappedBy는 One에 속하는 테이블 명을 써주면 된다. 

Student 객체는 ManyToOne을 선언하고 JoinColumn의 컬럼 명을 정의해주면 된다. 


그럼 테스트 ㄱㄱ

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
package com.zest.hibernate.chapter7.onetomanymapping;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;
 
import com.zest.hibernate.chapter5.inheritancemapping.Module;
import com.zest.hibernate.chapter5.inheritancemapping.Project;
import com.zest.hibernate.chapter5.inheritancemapping.Task;
 
public class OneToManyTest {
 
    @Test
    public void oneTest(){
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(College.class);
        config.addAnnotatedClass(Student.class);
        config.configure("hibernate.cfg.xml");
        
        new SchemaExport(config).create(truetrue);
 
        // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤.
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
 
        session.beginTransaction();
        
        College college1 = new College();
        college1.setCollegeName("Newyork College");
        
        Student s1 = new Student();
        s1.setStudentName("Alex Rod");
        
        Student s2 = new Student();
        s2.setStudentName("Linda Berry");
        
        s1.setCollege(college1);
        s2.setCollege(college1);
        
        session.save(college1);
        session.save(s1);
        session.save(s2);
        //session.save(alexdetail); 이건 안함. 카스케이드 라서 
        session.getTransaction().commit();
        
        
    }
}
 
cs


결과는 다음과 같다. 

1
2
3
4
 
Hibernate: insert into TESTSCHEMA.College (collegeName, collegeId) values (?, ?)
Hibernate: insert into TESTSCHEMA.Student (college_id, studentName, studentId) values (?, ?, ?)
Hibernate: insert into TESTSCHEMA.Student (college_id, studentName, studentId) values (?, ?, ?)
cs


예상했던 대로 College_ID는 FK로 셋팅이 된다. 



posted by 제스트
: