hibenate 시리즈 (3) 다 중 관계
Teacher 와 Student 를 예 로 들 면 그들 사 이 는 다 대 다 의 관계 다.수 동 으로 만 든 데이터베이스 의 세 장의 표 는 "teacher, student, teacher" 입 니 다.student。각각 다음 과 같다.
CREATE TABLE `teacher` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `teacher_student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`teacher_id` int(11) DEFAULT NULL,
`student_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Teacher 클래스 는 다음 과 같 습 니 다.
public class Teacher {
private Long id;
private String name;
private Set students;
// get、set
}
Teacher 클래스 에 대응 하 는 맵 파일 Teacher. hbm. xml:
그 중에서 set 태그 의 name 은 Teacher 류 의 students 속성 을 말 하 는데 table 은 이 속성 이 어떤 표 와 연결 되 어야 하 는 지 를 말 합 니 다.내부 키 탭 의 column 은 해당 Teacher 클래스 가 속 한 테이블 의 주 키 id 를 teacher 로 말 합 니 다.student 의 외 키 teacherid 값.라벨 은 Student 류 가 속 한 student 표 의 메 인 키 를 teacher 로 하 는 것 을 말 합 니 다.student 표 의 studentid 값.Stusent 클래스 는 다음 과 같 습 니 다:
public class Student {
private Long id;
private String name;
private Set teachers;
// get、set
}
Student 클래스 에 대응 하 는 맵 파일 Student. hbm. xml 는 다음 과 같 습 니 다.
그 중의 set 맵 관 계 는 같 습 니 다.그리고 추가 방법 을 살 펴 보 자.
@Test
public void testAddTeacher1(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();
Teacher t=new Teacher();
t.setName("teacher4");
Student s1=new Student();
s1.setName("assa");
Student s2=new Student();
s2.setName("sdfvdv");
Set students=new HashSet();
students.add(s1);
students.add(s2);
t.setStudents(students);
session.save(s1);
session.save(s2);
session.save(t);
tx.commit();
session.close();
}
세 개의 save, 세 개의 insert 문 구 를 동시에 t. setStudents (students) 때문에 teacher 는 teacher 를 지 킵 니 다.student 관계 표, 그래서 두 개의 insert 문 구 를 추가 합 니 다. sql 은 다음 과 같 습 니 다.
Hibernate: insert into hibernate.student (name) values (?)
Hibernate: insert into hibernate.student (name) values (?)
Hibernate: insert into hibernate.teacher (name) values (?)
Hibernate: insert into hibernate.teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into hibernate.teacher_student (teacher_id, student_id) values (?, ?)
다음 상태 로 추가 하면:
@Test
public void testAddTeacher(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();
Teacher t=new Teacher();
t.setName("teacher4");
Student s1=new Student();
s1.setName("assa");
Student s2=new Student();
s2.setName("sdfvdv");
Set students=new HashSet();
Set teachers=new HashSet();
students.add(s1);
students.add(s2);
teachers.add(t);
t.setStudents(students);
s1.setTeachers(teachers);
s2.setTeachers(teachers);
session.save(s1);
session.save(s2);
session.save(t);
tx.commit();
session.close();
}
이때 t. setStudents (students) 관 계 를 맺 었 을 뿐만 아니 라 s1. setTeachers (teachers) 도 맺 었 다.s2.setTeachers(teachers);관 계 를 맺 었 기 때문에 최종 사 무 를 제출 할 때 teacher, student 은 teacher 를 지 킵 니 다.student 표 는 4 개의 insert 문 구 를 만들어 중복 되 었 습 니 다.다음 과 같다.
Hibernate: insert into hibernate.student (name) values (?)
Hibernate: insert into hibernate.student (name) values (?)
Hibernate: insert into hibernate.teacher (name) values (?)
Hibernate: insert into hibernate.teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into hibernate.teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into hibernate.teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into hibernate.teacher_student (teacher_id, student_id) values (?, ?)
이러한 현상 을 피하 기 위해 서 는 어느 한 쪽 이 teacher 를 지 키 는 것 을 포기 해 야 합 니 다.student 표 의 권한.학생 이 이 관 계 를 유지 하 는 것 을 포기 할 경우 inverse = "true" 를 사용 합 니 다. 다음 과 같 습 니 다.
이때 상기 방법 에 따라 추가 하면 teacher 만 teacherstudent 표 입 니 다. 중복 되 지 않 습 니 다.다 중 관련 관계 에 대한 조 회 를 살 펴 보 자.
@Test
public void getTeacher(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();
Teacher t=(Teacher) session.get(Teacher.class,3L);
System.out.println(t.getName());
System.out.println(t.getStudents().size());
tx.commit();
session.close();
}
여기에 도 이 조회 정책 문제 가 존재 합 니 다. 이때 Teacher 류 의 맵 파일 에 대응 하 는 set 태그 의 lazy 속성 은 세 개의 값 이 있 습 니 다. 하 나 는 true, false, extra 입 니 다.기본 값 은 true 입 니 다. 로 딩 지연 정책 을 실행 하고 Student 를 사용 할 때 다시 불 러 옵 니 다. 다음 sql:
Hibernate: select teacher0_.id as id1_3_0_, teacher0_.name as name2_3_0_ from hibernate.teacher teacher0_ where teacher0_.id=?
teacher2
Hibernate: select students0_.teacher_id as teacher_1_3_0_, students0_.student_id as student_2_4_0_, student1_.id as id1_2_1_, student1_.name as name2_2_1_ from hibernate.teacher_student students0_ inner join hibernate.student student1_ on students0_.student_id=student1_.id where students0_.teacher_id=?
2
false 로 설정 하면 Teacher 를 불 러 올 때 관련 Student 를 즉시 불 러 오 는 것 을 의미 합 니 다. 다음 sql:
Hibernate: select teacher0_.id as id1_3_0_, teacher0_.name as name2_3_0_ from hibernate.teacher teacher0_ where teacher0_.id=?
Hibernate: select students0_.teacher_id as teacher_1_3_0_, students0_.student_id as student_2_4_0_, student1_.id as id1_2_1_, student1_.name as name2_2_1_ from hibernate.teacher_student students0_ inner join hibernate.student student1_ on students0_.student_id=student1_.id where students0_.teacher_id=?
teacher2
2
extra 로 설정 하면 더욱 스마트 화 됩 니 다. 즉, 상기 t. getStudents (). size () 는 Student 의 실제 내용 을 방문 하지 않 고 수량 만 얻 으 려 고 하기 때문에 sql 문 구 는 다음 과 같 습 니 다.
Hibernate: select teacher0_.id as id1_3_0_, teacher0_.name as name2_3_0_ from hibernate.teacher teacher0_ where teacher0_.id=?
teacher2
Hibernate: select count(student_id) from hibernate.teacher_student where teacher_id =?
2
업 데 이 트 된 Teacher:
@Test
public void updateTeacher(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();
Teacher t=(Teacher) session.get(Teacher.class,6L);
Student s1=new Student();
s1.setName("assa");
Student s2=new Student();
s2.setName("sdfvdv");
Set students=new HashSet();
students.add(s1);
students.add(s2);
t.setStudents(students);
session.save(s1);
session.save(s2);
tx.commit();
session.close();
}
업데이트 시 이전 teacher 를 먼저 삭제 합 니 다.student 표 의 관련 기록 을 추가 한 다음 에 새로운 기록 을 추가 합 니 다. 다음 sql:
Hibernate: select teacher0_.id as id1_3_0_, teacher0_.name as name2_3_0_ from hibernate.teacher teacher0_ where teacher0_.id=?
Hibernate: insert into hibernate.student (name) values (?)
Hibernate: insert into hibernate.student (name) values (?)
Hibernate: delete from hibernate.teacher_student where teacher_id=?
Hibernate: insert into hibernate.teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into hibernate.teacher_student (teacher_id, student_id) values (?, ?)
전재 하려 면 출처 를 밝 혀 주 십시오.http://lgbolgger.iteye.com/blog/2125014
저자: 아 이 디 의 탁구 광 마
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA 및 PostgreSQL 텍스트다음은 의 친구들과 논의한 후 오랫동안 초안으로 작성한 블로그 게시물이며 ( ) 주제에 대한 훌륭한 기사를 작성했기 때문에 여기에 작은 테스트를 게시하고 있습니다. JPA 주석 없이 String를 선언합니다. 재현하...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.