[Spring Boot] 06. 간단한 MyBatis 연동

shr·2022년 2월 16일
1

Spring

목록 보기
6/23
post-thumbnail

💡 간단 개념 정리

Mapper (매퍼)
sql문을 담고 있는 xml 파일을 말한다. 매퍼를 사용하면 일일이 DAO를 만들지 않고 인터페이스만을 이용해 좀 더 편하게 코드를 작성할 수 있다.

@Mapper
매퍼 등록을 위해 인터페이스에 선언하여 사용한다.

@MapperScan
매퍼를 하나씩 등록하지 않고 패키지 경로를 지정하여 해당 패키지 하에 있는 인터페이스들을 전부 매퍼로 사용할 수 있게끔 한다.

Map
Key와 Value로 이루어진 자료 구조를 말한다. Key는 중복될 수 없지만, Value는 중복이 가능하다. Map의 종류도 다양한데, 우리는 HashMap을 쓴다. 사용 예시는 아래와 같다.

Map<String,Object> map = new HashMap<>();
map.put("id", "spring");
map.put("nai", 20);


DB의 위와 같은 emp 테이블을 연동하려고 한다.

  1. src/main/java - com.example.demo.entity - Emp 클래스 생성

    package com.example.demo.entity;
    
    import java.time.LocalDate;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public class Emp {
        private Integer empno;
        private String ename;
        private String job;
        private Integer mgr;
        private LocalDate hiredate;
        private Double sal;
        private Double comm;
        private Integer deptno;
    }

    Entity는 실제 DB의 테이블과 일대일 매핑되는 클래스로, DB의 테이블 내에 존재하는 컬럼만을 필드로 가질 수 있다.


  2. src/main/resources - mapper - empMapper.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.example.demo.dao.EmpDao">
    	<select resultType="emp" id="findAll"> <!-- 이게 application.properties에서 설정한 typeAlias -->
    		select * from emp
    	</select>
    	
    	<select resultType="emp" id="findById">
    		select * from emp where empno=#{empno} and rownum=1
    	</select>
    	
    	<!-- CDATA 영역은 xml이 아니라 그냥 글자라고 지정하는 영역 -->
    	<select resultType="string" id="findEnameBySalLessThan">
    		<![CDATA[
                          select ename from emp where sal<=#{sal}
                     	]]>
    	</select>
    	
    	<insert id="insert">
    		insert into emp(empno, ename, sal) values(#{empno}, #{ename}, #{sal})
    	</insert>
    	
    	<update id="update">
    		update emp set ename=#{ename}, sal=#{sal} where empno=#{empno}
    	</update>
    	
    	<delete id="delete">
    		delete from emp where empno=#{empno}
    	</delete>
    	
    	<select id="existsByUsername" resultType="boolean">
    		select count(empno) from emp where ename=#{ename}
    	</select>
    </mapper>

    <![CDATA[ ]]>
    [ ] 안의 문장은 파싱되지 않고 그대로 문자열로 출력된다. select문에는 조건을 걸 때 <, >, = 등의 기호를 많이 사용하게 되는데, 이것이 파싱 중에 태그로 인식되거나 하는 등의 문제가 생기는 것을 방지하기 위해 사용한다.


  3. src/main/java - com.example.demo.dao - EmpDao 인터페이스 생성

    package com.example.demo.dao;
    
    import java.util.List;
    import java.util.Map;
    
    import org.apache.ibatis.annotations.Mapper;
    
    import com.example.demo.entity.Emp;
    
    @Mapper
    public interface EmpDao {
      public List<Emp> findAll();
    
      public Emp findById(Integer empno);
    
      public List<String> findEnameBySalLessThan(Integer sal);
    
      public Integer insert(Emp emp);
    
      public Integer update(Emp emp);
    
      public Integer delete(Integer empno);
    
      public Boolean existsByUsername(String username);

  1. src/test/java - com.example.demo - EmpDaoTest 생성 후 테스트

    package com.example.demo;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    import static org.junit.jupiter.api.Assertions.assertNotNull;
    
    import java.util.List;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.example.demo.dao.EmpDao;
    import com.example.demo.entity.Emp;
    
    // 테스트를 하려면 설정 파일을 읽어들여 ApplicationContet를 생성
    @SpringBootTest
    public class EmpDaoTest {
        @Autowired
        private EmpDao empDao;
    
        // @Test
        public void findAllTest() {
            assertEquals(15, empDao.findAll().size());
        }
    
        @Test
        public void findByIdTest() {
            assertEquals(7369, empDao.findById(7369).getEmpno());
        }
    
        @Test
        public void findEnameTest() {
            List<String> list = empDao.findEnameBySalLessThan(3000);
            list.forEach(e->System.out.println(e));
            /*
                for(String e:list)
                    System.out.println(e);
            */
        }
    
        // 테스트할 때 변경 작업 후 작업 취소
        @Transactional
        @Test
        public void CRUDTest() {
            Emp emp = Emp.builder().empno(3333).ename("summer").sal(5000.0).build();
            empDao.insert(emp);
            emp.setSal(7000.0);
            empDao.update(emp);
            empDao.delete(3333);
        }
    
        @Test
        public void existsByUsernameTest() {
            System.out.println(empDao.existsByUsername("SMITH"));
            System.out.println(empDao.existsByUsername("HELL"));
        }
    }
    
profile
못하다 보면 잘하게 되는 거야 ・ᴗ・̥̥̥

0개의 댓글