newlecture: spring boot (2) : Mybatis 설정
Spring Boot
Boot에서의 Mybatis
- DataSource, SqlSessionFactory, SqlSessionTemplate 설정 거의 자동화
우리가 해야할 건
- jdbc, mybatis starter 의존성 추가
- properties에 datasource 설정
- @Mapper 객체 구현
뉴렉쌤의 MVC 계층구조
- Service와 Dao는 Interface(추상)와 Implementaion(구현체)을 따로 나누어 추상화에 의존
- 하지만 나는 당분간 mybatis만 쓸것 같으므로 실전/포폴에선 구현체만 쓰자..
Boot에서 Mybatis 및 DB 연동
- starter 라이브러리 추가
- 프로젝트 우클릭 > spring > add starters
다음으로 넘어가서 dependency 추가 후 finish
Mapper 객체는 아래와 같이 사용하면 된다
@Mapper
public interface NoticeDao {
@Select("select * from notice")
List<Notice> getList();
List<Notice> get(int i);
}
위처럼 작성만 해주어도 해당 interface에 해당하는 Mybatis 구현체를 만들어서 IoC컨테이너에 담아준다
- application.properties 에 아래의 설정을 추가하면 된다
Oracle일 경우
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@...
spring.datasource.username=philz
spring.datasource.password=...
MySql일 경우
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.56.1:3306/newlecture?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
spring.datasource.username=newlecture
spring.datasource.password=111
IoC 컨셉
Dependency는 부품과 같다 꼽았다 뺐다가
Dependency를 생성/사용하는 방식은 크게 3가지가 있다
1. 메서드에서
class Frame {
public void f1() {
A a = new A();
a...();
}
}
2. 생성자에서
class Frame {
private A a;
public Frame() {
a = new A();
}
}
3. 해당 객체 외부에서
class Frame {
private A a;
public Frame(A a) {
this.a = a;
}
public void setA(A a) {
this.a = a;
}
}
이 때 1번의 객체 a의 소멸 시점은 메서드 종료시,
2번은 객체가 소멸될 때,
3번은 객체가 소멸되더라도 소멸되지 않는다2번과 3번은 멤버 변수에서 a를 선언하였는데
이때 Frame과 a의 관계를 Has A 관계라고 한다
2번은 Composition Has A
3번은 Assocation Has A 라고도 한다
스프링은 3번을 컨셉으로 두었다 그 이유는 아래와 같이 다형성을 이용해서 부품이 바뀌더라도 유연하게 교체할 수 있기 때문 (아래 코드 참고)
class Frame {
private IA a;
public Frame(IA a) { // Constructor Injection
this.a = a;
}
public void setA(IA a) { // Setter Injection
this.a = a;
}
}
객체를 넣어주기 위해서 더 상위에서 코드를 생성하는데..
이때 의존의 관계가 Frame -> IA -> IB -> IC 라고 할 때
C c = new C();
B b = new B();
b.set(c);
A a = new A();
a.set(b);
Frame f = = new Frame();
f.setA(a);
이렇게 더 상위의 정보에서 주입하게 된다
이때 순서는 기존에 하던 방식대로 작성하면 Frame에서 C로 가는 방향일 것이지만 위 순서는 그것의 역방향이다. (IoC의 I는 Inversion의 약자)
위 정보는 XML설정이나 JavaConfig으로 관리한다
jdbc 드라이버 연동이 하두 안되어서 1시간동안의 삽질 끝에..
드라이버 클래스네임 뒤에 스페이스바 하나가 있는 것을 발견함.. 지우니 아주 잘 된다..
- java의 entity랑 db의 물리 테이블은 1:1 매칭되게끔 하는게 좋다
- view table의 경우 기존 table을 상속받아서 나머지 컬럼에 대해서만 getter/setter/toString/Constructo 하는게 좋다
Mybatis Collum 매핑
한 컬럼일 때
@Mapper
public interface NoticeDao {
@Result(property = "memberName", column = "member_name")
@Select("select * from noticeview")
List<NoticeView> getList();
NoticeView get(int id);
}
여러 컬럼일 때
@Results({
@Result(property = "memberName", column = "member_name"),
@Result(property = "regdate", column = "reg_date"),
@Result(property = "memberId", column = "member_id")
})
paging
@Select("select * from NoticeView "
+ "where ${field} like '%${query}%' "
+ "order by id desc "
+ "limit #{offset}, #{size}")
#{}
값의 형태로 대입'
을 자동으로 넣어준다.prepareStatement
${}
그대로 삽입. 보안상 좋지 않다
서비스 구현체
@Override
public List<NoticeView> getList(int page, String field, String query) {
int size = 5;
int offset = 0 + size * (page-1); // an = a1 + (n-1)d : page 1-> 0, 2-> 10, 3-> 20
List<NoticeView> list = noticeDao.getList(offset, size, field, query);
return list;
}
Mybatis 어노테이션 -> XML
기존 NoticeDao 어노테이션 사용의 문제점
- 구현할 내용이 interface에 있음
- 구현의 형태가 Mybatis뿐만 아니라 Jpa등등이 있을 수 있음
- 그 구현의 형태가 Mybatis라는 것이 interface에 있는 것이 문제
- 규모가 커질 수록 Annotaion에 기술하는 것이 지저분해진다
xml은 아래를 참고하면 된다 !
<?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.dao.NoticeDao">
<select id="getList" resultType="com.newlecture.web.entity.NoticeView">
select * from NoticeView
where ${field} like '%${query}%'
order by id desc
limit #{offset}, #{size}
</select>
</mapper>
resultType
반환타입이 단일인지 목록인지는 고려하지 않아도 된다
.properties에 아래 내용을 추가
mybatis.mapper-locations=classpath:com/newlecture/web/dao/mybatis/mapper/*.xml
XML 태그를 추천하지 못한다면
- 이클립스 마켓플레이스에서 Eclipse XML Editors and Tools를 설치하면 된다
.dtd
우리가 사용하는 태그를 정의한 문서파일