마이바티스 프레임워크 설치 밎 적용
mybatis3.xx
-공식 메뉴얼
https://mybatis.org/mybatis-3/ko/getting-started.html
의존성 설치
(버전 스크린샷 첨부 안 했을 경우 최신버전)
// annotationProcessor도 추가
https://mybatis.org/mybatis-3/ko/getting-started.html
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" />
<property name="username" value="STUDY" />
<property name="password" value="oracle"/>
</properties>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/MemberMapper.xml"/> //맵핑경로
</mappers>
</configuration>
//맵핑 관리
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mappers.MemberMapper">
<select id="getList" resultType="member.Member">
SELECT * FROM MEMBER
</select>
<!--
<insert id="">
</insert>
<update id="">
</update>
<delete id="">
</delete>
-->
</mapper>
맵핑될 데이터베이스속 column명이랑 동일해야함
package member;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class Member {
private long USER_NO;
private String USER_ID;
private String USER_PW;
private String USER_NM;
private String MOBILE;
private LocalDateTime REG_DT;
private LocalDateTime MOD_DT;
}
package configs;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.Reader;
import java.util.ResourceBundle;
public class DBConn {
private static SqlSessionFactory factory;
static {
try {
Reader reader = Resources.getResourceAsReader("configs/mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSession(boolean autoCommit) {
return factory.openSession(autoCommit);
}
public static SqlSession getSession() {
return getSession(true);
}
}
package exam01;
import configs.DBConn;
import member.Member;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.List;
public class Ex01 {
@Test
void test1() {
SqlSession session = DBConn.getSession();
List<Member> members = session.selectList("mappers.MemberMapper.getList");
}
}
namespace.id로 접근
//UTF-8 설정
package member;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class Member {
private long userNo;
private String userId;
private String userPw;
private String userNm;
private String mobile;
private LocalDateTime regDt;
}
//MemberMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mappers.MemberMapper">
<resultMap id="memberMap" type="exam01.Member">
<result column="USER_NO" property="userNo" />
<result column="USER_ID" property="userId" />
<result column="USER_PW" property="userPw" />
<result column="MOBILE" property="mobile" />
<result column="USER_NM" property="userNm" />
<result column="REG_DT" property="regDt" />
</resultMap>
<select id="getList" resultMap="memberMap">
SELECT * FROM MEMBER
</select>
<!--
<update id="">
</update>
<insert>
</insert>
<delete>
</delete>
-->
</mapper>
public interface MemberMapper {
List<Member> getList();
}
//test2에서
@Test
void test2() {
SqlSession session = DBConn.getSession();
MemberMapper mapper = session.getMapper(MemberMapper.class);
List<Member> members = mapper.getList();
members.forEach(System.out::println);
}
//인터페이스에서 구현
@Select("SELECT USER_NO, userNo, USER_ID useId FROM MEMBER")
List<Member> getList2();
//테스트 메서드에서
@Test
void test3() {
SqlSession session = DBConn.getSession();
MemberMapper mapper = session.getMapper(MemberMapper.class);
List<Member> members = mapper.getList2();
members.forEach(System.out::println);
}
SLF4j
slf4j-api : slf4j 가이드라인 (인터페이스 위주) 구현체X
logback-class 구현체
//mybatis-config.xml
<settings>
<setting name="logImpl" value="SLF4J"/>
</settings>
의존성의 하위 의존성은 상위 의존성만 설치해도 모두 설치된다.
https://mybatis.org/mybatis-3/ko/logging.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p %c{2} - %m%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="stdout"/>
</root>
<logger name="mappers">
<level value="DEBUG"/>
</logger>
</configuration>
로그 레벨
FATAL
ERROR -
WARN - 경고(오류 X, 문제 소지가 생길 가능성이 있는 경우)
INFO - 일반 정보
DEBUG - 자세한 정보
TRACE - 디버그보다 더 자세한 정보
//맵퍼 인터페이스에서
int register(Member member);
int modify(Member member);
int delete(String userId);
// 구현부에서
void test2() {
MemberMapper mapper = session.getMapper(MemberMapper.class); //멤버 맵퍼 객체를 생성
Member member = Member.builder()
.userId("USER01")
.userPw("123456")
.userNm("(수정)사용자01")
.mobile("01000000000")
.build();
//int cnt = session.update("mappers.MemberMapper.modify", member);
int cnt = mapper.modify(member);
System.out.println(cnt);
}
이런 식으로 간단하게 줄일 수 있음.
update 는
//memberMapper.xml
xml 파일에서 sql문법으로 구현했었다.
// 맵퍼 인터페이스에서
@Delete("DELETE FROM MEMBER WHERE USER_ID = #{userId}")
int delete2(String userId);
.xml에서 맵핑을 하는 것보다 간단하게 사용이 가능하다.
//구현부에서
@Test
void test4() {
MemberMapper mapper = session.getMapper(MemberMapper.class);
int cnt = mapper.delete("USER02");
int cnt2 = mapper.delete2("USER03");
System.out.println(cnt);
System.out.println(cnt2);
}
// 1번 방식
<insert id="register">
INSERT INTO MEMBER (USER_NO, USER_ID, USER_PW, USER_NM, MOBILE)
VALUES (SEQ_MEMBER.NEXTVAL, #{userId}, #{userPw}, #{userNm}, #{mobile})
</insert>
//2번 방식
<insert id="register2">
<selectKey keyProperty="userNo" order="BEFORE" resultType="long">
SELECT SEQ_MEMBER.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO MEMBER (USER_NO, USER_ID, USER_PW, USER_NM, MOBILE)
VALUES (#{userNo}, #{userId}, #{userPw}, #{userNm}, #{mobile})
</insert>
2번 방식을 이용할 경우 seq 넘버를 가져올 수 있다.
.xml에서 쿼리문을 작성할때 조건을 동적으로 정의한다.
<update id="modify">
UPDATE MEMBER
<set>
<if test="userPw != null">
USER_PW = #{userPw},
</if>
<if test="userNm != null">
USER_NM = #{userNm},
</if>
<if test="mobile != null">
MOBILE = #{mobile},
</if>
</set>
WHERE USER_ID = #{userId}
</update>
<trim>
prefix="where
SET
-> trim 태그 내부에 유효한 조건식이 하나라도 있으면 출력
prefixOverrides="AND + OR" -> 가장 앞쪽에 나와 있는 (WHERE바로 뒤) AND또는 OR 제거
suffixOverrides="," -> 마지막 ,는 제거
<where>
-> 아래 구문과 같음 (아래 구문 왜씀?)
<trim prefix="WHERE" prefixOVerrides="AND | or">
</trim>
set도 같음
<!--
<update id="modify">
UPDATE MEMBER
<trim prefix="SET" suffixOverrides=",">
<if test="userPw != null">
USER_PW = #{userPw},
</if>
<if test="userNm != null">
USER_NM = #{userNm},
</if>
<if test="mobile != null">
MOBILE = #{mobile},
</if>
</trim>
WHERE USER_ID = #{userId}
</update>
-->
<update id="modify">
UPDATE MEMBER
<set>
<if test="userPw != null">
USER_PW = #{userPw},
</if>
<if test="userNm != null">
USER_NM = #{userNm},
</if>
<if test="mobile != null">
MOBILE = #{mobile},
</if>
</set>
WHERE USER_ID = #{userId}
</update>
<select id="getList3" resultMap="memberMap">
<bind name="P_userNm" value="'%' + _parameter.getUserNm() + '%'" />
<bind name="P_mobile" value="'%' + _parameter.getMobile() + '%'" />
SELECT * FROM MEMBER
<where>
<if test="userId != null">
USER_ID = #{userId}
</if>
<if test="userNm != null">
AND USER_NM LIKE #{P_userNm}
</if>
<if test="mobile != null">
AND MOBILE LIKE #{P_mobile}
</if>
</where>
</select>
bind구문을 사용하면 %와 같은 기호를 항상 포함한 채로 sql 구문을 실행할 수 있다.
<select id="getList5">
SELECT * FROM MEMBER WHERE
<![CDATA[
USER_NO > #{userNo}
]]>
</select>