Hibernate 독서 노트 - Hibernate 의 관련 맵 1 - N 관련 맵

13802 단어 Hibernate
셋, 하나 - N
1 - N 의 경우 지구 화 류 에 약간의 변화 가 생 겼 고 지구 화 류 에 서 는 집합 속성 을 사용 해 야 합 니 다.1 의 한쪽 은 N 의 한쪽 에 접근해 야 하고, N 의 한쪽 은 집합 (Set) 으로 표현 되 기 때문이다.
1. 단 방향 1 - N 연결
단 방향 1 - N 관련 관계 에 대해 서 는 1 의 한 끝 에 set 형식의 속성 을 추가 하고 이 속성 은 현재 실체의 관련 실 체 를 기록 합 니 다.
마찬가지 로 직원 - 부 서 를 예 로 들 면 (Employee - > Department).두 개의 지구 화 종 류 는 다음 과 같다.
Department
public class Department {
	private Integer id;
	private String name;
	private Set<Employee> employees;          //    

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<Employee> getEmployees() {
		return employees;
	}

	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}

}

Employee
public class Employee {
	private Integer id;
	private String name;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

1.1 연결 표 없 는 단 방향 1 - N 연결 기반
1 - N 의 단 방향 연결 에 대해 서 는 1 의 한 끝 에 대응 하 는 집합 맵 요 소 를 추가 해 야 합 니 다. 예 를 들 어 < set... / >, < bag... / >.집합 요소 에 < key... / > 하위 요 소 를 추가 해 야 합 니 다. 이 하위 요 소 는 외부 키 를 매 핑 하 는 데 사 용 됩 니 다.동시에 집합 요소 중 < one - to - many... / > 요 소 를 사용 하여 1 - N 관련 관 계 를 매 핑 해 야 합 니 다.
다음은 Department 의 맵 파일 Department. hbm. xml 입 니 다.
<hibernate-mapping package="com.hibernate.domain" >
	<class name="Department" table="department">
		<id name="id" column="departmentID">
			<generator class="native" />
		</id>
		
		<property name="name" column="departmentName" />
		
