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
저자: 아 이 디 의 탁구 광 마

좋은 웹페이지 즐겨찾기