[위 에 올 리 기] 하 이 버 네 이 트 의 매 핑 편 을 돌 이 켜 보 자.
한 쌍 의 다 중 맵
우선 이런 예 를 살 펴 보 자.학생 기본 정보, 학생 연락처 정보 등 을 포함 한 학생 관리 시스템 이 있다.한 학생 이 여러 개의 연락처 가 있 을 수 있 기 때문에 이곳 의 학생 과 주 소 는 한 쌍 이 많은 관계 이다.우 리 는 데이터 표를 만들어 설명 한다.
# student
CREATE TABLE IF NOT EXISTS `student` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `NAME` varchar(255) DEFAULT NULL, `AGE` int(11) DEFAULT NULL, `SEX` int(255) DEFAULT NULL, `MAJOR` varchar(255) DEFAULT NULL, PRIMARY KEY (`ID`) );
# student
INSERT INTO `student` (`ID`, `NAME`, `AGE`, `SEX`, `MAJOR`) VALUES (1, 'Jack', 22, 1, 'Psychology'), (2, 'Tom', 21, 1, 'Chemistry'), (3, 'Julia', 19, 0, 'Histroy'), (4, 'Alen', 25, 1, 'Histroy'), (6, 'Adam', 25, 1, 'Economics'), (7, 'Tony', 25, 1, 'Psychology'), (8, 'Daisy', 1, 0, 'Economics'), (106, 'Bill', 22, 1, 'Sociology'), (111, 'Emily', 26, 0, 'Biology');
# address
CREATE TABLE IF NOT EXISTS `address` ( `id` int(10) NOT NULL AUTO_INCREMENT, `student_id` int(10) NOT NULL, `address_info` varchar(50) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`id`) );
# address
INSERT INTO `address` (`id`, `student_id`, `address_info`) VALUES (1, 1, ' - '), (2, 1, ' - '), (3, 4, ' - '), (4, 7, ' - '), (5, 7, ' - '), (6, 7, ' - '), (9, 106, ' - '), (10, 106, ' - '), (11, 111, 'USA-NEWYORK'), (12, 111, 'CHINA-SHANGHAI');
이러한 한 쌍 이상 의 상황 에 대해 우 리 는 다음 과 같은 SQL 문 구 를 작성 하여 조회 할 것 입 니 다.
SELECT s.name,a.address_info FROM STUDENT s,ADDRESS a WHERE s.id=a.student_id
그럼 히 베 네 이 트 에 서 는 어떻게 작 동 하 는 건 가요?1. 한 쪽, 즉 학생 쪽 에 Student 류 에 여러 쪽 (즉 주소) 의 집합 속성 Set 또는 List 를 추가 합 니 다. 다음 과 같 습 니 다.public class Student {
private int id;
private String name;
private int age;
private int sex;
private String major;
private Set<Address> address=new HashSet<Address>();
//TODO getter setter
}
2. 한 쪽, 즉 학생 쪽 에 Student. hbm. xml 에 집합 속성 Set 또는 List 의 맵 을 추가 합 니 다. 다음 과 같 습 니 다.
<set name="address" cascade="delete" inverse="true">
<!-- -->
<key column="student_id"/>
<one-to-many class="com.earl.entity.Address"/>
</set>
코드 설명:
3. 호출 된 곳 에서 student. getAddress 를 사용 하면 이 학생 의 모든 연락처 에 대한 정 보 를 얻 을 수 있 습 니 다.
예 를 들 어 다음 과 같은 테스트 방법 이 있다.
public void testOneToMany(){
Session session=ThreadSessionUtil.getSession();
Student student=session.load(Student.class, 7);
System.out.println(student);
System.out.println("-----------address-----------");
Set<Address> addresses=student.getAddress();
for(Address address:addresses){
System.out.println(address.getAddress_info());
}
ThreadSessionUtil.closeSession();
}
먼저 학생 대상 을 조회 한 후, 학생 대상 의 getAddress () 방법 을 호출 하여, hibenate 는 로드 지연 형식 으로 데이터 베 이 스 를 통 해 이 학생 과 관련 된 모든 address 를 조회 합 니 다.hibenate 는 다음 과 같은 2 개의 SQL 을 인쇄 하여 우리 가 필요 로 하 는 정 보 를 조회 합 니 다.
Hibernate:
select
student0_.id as id1_6_0_,
student0_.name as name2_6_0_,
student0_.age as age3_6_0_,
student0_.sex as sex4_6_0_,
student0_.major as major5_6_0_
from
student student0_
where
student0_.id=?
Hibernate:
select
address0_.student_id as student_3_0_0_,
address0_.id as id1_0_0_,
address0_.id as id1_0_1_,
address0_.address_info as address_2_0_1_,
address0_.student_id as student_3_0_1_
from
address address0_
where
address0_.student_id=?
다 대 일 맵
아니면 위 에서 말 한 학생 과 주소 의 관 계 를 사용 하 시 겠 습 니까?여러 개의 주소 정보 가 한 학생 과 대응 하기 때문에 제 가 주소 정 보 를 얻 는 동시에 해당 하 는 학생 정 보 를 조회 하고 싶 을 때 저 희 는 이렇게 SQL 을 써 서 조회 할 수 있 습 니 다.
SELECT s.ID,s.NAME,a.address_info FROM STUDENT AS s,ADDRESS AS a WHERE a.STUDENT_ID=s.ID AND s.ID=?
그럼 히 베 네 이 트 에 서 는 어떻게 작 동 하 는 건 가요?1. 여러 쪽 (즉 주소 대상) 의 클래스 에 한 쪽 (즉 학생 대상) 의 유형 을 추가 하 는 속성 Student, 그들 사이 의 관련 필드 의 속성 studentid, 다음 과 같 음:public class Address {
private int id;
private String address_info;
private Student student;
//TODO getter setter
}
<many-to-one>
맵 을 추가 하고 기 존의 관련 필드 의 맵 을 제거 합 니 다. 다음 과 같 습 니 다. <class name="com.earl.entity.Address" table="address" >
<id name="id" column="id" type="integer">
<generator class="identity"></generator>
</id>
<property name="address_info" column="address_info" type="string"/>
<many-to-one name="student" class="com.earl.entity.Student" column="student_id"></many-to-one>
</class>
코드 설명:
<many-to-one>
의 name 은 관련 속성 이름 이 고 column 은 두 표 사이 의 관련 필드 입 니 다.3. 호출 된 곳 에서 getXXX 방법 으로 해당 하 는 대상 을 얻는다.
예 를 들 어 다음 과 같은 테스트 방법 이 있다.
public void testManyToOne(){
Session session=ThreadSessionUtil.getSession();
Address address=session.get(Address.class, 1);
System.out.println("---------- ----------");
Student student=address.getStudent();
System.out.println(student);
System.out.println(student.getName());
ThreadSessionUtil.closeSession();
}
먼저 주소 정 보 를 조회 한 다음 주소 정보 에 있 는 studentid 관련 학생 정보 조회.hibenate 는 다음 과 같은 SQL 두 개 를 출력 합 니 다.
Hibernate:
select
address0_.id as id1_0_0_,
address0_.address_info as address_2_0_0_,
address0_.student_id as student_3_0_0_
from
address address0_
where
address0_.id=?
Hibernate:
select
student0_.id as id1_6_0_,
student0_.name as name2_6_0_,
student0_.age as age3_6_0_,
student0_.sex as sex4_6_0_,
student0_.major as major5_6_0_
from
student student0_
where
student0_.id=?
계승 매 핑
계승 맵 은 하위 클래스 의 부모 클래스 간 의 관계 맵 과 관련된다.hibenate 에 서 는 서로 다른 계승 맵 을 정의 하 는 세 가지 방식 이 있 습 니 다.
public class Question {
private int id;
private String question_description;
private String level;
//TODO getter setter
}
public class ChoiceQuestion extends Question {
private String choice_option;
private String choice_answer;
//TODO getter setter
}
public class EssayQuestion extends Question {
private String essay_answer;
//TODO getter setter
}
그리고 Question. hbm. xml 에서 설정 합 니 다. 다음 과 같 습 니 다.
<class name="com.earl.entity.Question" table="question" >
<id name="id" column="id" type="integer">
<generator class="identity"></generator>
</id>
<!--discriminator , Question -->
<!--discriminator , Could not parse mapping document-->
<discriminator column="flag"></discriminator>
<property name="question_description" column="question_description" type="string"/>
<property name="level" column="level" type="string"/>
<!--discriminator-value Question flag , 1, , 1 flag。 ,hibernate flag=1 choiceQuestion -->
<subclass name="com.earl.entity.ChoiceQuestion" discriminator-value="1">
<property name="choice_option" column="choice_option" type="string"/>
<property name="choice_answer" column="choice_answer" type="string"/>
</subclass>
<subclass name="com.earl.entity.EssayQuestion" discriminator-value="2">
<property name="essay_answer" column="essay_answer" type="string"/>
</subclass>
</class>
구체 적 인 테스트 방법 은 문장 끝의 소스 코드 를 참고 하 세 요.
public class Product {
private int product_id;
private String product_name;
private String description;
//TODO getter setter
}
public class Book extends Product {
private int book_id;
private String book_name;
private String book_species;
private BigDecimal book_price;
private int product_id;
//TODO getter setter
}
데이터베이스 에 각각 상품 표 와 도서 표를 만들다.
CREATE TABLE IF NOT EXISTS `product` ( `id` int(10) NOT NULL AUTO_INCREMENT, `product_name` varchar(50) DEFAULT NULL, `description` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `book` ( `book_id` int(10) NOT NULL, `book_name` varchar(50) DEFAULT NULL, `book_species` varchar(50) DEFAULT NULL, `book_price` decimal(5,2) DEFAULT NULL, PRIMARY KEY (`book_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
자 표 와 부표 가 어떻게 연관 되 어 있 는 지 살 펴 보 자.joined - subclass 를 사용 하기 때문에 하위 테이블 에 관계 맵 파일 을 만 들 필요 가 없습니다. 하위 클래스 의 관 계 는 부모 클래스 가 유지 합 니 다.그래서 produt. hbm. xml 의 내용 을 살 펴 보 겠 습 니 다.
<hibernate-mapping>
<class name="com.earl.entity.Product" table="product" >
<id name="id" column="id" type="integer">
<generator class="identity"></generator>
</id>
<property name="product_name" column="product_name" type="string"/>
<property name="description" column="description" type="string"/>
<joined-subclass name="com.earl.entity.Book" table="book">
<!-- book id,book id , product id 。 -->
<key column="book_id"></key>
<property name="book_name" column="book_name" type="string"/>
<property name="book_species" column="book_species" type="string"/>
<property name="book_price" column="book_price" type="java.math.BigDecimal"/>
</joined-subclass>
</class>
</hibernate-mapping>
이런 관 계 를 맺 은 후에 우 리 는 자부 류 를 조작 할 수 있다.우선 삽입 작업 을 살 펴 보 자.
@Test
public void testJoinedSubclass(){
Session session=ThreadSessionUtil.getSession();
Transaction transaction=session.beginTransaction();
Book book=new Book();
// book product, book product , product , Product 。
book.setProduct_name("book");
book.setDescription("reading change world");
book.setBook_name("Harry Potter");
book.setBook_price(new BigDecimal("68.99"));
book.setBook_species("novel");
System.out.println("-------save book start-------");
session.save(book);
transaction.commit();
ThreadSessionUtil.closeSession();
}
이 테스트 방법 을 실행 한 후, 히 베 네 이 트 가 우 리 를 위해 무엇 을 했 는 지 살 펴 보 자.콘 솔 출력 을 관찰 하고 hibenate 는 다음 과 같은 sql 을 인쇄 했 습 니 다.
Hibernate:
insert into product (product_name, description) values (?, ?) Hibernate: insert into book (book_name, book_species, book_price, book_id) values (?, ?, ?, ?)
hibenate 가 먼저 부모 클래스 에 데 이 터 를 삽입 한 다음 에 하위 클래스 데이터 시트 에 데 이 터 를 삽입 한 것 을 설명 합 니 다.
다시 한 번 조 회 를 보다.다음 과 같은 테스트 방법 이 있 습 니 다.
@Test
public void testJoinedSubclassQuery(){
Session session=ThreadSessionUtil.getSession();
Book book=session.load(Book.class, 1);
System.out.println(book.getId());
System.out.println(book.getProduct_name());
System.out.println(book.getBook_name());
ThreadSessionUtil.closeSession();
}
우리 가 북 을 조회 할 때 getProduct 를 호출 합 니 다.name () 과 getBookname () 방법 을 사용 할 때 hibenate 는 북 시트 와 부모 류 produt 표를 연결 하여 조회 하 는 작업 을 했 기 때문에 hibenate 는 다음 과 같은 sql 을 출력 합 니 다.
Hibernate:
select book0_.book_id as id1_6_0_, book0_1_.product_name as product_2_6_0_, book0_1_.description as descript3_6_0_, book0_.book_name as book_nam2_1_0_, book0_.book_species as book_spe3_1_0_, book0_.book_price as book_pri4_1_0_ from book book0_ inner join product book0_1_ on book0_.book_id=book0_1_.id where book0_.book_id=?
그래서 자 표 와 부표 의 상응하는 데 이 터 를 얻 었 다.
이상 은 joined - subclass 의 기본 용법 입 니 다.
hibenate 의 구성 요소 맵 은 대상 을 대상 으로 하 는 구성 요소 의 중복 이용 사상 을 바탕 으로 설계 되 었 다.일부 속성 을 구성 요소 로 봉 하여 사용 하고 실체 클래스 의 정 의 를 간소화 합 니 다.다음은 구성 요소 맵 의 사용 을 살 펴 보 겠 습 니 다.전자상거래 플랫폼 에 있어 주문 Order 라 는 종류 가 있 습 니 다. 다음 과 같 습 니 다.
public class Order {
private int id;
private String goods_name;
private String receiver;
private String order_amount;
private ReceiveAddress receiveAddress;
//TODO getter setter
}
주문서 에 있어 서 수령 주소 의 정 보 는 ReceiveAddress 라 는 종류 로 봉 할 수 있 습 니 다. 다음 과 같 습 니 다.
public class ReceiveAddress {
private int id;
private String receive_address;
private String address_postcode;
//TODO getter setter
}
물론 ReceiveAddress 는 구성 요소 로 서 hbm. xml 파일 을 작성 해 야 합 니 다. 더 이상 군말 하지 않 습 니 다.이 어 Order 데이터 시트 와 ReceiveAddress 데이터 시트 를 만 듭 니 다. 다음 과 같 습 니 다.
# orderinfo
CREATE TABLE IF NOT EXISTS `orderinfo` ( `id` int(10) NOT NULL AUTO_INCREMENT, `goods_name` varchar(50) DEFAULT NULL, `receiver` varchar(50) DEFAULT NULL, `receiver_id` int(10) DEFAULT NULL, `order_amount` varchar(10) DEFAULT NULL, `receive_address` varchar(50) DEFAULT NULL, `address_postcode` varchar(6) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# receiveaddress
CREATE TABLE IF NOT EXISTS `receiveaddress` ( `id` int(10) NOT NULL AUTO_INCREMENT, `receive_address` varchar(50) DEFAULT NULL, `address_postcode` varchar(6) DEFAULT NULL, `receiver_id` int(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# receiveaddress
INSERT INTO `receiveaddress` (`id`, `receive_address`, `address_postcode`, `receiver_id`) VALUES (1, 'beijing', '100008', 1), (2, 'xian', '710000', 2);
Order. hbm. xml 에 대해 다음 과 같이 설정 합 니 다.
<hibernate-mapping>
<class name="com.earl.entity.Order" table="orderinfo" >
<id name="id" column="id" type="integer">
<generator class="identity"></generator>
</id>
<property name="goods_name" column="goods_name" type="string"/>
<property name="receiver" column="receiver" type="string"/>
<property name="order_amount" column="order_amount" type="string"/>
<!-- -->
<component name="receiveAddress" class="com.earl.entity.ReceiveAddress">
<property name="receive_address" column="receive_address" type="string"/>
<property name="address_postcode" column="address_postcode" type="string"/>
</component>
</class>
</hibernate-mapping>
지금 우 리 는 ReceiveAddress 를 구성 요소 로 Order 에 비 추 었 습 니 다.테스트 해 보 자.다음 insert 방법 을 보십시오:
@Test
public void testAdd(){
Session session=ThreadSessionUtil.getSession();
Transaction transaction=session.beginTransaction();
Order order=new Order();
order.setGoods_name("ipad Air2");
order.setReceiver("Earl");
order.setOrder_amount("4288.00");
// ReceiveAddress , Order
ReceiveAddress receiveAddress=session.get(ReceiveAddress.class, 1);
order.setReceiveAddress(receiveAddress);
session.save(order);
transaction.commit();
ThreadSessionUtil.closeSession();
}
위의 방법 이 실 행 될 때 hibenate 는 ReceiveAddress 의 기록 을 조회 한 다음 에 insert 작업 을 하기 때문에 다음 과 같은 sql 을 인쇄 합 니 다.
Hibernate:
select receiveadd0_.id as id1_8_0_, receiveadd0_.receive_address as receive_2_8_0_, receiveadd0_.address_postcode as address_3_8_0_, receiveadd0_.receiver_id as receiver4_8_0_ from receiveaddress receiveadd0_ where receiveadd0_.id=? Hibernate: insert into orderinfo (goods_name, receiver, order_amount, receiver_id, receive_address, address_postcode) values (?, ?, ?, ?, ?, ?)
구성 요소 맵 에 대해 서 는 여러 구성 요소 가 공동으로 사용 할 수 있 는 방식 도 있 습 니 다. 비교적 간단 합 니 다. 여 기 는 군말 없 이 Person 과 PersonAddress 에 관 한 코드 와 설정 을 참조 하 십시오.
연합 메 인 키 맵
실제 작업 에 서 는 표 의 여러 필드 에 메 인 키 를 설정 하여 연합 메 인 키 라 고 할 수 있 습 니 다.연합 키 의 사용 에 관 해 서 는 사실 그리 많 지 않다.연합 키 맵 에 관 한 지식 을 간단히 소개 합 니 다.그냥 실례 에서 설명 하 세 요.직원 Emp 류 가 있 습 니 다. 그 는 간단 한 속성 (성, 이름, 성별) 을 가지 고 있 습 니 다. 그 중에서 성과 이름 은 연합 키 입 니 다.hibenate 에서 연합 메 인 키 에 대한 작업 은 하나의 클래스 로 밀봉 하고 Serializable 인 터 페 이 스 를 실현 해 야 합 니 다. 다음 과 같 습 니 다.
public class EmpKey implements java.io.Serializable {
private String first_name;
private String last_name;
//TODO getter setter
}
그리고 Emp 클래스 에서 연합 키 속성 을 만 듭 니 다. 다음 과 같 습 니 다.
public class Emp {
private EmpKey key;
private String sex;
//TODO getter setter
}
다음은 hbm. xml 에서 연합 키 를 어떻게 비 추 는 지 살 펴 보 겠 습 니 다.다음 과 같다.
<hibernate-mapping>
<class name="com.earl.entity.Emp" table="emp" >
<!-- -->
<composite-id name="key" class="com.earl.entity.EmpKey">
<key-property name="first_name" type="string" column="first_name"/>
<key-property name="last_name" type="string" column="last_name"/>
</composite-id>
<property name="sex" type="string" column="sex"/>
</class>
</hibernate-mapping>
현재 우 리 는 이미 연합 키 맵 에 대해 설정 을 마 쳤 다.다음은 기본 적 인 추가 와 조회 작업 을 살 펴 보 겠 습 니 다.추가:
@Test
public void testAdd(){
Session session=ThreadSessionUtil.getSession();
Transaction transaction=session.beginTransaction();
Emp emp=new Emp();
//
emp.setKey(new EmpKey("Kobe", "Bryant"));
emp.setSex("male");
session.save(emp);
transaction.commit();
ThreadSessionUtil.closeSession();
}
test Add 방법 을 실행 한 후, hibenate 는 insert 의 sql 문 구 를 실행 해 주 었 습 니 다.
조회:
@Test
public void testQuery(){
Session session=ThreadSessionUtil.getSession();
// EmpKey Serializable , get load 。
Emp emp=session.get(Emp.class, new EmpKey("Kobe", "Bryant"));
System.out.println(emp);
ThreadSessionUtil.closeSession();
}
조 회 를 실행 할 때, hibenate 는 EmpKey 의 값 을 조회 조건 으로 조회 합 니 다.
총결산
이상 은 hibenate 에서 자주 사용 되 는 관계 맵 입 니 다. 실제 사용 에 있어 서 는 클래스 와 클래스 간 의 관 계 를 많이 분석 해 야 hibenate 가 우리 에 게 제공 하 는 관계 맵 을 잘 사용 하여 개발 효율 을 높 일 수 있 습 니 다.
이 다운로드 소스 코드 설명 을 누 르 십시오. 본 고 는 hibenate 에서 관계 맵 의 해당 내용 을 정리 하고 있 습 니 다. 독자 가 소스 코드 를 참조 할 때 come. earl. test 패키지 에서 Mapping 으로 끝 나 는 테스트 류 만 참조 하고 다른 것 은 자동 으로 무시 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[JPA] 즉시로딩(EAGER)과 지연로딩(LAZY) (왜 LAZY 로딩을 써야할까?) (1)Proxy는 이 글의 주제인 즉시로딩과 지연로딩을 구현하는데 중요한 개념인데, 일단 원리는 미뤄두고 즉시로딩과 지연로딩이 무엇인지에 대해 먼저 알아보자. 눈 여겨 볼 곳은 'fetch = FetchType.EAGER...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.