ORM은 Object-relational mapping 이다. 뭐라고? 그냥 DB 쓰기 편하게 해주는 프레임워크다.
기존에 DB를 가져다 쓸 때 일일이 JDBC를 생성해줬던 번거로움을 줄여주는 아주 편한 Framework이다.
기존에 일일이 JDBC로 Data를 가져왔던 것을, 이제는 그냥 자동으로 매핑해주는 Framework을 이용해 사용하기만 하면 된다.
ORM에는 대표적으로 3가지가 있다.
1. Mybatis(한국 多 사용)
(엄밀히 따지면 ORM은 아닌 듯. ORM은 쿼리문 없이 자동으로 객체 속성과 필드명 매치해줌)
2. Hibernate (전 세계적 多 사용)
3. JPA
google.trends에 쳐보면 Mybatis는 한국에서만 많이 사용하는데, 정부 표준 프레임워크 때문이란다.
그래서 나도 mybatis를 배운다.
< 구글 트랜즈 데이터 비교 >
Mybatis를 사용하기 위해선, 다음과 같이 행해야 한다.
라이브러리 다운 -> 지시서 작성 -> 디스패처에게 지시서 전달 -> 컨트롤러단에서 매핑된 데이터 이용
차근차근 살펴보자!
우선 라이브러리를 다운받는다.
mybatis와 spring에서 mybatis를 사용할 수 있는 mybatis spring을 다운받아야한다. (DI해줘라.)
그리고 지시서를 만들어야한다.
지시서는 DB와 entity를 매핑시켜준다는 의미로 mapper라고 칭한다.
흔히 우리는 Spring에서 디스패처에게 지시서를 전달해줄때 두 가지 방식을 이용했다.
1. 지시서(xml파일)
2. 어노테이션매핑
그럼 먼저, 지시서를 이용해보자.
1. xml 파일로 매핑해주기
@noticeDaoMapper.xml
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.newlecture.web.data.dao.NoticeDao"> <select id="getList" resultType="com.newlecture.web.data.view.NoticeView"> SELECT * FROM NOTICE_VIEW WHERE BINARY ${param2} LIKE '%${param3}%' LIMIT 0,10 </select> <!-- $는 ''가 오지 않고, #은 자동으로 ''가 들어간다. --> <select id="getSize"> SELECT COUNT(CODE) SIZE FROM NOTICE WHERE BINARY ${param1} LIKE '%${param2}%' </select> <select id="get" resultType="com.newlecture.web.data.view.NoticeView"> SELECT * FROM NOTICE_VIEW WHERE CODE= #{code} </select> <select id="getPrev"> SELECT * FROM NOTICE_VIEW WHERE CAST(CODE AS unsigned) > CAST(#{code} AS unsigned) ORDER BY REGDATE asc LIMIT ${()param1-1)*10},10 </select> <select id="getNext"> SELECT * FROM NOTICE_VIEW WHERE CAST(CODE AS unsigned) < CAST(#{code} AS unsigned) ORDER BY REGDATE DESC LIMIT 0,1 </select> <select id="lastCode" resultType="String"> SELECT MAX(CAST(CODE AS UNSIGNED)) CODE FROM NOTICE </select> <delete id="delete"> DELETE FROM NOTICE WHERE CODE=#{code} </delete> <!-- 객체를 전달받았을 때 사용법 -> el표기법과 비슷하다. --> <!-- getter 가져오는 el표기법과 유사함. --> <update id="update"> UPDATE NOTICE SET TITLE=#{title}, CONTENT=#{content} WHERE CODE=#{code} </update> <insert id="add"> 실행 전에 String code에 sql결과를 담는다. <selectKey order="BEFORE" keyProperty="code" resultType="String"> SELECT MAX(CAST(CODE AS UNSIGNED))+1 CODE FROM NOTICE </selectKey> INSERT INTO NOTICE(CODE, TITLE, WRITER, CONTENT) VALUES (#{code},#{title},#{writer},#{content}) </insert> </mapper> | cs |
mapper의 namespace에 Dao를 명시한다. 여기서 받아온 인자를 이용해 매핑할 수 있다.
단일 인자의 경우, 이름으로 접근 가능하다.
그러나 다중 인자의 경우, param 으로 접근해야한다. ex)param1, param2, param3 등
인자를 이용하는 방식은 2가지 방식이 있다.
${} 나 #{} 태그를 이용하는 것이다.
${}는 가져온 파라미터의 변수형에 관계 없이 가져온다
#{}은 값을 가져온다
ex) String n = "하하";
${n} => 하하
#{n} => '하하'
'%${n}%'=> '%하하%'
'%#{n}%' => '%'하하'%'
이중 쿼리의 경우, <selectKey> 태그를 넣어 메인 sql실행 전에 서브 쿼리가 실행되도록 한다.
<SelectKey> 옵션
order="before" 옵션 - 메인 쿼리 실행 전, 서브쿼리 실행
keyProperty = "code" 옵션 - 쿼리 결과를 가져올 이름
resultType = "String" 옵션 - 쿼리 결과의 반환 타입
2. Annotation(@)로 매핑해주기
엔티티를 명시한 java 인터페이스 파일 위에 sql문을 매핑해주는 annotation이용 시 xml 작성 없이 DB서 데이터를 가져올 수 있다.
sql문을 한 줄에 작성하지 않아도 되는 xml과 달리, 한 줄에 명시해줘야하므로 sql문이 길어지는 경우 불편함을 가져올 수 있다. 그럼에도 불구하고, 많은 사용자들이 이 방식을 이용한다.
@NoticeDao.java(interface)
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 29 30 31 32 33 | package com.newlecture.web.data.dao; import java.util.Date; import java.util.List; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.SelectKey; import com.newlecture.web.data.entity.Notice; import com.newlecture.web.data.view.NoticeView; public interface NoticeDao { @Select("SELECT * FROM NOTICE_VIEW WHERE BINARY ${field} LIKE '%${query}%' LIMIT 0,10") List<NoticeView> getList(); List<NoticeView> getList(@Param("page")int page, @Param("field")String field, @Param("query")String query); List<NoticeView> getList(int page); @Select("SELECT * FROM NOTICE_VIEW WHERE CODE= #{code}") NoticeView get(String code); NoticeView getPrev(String code); NoticeView getNext(String code); @SelectKey(statement="SELECT MAX(CAST(CODE AS UNSIGNED))+1 CODE FROM NOTICE", before=true,keyProperty="code", resultType = String.class) @Insert("INSERT INTO NOTICE(CODE, TITLE, WRITER, CONTENT) VALUES (#{code},#{title},#{writer},#{content}") int add(Notice notice); int add(String title, String content, String writer); } | cs |
명시한 엔티티 위에 어노테이션을 이용해 바로 DB에서 데이터를 집어넣을 수 있다.
xml과 작성법은 비슷하다.
주의할점은 xml에서 사용한 param1, param2 가 사용 불가능하단 것이다.
어노테이션으로 다중 인자를 받는 경우,
@param("이름")변수형 변수명
으로 변수에 인자를 대입해 가져와야한다.
마찬가지로 서브 쿼리는 SelectKey를 이용한다.
객체로 받아오는 경우, getter에서 변수명 맨 앞 글자를 소문자로 자동으로 바꿔 sql문에 넣어준다.
지시서 작성 후, 지시서를 전달해줘야한다.
전달자는 세 놈이 가능한데, 1.Java 전역변수, 2. Tomcat, 3. Dispatcher 이다.
보통, 트랜잭션과 보안 처리를 위해 Sprgin이용 시에는 3.디스패처를 많이 이용하므로 디스패처에게 지시서를 전달해준다.
@Servcie-Context.xml (나눈 디스패처 중 이 놈한테 넣어준다.)
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- Spring에게 mybatis 지시서 주기 --> <!-- Mapper객체를 만들어주는 Bean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/newlecture/web/mybatis/mapper/*.xml" /> </bean> <!-- 자동으로 db를 연결하고 닫아주는 Bean --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> | cs |
Bean을 이용해 Mapper객체를 생성하고, mapperLocation을 통해 위의 지시서를 전달해준다.
이제 컨트롤러단에서 사용하기만 하면 된다.
기존에 Dao객체를 일일이 생성하고 만들었지만 그럴 필요가 없어졌다.
1 2 3 4 5 6 7 | @Autowired private NoticeDao noticeDao; /*컨테이너가 자동으로 담아준다*/ @Autowired private NoticeFileDao noticeFileDao; | cs |
1 2 3 4 5 6 7 8 9 10 11 | @Autowired private SqlSession sqlSession; @RequestMapping("notice") public String notice(@RequestParam(value="p", defaultValue="1")int page, @RequestParam(value="q", defaultValue="")String query, @RequestParam(value="f", defaultValue="TITLE")String field, Model model){ List<NoticeView> list = sqlSession.getMapper(NoticeDao.class).getList(page, field, query); | cs |
< Mybatis 이용시 매핑된 sqlSession 객체 이용>
Bean의 sqlSession을 이용해 매핑된 DB data를 이용하면 된다.
'공부 > Spring' 카테고리의 다른 글
Maven프로젝트로 Spring 이용해보기(설정) (0) | 2017.06.04 |
---|---|
Mybatis - Mapper, Service, MyBatisDao (0) | 2017.04.17 |
인증2. DB연동 후 알아서 권한 확인해주는 편한 Spring (0) | 2017.04.10 |
http태그의 use-expressions (0) | 2017.04.10 |
인증(Authentication) (0) | 2017.04.06 |