3. 귀찮은 일
<insert id="insertDoctor" parameterType="domain.Doctor">
insert into Doctor (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateDoctor" parameterType="domain.Doctor">
update Doctor set
username = #{username}, password = #{password},
email = #{email}, bio = #{bio}
where id = #{id}
</update>
<delete id="deleteDoctor” parameterType="int">
delete from Doctor where id = #{id}
</delete>
<select id="selectDoctor" resultType="domain.Doctor">
select * from Doctor
</select>
3
4. 머리 아픈 일
<hibernate-mapping>
<class name="hello.Message“ table="MESSAGES">
<id name="id" column="MESSAGE_ID">
<generator class="increment"/>
</id>
<property name="text" column="MESSAGE_TEXT"/>
<many-to-one name="nextMessage" cascade="all"
column="NEXT_MESSAGE_ID"/>
</class>
</hibernate-mapping>
SELECT new list(mother, offspr, mate.name)
FROM DomesticCat AS mother
INNER JOIN mother.mate AS mate
LEFT OUTER JOIN mother.kittens AS offspr
4
5. 하고 싶은 일
• SQL 작성 최소화
• Object oriented programming
• 로직에 집중
• 단순한 설정 - 쉽고, 직관적
• 학습의 최소화
5
8. 고려해야 할 점
• 설정
– object, relation 매핑
• SQL 생성
– object 를 SQL 의 파라미터로 전달
– SQL 결과를 object 로 리턴
8
9. 구현 전략
• object 와 relation 의 1:1 매핑 구현
– MyBatis 를 이용하여 기본적인 insert, update,
delete, select 문을 runtime 자동 생성
– 생성된 SQL문을 MyBatis SQL repository 에
저장
– Association 은 다루지 않음
– Join, subquery 구문은 MyBatis로 처리
• 설정은 Java Annotation 사용
• 일단 MySQL 먼저
9
10. Java Annotation
• 자바 5.0 에서 소개
• 자바 소스 코드에 추가되는 문법적인 메타데이터
• 클래스, 메소드, 변수, 파라미터, 패키지에 첨언하
여 컴파일러의 의해 .class 파일에 포함되어 컴파일
혹은 런타임 시 이용
• 번거로운 설정 작업들과 반복적인 코드를 줄여줌
• Built-in Annotations
– @Override, @Deprecated, @SupressWarnings
• Custom Annotations
– @Controller, @Service, @Entity, @Column
10
11. Custom Annotation
• @interface 선언
public @interface MyAnnotation {
String value();
}
• Annotation 추가
import MyAnnotation
@MyAnnotation(value=“my annotation”)
public void myMethod(int arg) {
// do something
}
11
12. Annotation API
• Class 와 Field
– getAnnotation(Class<A> annotationClass)
특정 타입에 대한 annotation 을 리턴
– getAnnotations()
모든 타입의 annotation 을 리턴
– isAnnotationPresent(Class annotationClass)
특정 타입에 대한 annotation 이 존재하면
true 리턴
12
13. MyBatis
• 구) iBatis
• SQL문과 객체를 매핑
• SQL문을 XML 파일에 저장
• JDBC 코드 제거
13
출처) www.mybatis.org
14. MyBatis 예제
• Mapped Statement
<mapper namespace="org.mybatis.example.HospitalMapper">
<select id="selectHospital" parameterType="int"
resultType="Hospital">
select * from Hospital where id = #{id}
</select>
</mapper>
• Java DAO code
public interface HospitalMapper {
public Hospital selectHospital(int id);
}
HospitalMapper mapper = session.getMapper(HospitalMapper.class);
Hospital hospital = mapper.selectHospital(101);
14
15. 순서
1. Table 생성
2. Annotation 정의
3. Mapping class 생성
4. EntityManager 작성 – CRUD interface
5. SQL Generation 클래스 작성
– InsertSqlSource
– UpdateSqlSource
– DeleteSqlSource
– SelectOneSqlSource
– SelectListSqlSource
15
16. 1. Table 생성
Create table hospital (
hospitalid INT NOT NULL
PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(30),
regdttm DATETIME
)
16
21. 5. SQL Generation
• INSERT
– 컬럼 중 auto_increment 로 선언된 컬럼은 insert 문
에서 제외
• UPDATE
– Primary Key 가 아닌 컬럼들만 update
– PK로 where 조건절 생성
• DELETE
– parameter 객체에서 null 값이 아닌 field 로 where 조
건절 생성
• SELECT
– parameter 객체에서 null 값이 아닌 field 로 where 조
건절 생성
21
22. 5-1. Insert문 생성
• 컬럼 중 auto_increment 로 선언된 컬럼은
insert 문에서 제외
<생성되는 SQL>
INSERT INTO hospital (name, regdttm)
VALUES (#{name}, #{regdttm})
22
26. AnnotationUtil.getNonAutoIncrem
entColumnNames
1: List<String> names = new LinkedList<String>();
2: for (Field field : clazz.getDeclaredFields()) {
3: if (field.isAnnotationPresent(Column.class)) {
4: Column c = field.getAnnotation(Column.class);
5: if (!c.autoIncrement())
6: names.add("".equals(c.name()) ? field.getName():c.name());
7: }
8: }
9: return names;
26
27. 5-2. Update문 생성
• Primary Key 가 아닌 컬럼들만 update
• PK로 where 조건절 생성
<생성되는 SQL>
UPDATE hospital
SET name = #{name}, regdttm = #{regdttm}
WHERE hospitalid = #{hospitalid}
27
30. AnnotationUtil.getNonPrimaryKey
ColumnNames
1: List<String> names = new LinkedList<String>();
2: for (Field field : clazz.getDeclaredFields()) {
3: if (field.isAnnotationPresent(Column.class)) {
4: Column c = field.getAnnotation(Column.class);
5: if (!c.primaryKey())
6: names.add("".equals(c.name()) ? field.getName() :
7: c.name());
8: }
9: }
10: return names;
30
31. AnnotationUtil.getPrimaryKeyColu
mnNames
List<String> names = new LinkedList<String>();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Column.class)) {
Column c = field.getAnnotation(Column.class);
if (c.primaryKey())
names.add("".equals(c.name()) ? field.getName() : c.name());
}
}
return names;
31
32. 5-3. Delete문 생성
• parameter 객체에서 null 값이 아닌 field 로
where 조건절 생성
예)
Hospital hospital = new Hospital();
hospital.setName(“JCO병원”);
entityManager.delete(hospital);
<생성되는 SQL>
DELETE FROM hospital
WHERE name = #{name}
32
35. 5-4. Select문 생성
• parameter 객체에서 null 값이 아닌 field 로 where
조건절 생성
예)
Hospital hospital = new Hospital();
hospital.setName(“JCO병원”);
hospital = (Hospital)entityManager.load(hospital);
<생성되는 SQL>
SELECT hospitalid, name, regdttm
FROM hospital
WHERE name = #{name}
35
38. 복습
1. Table 생성
2. Annotation 정의
3. Mapping class 생성
4. EntityManager 작성 – CRUD interface
5. SQL Generation 클래스 작성
– InsertSqlSource
– UpdateSqlSource
– DeleteSqlSource
– SelectOneSqlSource
– SelectListSqlSource
38
39. Effect
• 비타민MD 사이트에 일부 적용
• 만약 전체 적용한다면
69% SQL문 제거 가능
39
SQL 적용 전 적용 후
insert 112 7
update 80 2
delete 79 0
select 327 176
총 598 185
40. Future Work
• Annotation 추가
– Like 구문 지원
– DDL 상의 default 값, not null 등의 constraint
지원
• Transaction
• Caching
• Oracle, MSSQL, DB2 등 다른 DBMS 지원
40
43. 이 저작물은 크리에이티브 커먼스 코리아 저작자표시-비영리-
동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
This work is Licensed under Creative Commons Korea Attribution 2.0 License.