일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 여행
- mysql polygon
- shortcuts
- IntelliJ
- mybatis polygon
- mybatis polygon mapper
- 엽서
- Java
- mybatis
- 좌표변환
- 하이버네이트
- 쿼리
- join
- 자바
- 좌표계변환
- 사진
- 캘리그라피
- 큐브리드
- spring
- 파이어폭스41
- QGIS
- Hibernate
- cubrid
- 위경도계
- JSON 변환
- Query
- mysql gis
- 단축키
- json parser
- JPA
- Today
- Total
쏘댕
Hibernate - 큐브리드 2 JOIN 본문
Spring data JPA를 적용해보겠다고 별짓을 다했는뎅 어디가 어떻게 어디서부터 잘못된건지 설정이 꼬여가지고 안된다......
다음번에 새로운 마음으로 다시해야지..................
이번엔 쪼인을 해보쟈
일단 지난번에 test_table 추가에 이어서 조인 테스트를 위한 테이블 추가!
(이름이 온통 엉망인데... 좋은 이름이 안생각난다.. @_@)
테이블 추가했으니 모델도 추가!
public class JoinTest {
private long id;
private long testId;
private JoinKeyword joinKeyword;
public enum JoinKeyword {
RELATION_A, RELATION_B
}
/* getter, setter */
}
TestModel.java에는 JoinTest를 추가한다
(뭔가 조인을 하기위해 모델 안에 인자가 추가되는게 그림이 이상한데.. 이방법말고도 있을텐뎅... 더 찾아봐야지)
public class TestModel {
private long id;
private String name;
private Date date;
private Member creator;
private TestEnum testEnum;
private JoinTest joinTest;
/* 이하 생략! */
}
지난번에 매핑 설정하던 mapper.hbm.xml에 추가를 한다. 아래와 같이!
(mapper도 곧 테이블별로 분리할 예정!!)
<class name="TestModel" table="test_table">
<id name="id" type="long" column="id">
<generator class="identity"></generator>
</id>
<property name="name" type="String" column="name"></property>
<property name="date" type="Date" column="reg_date"></property>
<component name="creator" class="Member">
<property name="paycoUniqueId" type="String" column="reg_user_uid"></property>
<property name="paycoId" type="String" column="reg_user"></property>
</component>
<property name="testEnum" column="test_enum">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">com.nhnent.deploy.admin.model.TestModel$TestEnum</param>
<param name="useNamed">true</param>
</type>
</property>
<join table="join_table" optional="true">
<key column="test_id"></key>
<component name="joinTest" class="JoinTest">
<property name="id" type="long" column="id" generated="insert"></property>
<property name="joinKeyword" column="join_keyword">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">com.nhnent.deploy.admin.model.JoinTest$JoinKeyword</param>
<param name="useNamed">true</param>
</type>
</property>
</component>
</join>
</class>
<class name="JoinTest" table="join_table">
<id name="id" type="long" column="id">
<generator class="identity"></generator>
</id>
<property name="testId" type="long" column="test_id"></property>
<property name="joinKeyword" column="join_keyword">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">com.nhnent.deploy.admin.model.JoinTest$JoinKeyword</param>
<param name="useNamed">true</param>
</type>
</property>
</class>
여기서 optional="true"가 신기하다
optional 속성을 안주면
Hibernate:
select
testmodel0_.id as id1_5_,
testmodel0_.name as name2_5_,
testmodel0_.reg_date as reg_date3_5_,
testmodel0_.reg_user_uid as reg_user4_5_,
testmodel0_.reg_user as reg_user5_5_,
testmodel0_.test_enum as test_enu6_5_,
testmodel0_1_.id as id2_2_,
testmodel0_1_.join_keyword as join_key3_2_
from
test_table testmodel0_
inner join
join_table testmodel0_1_
on testmodel0_.id=testmodel0_1_.test_id
where
testmodel0_.id=?
이렇게 inner join이 되고,
optional="true"를 추가하면
Hibernate:
select
testmodel0_.id as id1_5_,
testmodel0_.name as name2_5_,
testmodel0_.reg_date as reg_date3_5_,
testmodel0_.reg_user_uid as reg_user4_5_,
testmodel0_.reg_user as reg_user5_5_,
testmodel0_.test_enum as test_enu6_5_,
testmodel0_1_.id as id2_2_,
testmodel0_1_.join_keyword as join_key3_2_
from
test_table testmodel0_
left outer join
join_table testmodel0_1_
on testmodel0_.id=testmodel0_1_.test_id
where
testmodel0_.id=?
이렇게 left outer join이 된다.
실행해본 Test코드는 아래와 같다!
확인에 급급해서.... 그저 sout만 찍었다.. ㅎ_ㅎ
@Test
public void selectJoinTest() {
// begin
HibernateUtil.beginTransaction();
/* select by id */
long testModelId = 22;
Query query = HibernateUtil.getCurrentSession().createQuery("from TestModel t left join t.joinTest j on j.testId = t.id where t.id = :id");
query.setParameter("id", testModelId);
TestModel testModel = (TestModel)query.uniqueResult();
System.out.println(testModel.toString());
// commit
HibernateUtil.commitTransaction();
}
그런데!! 이렇게 명시하지 않아도 암묵적 조인이 된다고해서 그것도 해봤따
/* select by joinKeyword */
JoinTest.JoinKeyword joinKeyword = JoinTest.JoinKeyword.RELATION_B;
/* 명시적 조인 */
Query explicitQuery = HibernateUtil.getCurrentSession().createQuery("from TestModel t left join t.joinTest j on j.testId = t.id where j.joinKeyword = :keyword");
explicitQuery.setParameter("keyword", joinKeyword);
List<TestModel> explicitTestModels = explicitQuery.list();
for (TestModel t : explicitTestModels) {
System.out.println(t.toString());
}
/* 암묵적 조인 */
Query implicitQuery = HibernateUtil.getCurrentSession().createQuery("from TestModel t where t.joinTest.joinKeyword = :keyword");
implicitQuery.setParameter("keyword", joinKeyword);
List<TestModel> implicitTestModels = implicitQuery.list();
for (TestModel t : implicitTestModels) {
System.out.println(t.toString());
}
Assert.assertEquals(explicitTestModels, implicitTestModels);
실행된 쿼리는 명시적, 암묵적 조인 둘 다 아래와 같다.
select
testmodel0_.id as id1_5_,
testmodel0_.name as name2_5_,
testmodel0_.reg_date as reg_date3_5_,
testmodel0_.reg_user_uid as reg_user4_5_,
testmodel0_.reg_user as reg_user5_5_,
testmodel0_.test_enum as test_enu6_5_,
testmodel0_1_.id as id2_2_,
testmodel0_1_.join_keyword as join_key3_2_
from
test_table testmodel0_
left outer join
join_table testmodel0_1_
on testmodel0_.id=testmodel0_1_.test_id
where
testmodel0_1_.join_keyword=?
당연히 assertEquals 결과도 동일하다고 나오는데,
심지어 하이버네이트는 같은 트랜잭션 안에서 동일한 쿼리는 결과를 캐싱한다고 했던거 같은데 @_@
그래서 완전히 같은 결과를 가져왔을지도 @_@
하지만 내가 제일 신기한건 @_@
위에 언급한 optional="true" 상태로 save를 했을때다.
@Test
public void insertForJoinTest() {
HibernateUtil.beginTransaction();
Member member = new Member("uuid", "ssod***@e-mail.com");
/* joinTest 모델 set한 상태로 insert */
TestModel testModelWithJoin = new TestModel("test_1", new Date(), member, TestModel.TestEnum.TEST_A);
testModelWithJoin.setJoinTest(new JoinTest(testModelWithJoin.getId(), JoinTest.JoinKeyword.RELATION_B));
HibernateUtil.getCurrentSession().save(testModelWithJoin);
/* joinTest 모델 없는 상태로 insert */
TestModel testModelWithoutJoin = new TestModel("test_2", new Date(), member, TestModel.TestEnum.TEST_B);
HibernateUtil.getCurrentSession().save(testModelWithoutJoin);
HibernateUtil.commitTransaction();
}
JoinTest 모델을 set한 후 save를 실행하면
Hibernate:
insert
into
test_table
(id, name, reg_date, reg_user_uid, reg_user, test_enum)
values
(NULL, ?, ?, ?, ?, ?)
Hibernate:
select
last_insert_id()
Hibernate:
insert
into
join_table
(join_keyword, test_id)
values
(?, ?)
Hibernate:
select
testmodel_1_.id as id2_2_,
testmodel_1_.join_keyword as join_key3_2_
from
test_table testmodel_
left outer join
join_table testmodel_1_
on testmodel_.id=testmodel_1_.test_id
where
testmodel_.id=?
이렇게나 알아서 양쪽에 넣어준다...............
마지막에 결과 select는 왜하는건지 사실 모르겠는뎅..
그리고 JoinTest 모델을 안넣고 save 하면
Hibernate:
insert
into
test_table
(id, name, reg_date, reg_user_uid, reg_user, test_enum)
values
(NULL, ?, ?, ?, ?, ?)
Hibernate:
select
last_insert_id()
Hibernate:
select
testmodel_1_.id as id2_2_,
testmodel_1_.join_keyword as join_key3_2_
from
test_table testmodel_
left outer join
join_table testmodel_1_
on testmodel_.id=testmodel_1_.test_id
where
testmodel_.id=?
test_table만 insert 딱 하고 결과 select
요게 optional 값을 true로 안주면 두번째 실행처럼 join으로 설정되어있는 모델을 셋팅하지 않으면 insert 시 에러가 발생한다.
Hibernate:
insert
into
test_table
(id, name, reg_date, reg_user_uid, reg_user, test_enum)
values
(NULL, ?, ?, ?, ?, ?)
Hibernate:
select
last_insert_id()
Hibernate:
insert
into
join_table
(join_keyword, test_id)
values
(?, ?)
org.hibernate.exception.GenericJDBCException: could not execute statement
요렇게 무조건적으로다가 저걸 insert할려고 찾으니 필수값이 null이여서 에러를 뱉는다.
이제 one-to-many 랑 many-to-one 이런것도 해봐야겠따
'공부 > Java' 카테고리의 다른 글
WebMvcConfigurerAdapter 변경 (0) | 2019.07.24 |
---|---|
[하이버네이트] 4버전 이상에서의 HibernateUtil.java (0) | 2015.11.05 |
[Hibernate] 하이버네이트 - 큐브리드 (0) | 2015.09.01 |
개인정보 마스킹처리 (휴대폰번호, 이메일) (0) | 2015.07.20 |
[웹 시큐어 코딩] owasp-java-html-sanitizer 적용 (0) | 2015.07.10 |