		<!--        -->
		<set name="employees" inverse="true" >
		    <!--          -->
			<key column="departmentID" />
			<!--            -->
			<one-to-many class="Employee"/>
		</set>	
	</class>
</hibernate-mapping>

위의 맵 파일 에 대해 < set... / > 요 소 를 매 핑 할 때 캐 스 케 이 드 속성 을 지정 하지 않 았 습 니 다. 기본 적 인 상황 에서 메 인 표 실체 에 대한 지속 화 작업 은 표 실체 로 연결 되 지 않 습 니 다.
Employee.hbm.xml
<hibernate-mapping package="com.hibernate.domain">
	<class name="Employee" table="employee">
		<id name="id" column="employeeID">
			<generator class="native" />
		</id>
		<property name="name" column="employeeName" />    
	</class>
</hibernate-mapping>

Department 와 Employee 실 체 를 다음 코드 로 조작 합 니 다. Department 실체 하나 와 Employee 실 체 를 저장 합 니 다.
static void add(){
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		Department department = new Department();
		department.setName("   ");
		
		//      
		Employee employee1 = new Employee();
		employee1.setName("chentmt1");
		
		Employee employee2 = new Employee();
		employee2.setName("chentmt2");

		Set<Employee> emps = new HashSet<Employee>();
		emps.add(employee1);
		emps.add(employee2);
		
		//  Department Employee       
		department.setEmployees(emps);       
	
		session.save(department);          //....1
		session.save(employee2);
		session.save(employee1);
		tx.commit();
		session.close();
	}

위 코드 세그먼트 분석:
프로그램 이................................................................................이때 Hibernate 는 두 가지 일 을 완성 해 야 합 니 다.
1. insert 문 구 를 실행 하고 depart. ment 표 에 기록 을 삽입 하려 고 합 니 다.
2. Hibernate 는 update 문 구 를 실행 하려 고 합 니 다. 현재 depart. ment 표 에 연 결 된 employee 표 에 기 록 된 외 키 depart. ment ID 를 이 depart. ment 에 기 록 된 메 인 키 의 값 으로 변경 합 니 다.
다음은 위의 코드 세그먼트 의 sql 문 구 를 위 한 것 입 니 다.
Hibernate: insert into department (departmentName) values (?)

Hibernate: insert into employee (employeeName) values (?)

Hibernate: insert into employee (employeeName) values (?)

Hibernate: update employee set departmentID=? where employeeID=?

Hibernate: update employee set departmentID=? where employeeID=?


위의 sql 문 구 를 통 해 알 수 있 듯 이 프로그램 은 Department 실체 에 관련 Employee 실 체 를 추가 해 야 하지만 Hibernate 는 두 개의 SQL 문 구 를 사용 하여 완성 합 니 다. 하나의 inset 문 구 는 null 의 employee 기록 을 삽입 하고 하나의 update 문 구 는 삽 입 된 employee 기록 을 수정 합 니 다.이 문 제 를 일 으 킨 근본 적 인 원인 은 Department 에서 Employee 까지 의 관련 이 Department 대상 상태의 일부분 이 아니 기 때문이다.
이 문 제 를 해결 하기 위해 서 는 프로그램 이 Employee 실 체 를 지속 화하 기 전에 Employee 실체 가 관련 된 Department 실 체 를 알 수 있 도록 해 야 합 니 다. 즉, employee. setDepartment (department) 를 통 해.방법 은 연관 관 계 를 맺 지만 이때 이미 1 - N 의 쌍방 향 연관 이 되 었 다.따라서 1 - N 의 단 방향 연결 을 최소 화하 고 1 - N 의 양 방향 연결 로 바꾼다.
1.2 연결 표 가 있 는 단 방향 1 - N 연결 기반
연결 표 가 있 는 1 - N 관련 맵 에 대해 맵 파일 은 < one - to - many... / > 요소 맵 관련 실 체 를 사용 하지 않 고 < many - to - many... / > 요 소 를 사용 합 니 다. 그러나 현재 실체 가 1 의 한 끝 임 을 보장 하기 위해 서 는 속성 을 추가 해 야 합 니 다: 유 니 크 = "true".
그래서 Department. hbm. xml 프로필 은 다음 과 같 습 니 다.
<hibernate-mapping package="com.hibernate.domain" >
	<class name="Department" table="department">
		<id name="id" column="departmentID">
			<generator class="native" />
		</id>
		<property name="name" column="departmentName" />
		
