💡 간단 개념 정리
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 테이블을 연동하려고 한다.
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의 테이블 내에 존재하는 컬럼만을 필드로 가질 수 있다.
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문에는 조건을 걸 때 <, >, = 등의 기호를 많이 사용하게 되는데, 이것이 파싱 중에 태그로 인식되거나 하는 등의 문제가 생기는 것을 방지하기 위해 사용한다.
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);
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"));
}
}