Spring - MyBatis 사용 순서 / @Mapper / @MapperScan / Java에서 MyBatis로 파라미터 전달

S.Sun·2024년 4월 11일

스프링

목록 보기
8/17

질문 내용

오전

  1. 마이바티스를 사용하는 순서는?
  2. 아래 @를 설명하시오.
  • @Mapper
  • @MapperScan

오후

  1. 자바에서 마이바티스(xml)로 파라미터 전달 방법은?
  2. Dept insert 와 remove 를 구현하시오.

개인 작성

Spring Starter Project를 이용해 수업 시간에 진행한 방식

- Mybatis 라이브러리를 pom.xml에 추가(의존성 관리 도구에 라이브러리 추가)

설치된 상태인지 확인하기.

- application.properties에 설정 추가(데이터베이스 설정 및 마이바티스 설정 추가. 스샷은 마이바티스 설정만 찍음.)

  • @MapperScan() 추가
  • @Mapper() 추가

  • unit test 진행

    콘솔창 확인. @Slf4j를 사용한 상태 + log 출력.


GPT 답변

  • 의존성 추가: 먼저 프로젝트의 의존성 관리 도구(예: Maven, Gradle)를 사용하여 마이바티스 라이브러리를 프로젝트에 추가

  • 매퍼 인터페이스 작성: 데이터베이스와 상호작용하는 메서드를 정의한 매퍼 인터페이스를 작성

  • 매퍼 XML 파일 작성: 매퍼 인터페이스의 메서드에 대응하는 SQL 쿼리를 작성하고, 결과를 자바 객체에 매핑하는 정보를 포함한 XML 파일을 작성

  • SqlSessionFactory 설정: 데이터베이스 연결과 관련된 설정을 포함한 SqlSessionFactory를 설정

  • 매퍼 인터페이스와 SqlSessionFactory 연결: 매퍼 인터페이스와 SqlSessionFactory를 연결하여 사용할 수 있도록 설정

  • 매퍼 인터페이스 사용: 매퍼 인터페이스의 메서드를 호출하여 데이터베이스와 상호작용하기


해당 부분에 대해 찾아본 참조링크
[MyBatis] 동작원리, 사용방법 정리
[MyBatis] 마이바티스 기본 사용법


  • @Mapper
    - Mapper Interface를 지정할 때 사용됨
    - @MapperScan을 사용하는 경우에는, 매퍼 인터페이스에 해당 에너테이션을 매퍼 파일에 사용하지 않아도 된다. 그러나 개발자들이 자체적으로 구분하기 위해 사용한다고 한다.
    - 해당 에너테이션이 붙어 있으면, 마이바티스의 매퍼로 인식하여 해당 매퍼를 구현한 객체를 생성.
  • @MapperScan
    - Mapper Interface를 스캔 및 bean으로 등록하는데 사용됨
    - 해당 에너테이션이 붙어 있으면, 특정 패키지 내 매퍼 인터페이스를 찾아 자동으로 스프링 빈 등록.

