[Spring Framework] 16강 - Mapper XML 파일 생성

seb Incode·2022년 4월 23일
0

Spring Framework

목록 보기
16/22
post-thumbnail

학습 내용

  • MaBatis Mapper XML

학습 목표

  • Mapper XML 파일의 구성을 이해하고 작성할 수 있다.
  • MyBatis 로깅을 적용하여 쿼리 로그를 확인한다.

Mapper XML 파일

MyBatis의 가장 큰 장점은 매핑파일

  • SQL문을 저장하는 존재를 매핑파일이라고 함
  • JDBC 코드에 비하면 코드수가 95% 이상 감소하기도 함
  • MyBatis는 SQL작성에 집중할 수 있도록 만들어짐

MaBtis Mapper파일을 만들 때는 mapper-dtd를 따릅니다. xml파일이다보니, 오타가 나면 작동이 안됩니다.. 그래서 STS의 경우 MyBatis 플러그인을 제공해서 편하게 작성할 수 있도록 도와줍니다.

<select id="getUser" resultMap="usermap">
  select * from users
</select>
<insert id="insert">
  insert into users(id, name, funkyNumber, roundingMode) values(#{id}, #{name}, #{funkyNumber}, #{roundingMode})
</insert>

Mapping 파일 내에 SQL문 작성 예시입니다.

참고로 MyBatis는 데이터 타입을 Java 타입에 맞게 자동으로 매핑해줍니다.

XML Mapper 작성

DAO 클래스가 작성되면 이를 사용하는 SQL문 작성이 필요

작성 순서

  1. XML로 작성된 Mapper의 위치(저장경로) 설정
  2. XML Mapper 파일을 작성하고 필요한 DTD 추가(템플릿 파일 사용)
  3. SQL 작성

Mapper파일들 저장 경로는 우리가 지난 실습에 폴더를 하나 생성해놨습니다. 일반적으로도 이 방법으로 파일들을 모아놓습니다.

Mapper XML :: select

select

  • MyBatis에서 가장 많이 사용하는 엘리먼트
  • 어플리케이션은 데이터를 수정하는 기능보다 데이터 조회를 주로 함
  • MyBatis는 데이터를 조회하는 기능에 집중함
<select id="selectPerson" parameterType="int" resultType="hashmap">
  select * from person where id=#{id}
</select>
  • 위 쿼리의 의미는, 이름은 selectPerson 파라미터는 int이고 결과 데이터는 HashMap에 저장됨
//JDBC 코드와 유사함, 마이바티스 코드는 아님...
String selectPerson = "select * from person where id=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1, id);

MyBatis에서 select 기능 관련 개념

  • parameterType : 쿼리문 파라미터 데이터 타입
  • resultType : 쿼리 결과 반환 받을 때 데이터 타입

DB로부터 데이터를 리턴 받을 때 하나의 레코드를 리턴 받으면 VO 즉, 객체로 바인딩 해서 받고
여러 개의 레코드를 리턴 받으면 리스트 형태로 바인딩해서 리턴 받습니다.
위의 예시는 한 사람에 대한 정보이기 때문에 hashmap으로 받습니다.

select 엘리먼트 세부 속성

<select
        id="selectPerson"
        parameterType="int"
        parameterMap="deprecated"
        resultType="hashmap"
        resultMap="personResultMap"
        flushCache="false"
        useCache="true"
        timeout="10000"
        fetchSize="256"
        statementType="PREPARED"
        resultSetType="FORWARD_ONLY">
  • id : 쿼리문의 이름
  • parameterType : 쿼리문에 파라미터가 있을 경우, 적는 데이터 타입
  • parameterMap : 더이상 사용하지 않는 속성, parameterType이 대체중
  • resultType : 반환받을 데이터 타입, 클래스, 리스트 등등 가능
  • resultMap : 컬럼명과 객체 변수명이 다를경우, 수동으로 설정하는 속성

insert, update and delete

상대적으로 간단함

<insert
        id="insertAuthor"
        parameterType="domian.blog.Author"
        flushCache="true"
        statementType="PREPARED"
        keyProperty=""
        keyColumn=""
        useGeneratedKeys=""
        timeout="20">
<!---->
<update
        id="updateAuthor"
        parameterType="domain.blog.Author"
        flushCache="true"
        statementType="PREPARED"
        timeout="20">
<!---->
<delete
        id="deleteAuthor"
        parameterType="domain.blog.Author"
        flushCache="true"
        statementType="PREPARED"
        timeout="20">

insert, update, delete는 돌아오는 데이터가 없기 때문에 resultType 속성 지정이 필요 없습니다.

insert, update, delete 예제

<insert id="insertAuthor">
  insert into Author (id, username, password, email, bio)
            values (#{id}, #{username}, #{password}, #{email}, #{bio})
</insert>
<update id="updateAuthor">
  update Author
  set username=#{username},
  password=#{password},
  email=#{email},
  bio=#{bio}
  where id=#{id}
</update>
  • MS-SQL, MySQL의 경우 KeyProperty 설정(id column이 생략되면 key 자동 생성됨)

< SQL >

  • 다른 구문에서 재사용 가능한 SQL 구문을 정의함
<sql id="userColumns"> id, username, password </sql>
  • 다른 구문에서 사용
<select id="selectUsers" resultType="map">
  select <include refid="userColumns" />
  from some_table
  where id=#{id}
</select>

sql 태그 기능을 제공하는데 재밌습니다.
쿼리 일부분을 미리 정의해둘 수 있는 기능입니다.
정의한 쿼리문을 사용할 때는 include 태그를 사용하시면 됩니다.

Parameters

  • 쿼리의 파라미터
  • PreparedStatement의?
<select id="selectUsers" resultType="kr.co.acompp.hello.VO.User">
  select id, username, password
  from users
  where id=#{id}
</select>
  • 전달되는 객체에 따라 파라미터의 타입이 결정된다.
  • 좀 더 복잡한 파라미터의 경우
<insert id="insertUser" parameterType="kr.co.acompp.hello.VO.User">
  insert into users
  (id, username, password)
  values (#{id}, #{username}, #{password})
</insert>
  • User 타입의 파라미터가 전달됨. 각 멤버변수가 파라미터의 이름이 됨

parameterType으로 객체를 쓰려면 풀 패키지 명을 써야 합니다.

Result Maps

  • MyBatis에서 가장 중요하고 강력한 요소
  • 데이터베이스에서 데이터를 가져올 때 작성되는 JDBC 코드를 대부분 줄여주는 역할
<select id="selectUsers" resultMap="UserMap">
  select user_id, user_name, user_password
  from users
  where id=#{id}
</select>
  • 위 쿼리는 아래의 resultMap에 저장된다.
<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name" />
  <result property="password" column="user_password" />
</resultMap>

select문에서 사용하는 resultMap 속성 설명입니다.
resultMap 태그로 별도로 하나 정의를 해둡니다.
내용은 User 클래스와 DB 컬럼을 각각 매핑 시켜줍니다. 이름이 다르니까 이렇게 수동으로 바인딩 해줘야 합니다.

Mybatis 로깅 :: log4jdbc-log4j2

MyBatis의 로그를 보다 자세히 확인 가능하게 해줌

  • Log4jdbc-log4j2 라이브러리 의존성 추가

데이터 소스 변경

<bean id="dataSource" class="org.springframework.datasource.SimpleDriverDataSource">
  <property name="driverClass" value="net.sflog4jdbc.sql.jdbcapi.DriverSpy" />
  <property name="url" value="jdbc:log4jdbc:mysql://127.0.01:3306/spring" />
  <property name="username" value="root" />
  <property name="password" value="spring" />
</bean>
  • JDBC 드라이버 클래스 net.sf.log4jdbc.DriverSpy로 변경
  • 연결 URL 중간에 'log4jdbc' 라는 단어 추가
  • log4jdbc.log4j2.properties 파일 추가

먼저, Log4jdbc-log4j2 라이브러리를 pom.xml에 추가하시면 됩니다.
그리고 dataSource.xml에서 소스를 변경하면 됩니다.

운영시에는 오버헤드 때문에 권장되지 않습니다.

실습

1. 게시판 글 insert, select 구현

↑ select문과 insert문을 작성합니다.
[설명]

  • id : 일반적으로 DAO 메소드와 똑같이 작성한다.
  • parameterType : 풀 패키지명 포함해서 작성해야 한다.
  • resultType : 풀 패키지명 포함해서 작성해야 한다.
    위 select문의 경우는 한 게시글의 id값만 전달하기 때문에 String으로 썼습니다.
    💜잠~깐~만💜
    select 쿼리문 보면 article_id as articleId 라고 했습니다.
    그 이유는 VO 객체 변수명과 DB 컬럼명이 맞지 않아서 저렇게 선언한겁니다. 아까 이론 얘기할 때 reseultMap 언급했었는데 이 실습은 다음 포스팅에 있습니다~

↑ DAO클래스에서 SqlSession 참조 객체를 선언하고 자동 DI 어노테이션을 붙여줍니다.
↑ SqlSession 참조 객체의 메소드들을 이용해서 쿼리문 실행을 요청합니다.

0개의 댓글