		<set name="employees" inverse="true" table="department_employee">
		    <!--          -->
			<key column="departmentID" />
			<!--            -->
			<many-to-many class="Employee" column="employeeID" unique="true"/>
		</set>
	</class>
</hibernate-mapping> 

Employe. hbm. xml 프로필 이 변 하지 않 습 니 다.
만약 에 우리 가 여전히 조작 방법 을 사용한다 면 Department 하나, Employee 두 개 를 저장 합 니 다. 이때 시스템 은 5 개의 sql 문 구 를 만들어 야 합 니 다.이 중 두 가 지 는 연결 표 에 기록 을 삽입 하여 Department 와 Employee 간 의 관 계 를 맺 는 데 사용 된다.
2. 쌍방 향 1 - N 관련
1 - N 연결 에 대해 서 는 하 이 버 네 이 트 가 양 방향 연결 을 추천 하 며, 1 단 으로 연결 관 계 를 제어 하지 못 하 게 하고 N 의 한쪽 으로 연결 관 계 를 제어 하 는 것 을 권장 합 니 다.
양 방향 1 - N 관련, 양 끝 모두 관련 속성 에 대한 접근 을 증가 해 야 합 니 다. N 의 한 끝 은 관련 실체 에 인 용 된 속성 을 증가 하고 1 의 한 끝 은 집합 속성 을 증가 하 며 집합 요 소 는 관련 실체 입 니 다.
두 개의 지구 화 류 와 위 에 차이 가 많 지 않 습 니 다. Employee 에서 Department 에 대한 인용 속성 을 추가 하면 됩 니 다.
2.1 연결 표 없 는 양 방향 1 - N 연결
연결 표 가 없 는 양 방향 1 - N 연결.N 의 한쪽 끝 은 < many - to - one... / > 요 소 를 추가 하여 관련 속성 을 매 핑 해 야 하 며, 1 의 한쪽 끝 은 < set... / > 또는 < bag... / > 요 소 를 사용 하여 관련 속성 을 매 핑 해 야 합 니 다.또한 < set... / > 또는 < bag.. / > 요 소 는 < key... / > 하위 요소 맵 외 키 열 을 추가 하고 < one - to - many... / > 하위 요소 맵 관련 속성 을 사용 해 야 합 니 다.
앞에서 언급 했 듯 이 1 - N 관련 맵 은 보통 1 의 한 끝 이 관련 관 계 를 통제 하 는 것 을 제창 하지 않 고 N 의 한 끝 이 관련 관 계 를 통제 해 야 한다.이 때 우 리 는 < set... / > 요소 에서 inverse = "true" 를 지정 할 수 있 습 니 다. 1 의 한 끝 을 지정 하여 관련 관 계 를 제어 하지 않 습 니 다.
Department 맵 파일: Department. hbm. xml
<hibernate-mapping package="com.hibernate.domain" >
	<class name="Department" table="department">
		<id name="id" column="departmentID">
		     <generator class="native" />
		</id>
		<property name="name" column="departmentName" />
		<!--        -->
		<set name="employees" inverse="true" >
		    <!--          -->
			<key column="departmentID" />
			<!--            -->
			<one-to-many class="Employee"/>
		</set>	
	</class>
</hibernate-mapping>

Employee 맵 파일: Employee. hbm. xml
<hibernate-mapping package="com.hibernate.domain">
	<class name="Employee" table="employee">
		<id name="id" column="employeeID">
			<generator class="native" />
		</id>
		<property name="name" column="employeeName" />
		<!--     N-1    ,         :Department,     :departmentID-->
		<many-to-one name="department" column="departmentID" />    
	</class>
</hibernate-mapping>

다음 프로그램 은 Department 대상 하나 와 Employee 대상 두 개 를 저장 하 는 데 사 용 됩 니 다.
	static void add(){
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		Department department = new Department();
		department.setName("   ");
		
		//      
		Employee employee1 = new Employee();
		employee1.setName("chentmt1");
		employee1.setDepartment(department);      //           
		
		Employee employee2 = new Employee();
		employee2.setName("chentmt2");
		employee2.setDepartment(department);      //           
      
		session.save(department);          //....1
		session.save(employee2);
		session.save(employee1);
		tx.commit();
		session.close();
	}

SQL 구문:
Hibernate: insert into department (departmentName) values (?)

Hibernate: insert into employee (employeeName, departmentID) values (?, ?)

Hibernate: insert into employee (employeeName, departmentID) values (?, ?)


위의 SQL 문 구 를 통 해 알 수 있 듯 이 Hibernate 는 어떤 선 insert 후 update 방식 으로 employee 기록 을 삽입 하 는 것 이 아 닙 니 다.insertSQL 문 구 를 통 해 실 행 됩 니 다.왜?프로그램 이 Employee 실 체 를 지속 하기 전에 Employee 는 관련 Department 실체 (employee 2. setDepartment (department) 를 알 고 있 었 기 때 문 입 니 다.따라서 비교적 좋 은 성능 을 확보 하기 위해 다음 과 같은 두 가지 문 제 를 주의해 야 한다.
1. 메 인 테이블 대상: Department.프로그램 이 표: Employee 대상 에서 오래 지속 되 기 를 바 랄 때 Hibernate 는 그의 외부 키 속성 값 을 할당 할 수 있 기 때 문 입 니 다.
2. 두 개의 지구 화 클래스 (Department 와 Employee) 의 관 계 를 설정 한 다음 에 표 대상 (Employee) 에서 지구 화 를 저장 합 니 다.순서 가 뒤 바 뀌 면 프로그램 이 Employee 대상 을 영구 화 할 때 해당 대상 은 아직 실체 와 관련 이 없 기 때문에 Hibernate 는 기 록 된 외 키 열 에 값 을 지정 할 수 없 으 며, 관련 관 계 를 설정 할 때 까지 Hibernate 는 update 문 구 를 다시 사용 하여 수정 할 수 밖 에 없습니다.
2.2 연결 표 의 양 방향 1 - N 연결
연결 표 의 양 방향 1 - N 연결 이 있 습 니 다.1 의 한쪽 은 집합 요소 맵 을 사용 한 다음 집합 요소 에 < many - to - many.. / > 하위 요 소 를 추가 합 니 다. 이 하위 요 소 는 관련 클래스 에 매 핑 됩 니 다.이 실체 가 1 의 한 끝 임 을 보장 하기 위해 서 는 유 니 크 = "true" 속성 을 추가 해 야 합 니 다.N 의 한쪽 은 < join... / > 요 소 를 사용 하여 연결 표를 강제로 사용 합 니 다.
N 의 한쪽 끝 에 < join.. / > 요 소 를 사용 하여 연결 표를 강제로 사용 하기 때문에 < key... / > 하위 요 소 를 사용 하여 연결 표 의 외부 키 열 을 매 핑 하고 < many - to - one.. / > 를 사용 하여 연결 표 에 연 결 된 실체의 외부 키 열 을 매 핑 합 니 다.반대로 1 의 한 끝 도 < set... / > 요소 에서 < key... / > 와 < many - to - many... / > 두 개의 키 요 소 를 사용 합 니 다. 그들 도 연결 표 의 두 열 에 비 칩 니 다.정확 한 매 핑 관 계 를 확보 하기 위해 서 는 다음 과 같은 관 계 를 만족 시 켜 야 합 니 다. < join... / > 에서 < key... / > 하위 요소 의 column 속성 과 < set... / > 에서 < man - to - many... / > 요소 의 column 속성 이 같 습 니 다. 에 있 는 < many - to - many... / > 하위 요소 의 column 속성 과 < set.. / > 요소 의 < key.. / > 하위 요소 의 column 속성 은 같 아야 합 니 다.
다음은 Department 와 Employee 두 개의 지구 화 된 맵 파일 입 니 다.
Department.hbm.xml
<hibernate-mapping package="com.hibernate.domain" >
	<class name="Department" table="department">
		<id name="id" column="departmentID">
			<generator class="native" />
		</id>
		<property name="name" column="departmentName" />
		<set name="employees" inverse="true" table="department_employee">
		    <!--          -->
			<key column="departmentID" />
			<!--            -->
			<many-to-many class="Employee" column="employeeID" unique="true"/>
		</set>
		
	</class>
</hibernate-mapping>

Employee.hbm.xml
<hibernate-mapping package="com.hibernate.domain">
	<class name="Employee" table="employee">
		<id name="id" column="employeeID">
			<generator class="native" />
		</id>
		<property name="name" column="employeeName" />
		
		<!--   join          -->
		<join table="department_employee">
			<!-- key      -->
			<key column="employeeID" />
			<!--        -->
			<many-to-one name="department" column="departmentID" />
		</join>  
	</class>
</hibernate-mapping>

이 강의 《 경량급 자바 기업 응용 실전 》 을 읽다.

좋은 웹페이지 즐겨찾기