참조하기 좋은 사이트 : MyBatis 공식 사이트 설명 - Mapper XML 파일


  • 매퍼 XML 파일에서는 파라미터를 사용할 위치에 #{} 문법을 사용하여 파라미터를 정의
    - Spring Boot 애플리케이션에서는 일반적으로 MyBatis와 함께 사용할 때 SqlSession을 직접 다루지 않고, 매퍼 인터페이스를 사용하여 데이터베이스 작업을 수행
    -> Spring Boot가 자동으로 SqlSession을 관리하고 매퍼 인터페이스에 매핑해주기 때문
    <insert id="insert" parameterType="edu.sejong.ex.vo.DeptVo" >
    	<![CDATA[
        	insert into dept(deptno, dname, loc) values(#{deptno},#{dname},#{loc})
        ]]>
    </insert>
  • 자바 코드에서는 MyBatis의 SqlSession 객체를 사용하여 SQL 쿼리를 실행할 때 파라미터를 전달
    - SqlSession의 메서드 중 select, insert, update, delete 등의 메서드를 호출할 때 파라미터를 전달
    - 파라미터는 해당 메서드의 두 번째 매개변수로 전달
    - 해당 코드 예시는 Spring Boot에서 MyBatis를 사용할 때 내장된 SqlSession 빈 객체를 사용하지 않고, 외부에서 주입된 SqlSession을 사용할 때 활용되는 예시
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class DeptRepository {

    private final SqlSession sqlSession;

    @Autowired
    public DeptRepository(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    public void insertDept(DeptVo deptVo) {
        sqlSession.insert("edu.sejong.ex.mapper.DeptMapper.insertDept", deptVo);
    }

    public void deleteDept(int deptno) {
        sqlSession.delete("edu.sejong.ex.mapper.DeptMapper.deleteDept", deptno);
    }
}

기존에 이미 작성된 파일을 수정하는 것이다.

  • 수정되는 파일만 수록.
  • 테스트 파일은 DeptMapperTest.java만 수록. 나머지는 미수록.

DeptMapper.java - 맵퍼 파일

package edu.sejong.ex.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import edu.sejong.ex.vo.DeptVo;

@Mapper
public interface DeptMapper {
	List<DeptVo> selectList();	
	void insert(DeptVo deptVo);
	void delete(DeptVo deptVo);
}

DeptMapperTest.java - 테스트 파일

package edu.sejong.ex.mapper;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import edu.sejong.ex.vo.DeptVo;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootTest
class DeptMapperTest {

	@Autowired
	private DeptMapper deptMapper;
	
	@Test
	void test() {
		assertNotNull(deptMapper);
	}
	
	@Test
	void testSelectList() {
		for(DeptVo dept : deptMapper.selectList()) {
			log.info("부서번호 : " + dept.getDeptno());
			log.info("부서이름 : " + dept.getDname());
			log.info("부서위치 : " + dept.getLoc());			
		}	
	}

	@Test
	void testInsert() {
		deptMapper.insert(new DeptVo(11, "홍콩", "마오이"));
		for(DeptVo dept : deptMapper.selectList()) {
			log.info("부서번호 : " + dept.getDeptno());
			log.info("부서이름 : " + dept.getDname());
			log.info("부서위치 : " + dept.getLoc());			
		}	
	}

	@Test
	void testDelete() {
		deptMapper.delete(new DeptVo(11, "홍콩", "마오이"));
		for(DeptVo dept : deptMapper.selectList()) {
			log.info("부서번호 : " + dept.getDeptno());
			log.info("부서이름 : " + dept.getDname());
			log.info("부서위치 : " + dept.getLoc());			
		}	
	}
}

DeptMapper.xml - 맵퍼 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="edu.sejong.ex.mapper.DeptMapper">
    <select id="selectList" resultType="edu.sejong.ex.vo.DeptVo">
    	<![CDATA[
        	select * from dept
        ]]>
    </select>
    <insert id="insert" parameterType="edu.sejong.ex.vo.DeptVo" >
    	<![CDATA[
        	insert into dept(deptno, dname, loc) values(#{deptno},#{dname},#{loc})
        ]]>
    </insert>
    <delete id="delete" parameterType="edu.sejong.ex.vo.DeptVo">
    	<![CDATA[
        	delete from dept where deptno = #{deptno}
        ]]>
    </delete>
</mapper>

DeptServiceImpl.java - 서비스 파일

package edu.sejong.ex.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import edu.sejong.ex.mapper.DeptMapper;
//import edu.sejong.ex.repository.DeptRepository;
import edu.sejong.ex.vo.DeptVo;

// @Component + 의미(Command) 
@Service 
public class DeptServiceImpl implements DeptService {

//	@Autowired
//	private DeptRepository deptRepository;
	
	@Autowired
	private DeptMapper deptMapper;
	
	@Override
	public List<DeptVo> getList() {
		System.out.println("getList()..");
		return deptMapper.selectList();
//		return deptRepository.selectList();		
	}

	@Override
	public void register(DeptVo deptVo) {
		System.out.println("register()..");
		deptMapper.insert(deptVo);
//		deptRepository.insert(deptVo);
	}
//
	@Override
	public void erase(DeptVo deptVo) {
		System.out.println("erase()..");
		deptMapper.delete(deptVo);
//		deptRepository.delete(deptVo);		
	}

}
profile
두리둥둥

0개의 댓글