코딩마을방범대

MyBatis 기본 세팅과 활용 본문

💡 백엔드/Java

MyBatis 기본 세팅과 활용

신짱구 5세 2023. 5. 25. 13:32
728x90

 

MyBatis란

  • 자바 오브젝트와 SQL사이의 자동 매핑 기능을 지원하는 ORM(Object relational Mapping)프레임워크
  • SQL쿼리들을 한 구성파일(xml)에 구성하여 프로그램 코드와 SQL문을 분리할 수 있음
  • 데이터소스(DataSource) 기능과 트랜잭션 처리 기능을 제공

 

특징

  • SQL문을 그대로 사용하여 커스터마이징한 sql문 구성이 가능함
  • 비슷한 쿼리는 여러 번 사용할 수 밖에 없음

 


 

주요 컴포넌트

MyBatis 설정파일

  • 고정된 환경정보를 설정(데이터베이스의 접속 주소 정보나 Mapping 파일의 경로 등)
    (예:SqlMapConfig.xml)

SqlSessionFactoryBuilder

  • MyBatis 설정 파일을 바탕으로 SqlSessionFactory를 생성

SqlSessionFactory

  • SqlSession 객체를 실행하는 팩토리 클래스(인터페이스)

SqlSessionFactoryBean

  • config 파일을 바탕으로 SqlSessionFactory를 생성하는 클래스

SqlSession

  • mapper.xml에 등록된 SQL문을 실행하고 트랜잭션을 관리하는 클래스
    (인터페이스, Thread-not-safe하여 싱글쓰레드환경에 적합하고, 쓰레드를 매번 생성해야 함)

SqlSessionTemplate

  • SqlSession 인터페이스를 상속받아 구현된 클래스이며, 실제 SQL 및 트랜잭션을 실행
    (Thead-safe하여 멀티쓰레드환경에도 안전)

Mapping 파일

  • SQL문 작성
    (예:user.xml)

 

 

 


 

 

 

 

 

MyBatis 사용법

 

 

application.yml

  • type-aliases-package
    • com.그룹명.패키지명.세부경로 대신 설정된 경로에서 모델을 찾음
      예) com.group.package.model.UserRequest ⇒ UserRequest
mybatis:
  # mapper.xml 경로(resources 안의 mapper.xml 담을 폴더명)
  mapper-locations:
    - classpath:mappers/*.xml
  # config.xml 경로
  config-location:
    - classpath:*.xml
  # DTO, VO 등의 도메인 클래스가 포함된 패키지 경로
  # 이 항목을 설정하지 않으면 mapper.xml에서 DTO, VO를 사용할 때 패키지 경로를 모두 작성해야 함
  type-aliases-package: com.group.package
  # Mybatis의 SQL 문에 null을 파라미터로 전송할 수 있게 해줌
configuration:
  jdbc-type-for-null: null

 

 


 

config.xml

  • typeAliases
    • application.yml의 type-aliases-package와 비슷한 방법이며, 정확한 명칭을 정해주는 세팅 방법
<?xml version="1.0" encoding="UTF-8"?>
http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="userRequest" type="com.group.package.model.UserRequest"/>
    </typeAliases>
</configuration>

 

 


 

mapper.xml (Mapping 파일)

  • namespace
    • mapper.interface의 경로를 지정
<?xml version="1.0" encoding="UTF-8"?>
http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.group.package.UserMapper">
<!--
        실행할 sql 문들
        id: 선언 시 사용할 이름
        parameterType: String, model 경로 기입
        resultType: 반환 받을 타입 기입
-->
    <select id="find" parameterType="String" resultType="UserResponse">
        select id, mem_name, pw
        from user
        where id = #{id} and mem_name = #{name}
    </select>
    <insert id="create" parameterType="com.group.package.model.UserRequest">
        insert into user(id, mem_name, phone_num, pw)
        values (#{id}, #{memName}, #{phoneNum}, #{pw})
    </insert>
</mapper>

 

 


 

 

Mapper.interface

  • Mapper Interface를 스프링 빈으로 주입받아 DB에 접근하는 방법
  • 직접 SqlSessionDaoSupport 나 SqlSessionTemplate 를 사용
@Mapper
public interface UserMapper {
    // xml에 적었던 sql문들에 대한 id를 통해 선언
    Optional<UserResponse> find(String id, String name);
    boolean create(UserRequest request);
}

 

🎃 mapper.xml 없이 Mapper 인터페이스 상에서 어노테이션을 이용하는 방법

@Mapper
public interface BoardMapper  {
    @Insert("insert into user (id, name) values (#{id}, #{name})")
    void create(UserRequest request) throws Exception;
}

 

 


 

 

Service

@Service
public class UserService {
    // 생성자를 통해 Autowired 역할 해주기
    private final SqlSession sqlSession;
    public UserService(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }
    public void test(Request request){
         sqlSession.getMapper(UserMapper.class).find(request)
    }
}

 

 

 

 

 


 

 

 

 

 

 

💡 TIP!

 

1. varchar와 char의 차이

CHAR

  • 경우에 따라 데이터가 낭비될 수 있음
  • 추후 연산이 필요 없기 때문에 검색속도 및 읽히는 속도가 VARCHAR에 비해 빠름
  • insert 후 남은 부분을 공백으로 채움

VARCHAR

  • 입력받은 데이터의 크기가 작을 경우, 그 크기만큼만 메모리를 차지하므로 메모리 사용량을 줄일 수 있음
  • 현재 차지하고 있는 영역이 얼마인지 확인하고, 부족한 경우 더 할당하고 남으면 줄여서 insert

max size limit 가능 여부
VARCHAR: 있다, 1~65535
TEXT: 없다, only 65535

 

Type Description Byte
CHAR 고정형 n ≤ 255
VARCHAR 가변형 n ≤ 65535
TEXT 가변형 n ≤ 65535



 


 

 

 

2. Optional의 orElse와 orElseGet의 차이점

public T orElse(T other)

public T orElseGet(Supplier<? extends T> other)

 

orElse

  • null일 때 값을 넘겨야 할 때
  • 메소드를 인수로 받지 않고, 값을 인수로 받음

orElseGet

  • null일 경우 메소드를 실행해야 할 때
  • 인수로 전달된 Supplier 메소드 경우 Optional의 값이 없을 때만 get()을 통해 실행

Supplier은 함수적 인터페이스로서 get을 호출하여 결과를 리턴하는 역할
매개변수를 받지 않고 단순히 반환함

 

 

728x90