Java - mybatis

김정현·2024년 5월 26일
0

JAVA

목록 보기
25/25

마이바티스 프레임워크 설치 밎 적용

1. 설치

mybatis3.xx

-공식 메뉴얼
https://mybatis.org/mybatis-3/ko/getting-started.html

2. 기초 설정

  • 의존성 설치
    (버전 스크린샷 첨부 안 했을 경우 최신버전)

// annotationProcessor도 추가

  • mybatis 설정

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;
}

  • SqlSessionFactory
    -> SqlSession 객체 생성
    -> insert(...)
    -> delete(...)
    -> List<T> selectList(...)
    -> T selectOne(...) getMapper(class ..)
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, UPDATE, INSERT, DELETE 간단하게 구현

//인터페이스에서 구현

 @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>
  • %d: 로그 기록 시점(날짜, 시간)
  • %p: 로그레벨 5p -> 5글자내에서 로그레벨을 표기
  • %m: 로그 메세지
  • %n: 줄개행
  • %c: 패키지명을 포함한 전체 클래스명
    %c{2} -> 패키지명은 한자로 축약, 클래스명은 전체이름

로그 레벨

FATAL
ERROR -
WARN - 경고(오류 X, 문제 소지가 생길 가능성이 있는 경우)
INFO - 일반 정보
DEBUG - 자세한 정보
TRACE - 디버그보다 더 자세한 정보

인터페이스 update, insert, delete, select 추상 메서드 추가

//맵퍼 인터페이스에서

 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("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 넘버를 가져올 수 있다.

동적 sql

if

.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, where, set

<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>

bind

<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>

0개의 댓글