MyBatis-Plus 핵심 기능과 활용법 정리

시작하기 전에: 필요한 사전 지식

MyBatis-Plus를 학습하기 위해서는 먼저 아래 기술 스택을 익히는 것이 중요합니다:

  • MyBatis
  • Spring 프레임워크
  • Spring MVC

이러한 기초가 탄탄해야 MyBatis-Plus의 편의성과 확장성을 제대로 이해하고 활용할 수 있습니다.

왜 MyBatis-Plus를 사용하는가?

개발 과정에서 반복적인 CRUD 작업은 시간과 노력을 많이 소모합니다. MyBatis-Plus는 이러한 문제를 해결하기 위해 설계된 강력한 ORM 도구입니다. JPA, tk-mybatis 등과 마찬가지로 개발 생산성을 높이는 목적을 가지고 있으며, 다음과 같은 장점을 제공합니다:

  • 기존 코드에 영향 없이 기능을 확장 (무침투성)
  • 자동화된 기본 쿼리 생성
  • 코드 양 감소 및 유지보수 용이성 향상

공식 사이트 및 문서

자세한 정보는 공식 문서를 참고하세요: https://baomidou.com

주요 특징

  • 무침투 아키텍처: 기존 프로젝트에 영향을 주지 않으며, 의존성 추가만으로 기능을 사용할 수 있습니다.
  • 고성능: 기본 CRUD 메서드는 시작 시 자동 주입되며 성능 저하가 거의 없습니다.
  • 강력한 조건 쿼리 지원: QueryWrapper 등을 통해 복잡한 조건도 간결하게 표현 가능.
  • Lambda 표현식 지원: 필드 이름 오타 방지를 위해 메서드 참조 기반 쿼리 작성이 가능합니다.
  • ID 자동 생성: Snowflake 알고리즘 기반의 분산 고유 ID 생성을 포함하여 다양한 전략 제공.
  • ActiveRecord 모드: 엔티티 클래스가 Model을 상속하면 객체 기반 CRUD 연산이 가능해집니다.
  • 코드 생성기 내장: Mapper, Service, Controller 등의 코드를 자동 생성하여 초기 개발 시간 단축.
  • 물리적 페이징 플러그인: 데이터베이스 종류에 맞는 최적화된 페이징 쿼리를 자동 생성합니다.
  • SQL 성능 분석: 실행 시간이 긴 쿼리를 로그로 출력하여 성능 병목 탐지에 유용합니다.
  • 전역 인터셉터: 잘못된 전체 삭제나 업데이트 작업을 차단할 수 있어 안정성 향상.

빠른 시작 가이드

  1. 데이터베이스 생성
    DROP TABLE IF EXISTS user;
    
    CREATE TABLE user (
        id BIGINT NOT NULL COMMENT '기본 키',
        name VARCHAR(30) NULL DEFAULT NULL COMMENT '이름',
        age INT NULL DEFAULT NULL COMMENT '나이',
        email VARCHAR(50) NULL DEFAULT NULL COMMENT '이메일',
        PRIMARY KEY (id)
    );
    샘플 데이터 삽입:
    INSERT INTO user (id, name, age, email) VALUES
    (1, 'Jone', 18, 'test1@baomidou.com'),
    (2, 'Jack', 20, 'test2@baomidou.com'),
    (3, 'Tom', 28, 'test3@baomidou.com');
  2. Spring Boot 프로젝트 설정

    의존성 추가 (Maven):

    <dependencies>
        <!-- MySQL 드라이버 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    
        <!-- MyBatis-Plus Starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
    </dependencies>

    주의: mybatis와 mybatis-plus를 동시에 사용하지 마세요. 충돌 가능성 있음.

  3. application.yml 설정
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
        username: root
        password: your_password
        driver-class-name: com.mysql.cj.jdbc.Driver
    
    # MyBatis-Plus 로깅 활성화
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  4. 엔티티 클래스 작성
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
  5. Mapper 인터페이스 정의
    @Repository
    public interface UserMapper extends BaseMapper<User> {
        // BaseMapper를 상속함으로써 자동으로 CRUD 메서드 제공
    }

    부트스트랩 클래스에 스캔 어노테이션 추가:

    @SpringBootApplication
    @MapperScan("com.example.mapper")
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
  6. 테스트 코드 작성
    @SpringBootTest
    class UserMapperTest {
    
        @Autowired
        private UserMapper userMapper;
    
        @Test
        void testSelectAll() {
            List<User> users = userMapper.selectList(null);
            users.forEach(System.out::println);
        }
    }

기본 CRUD 확장 기능

1. 데이터 삽입 및 ID 전략

기본적으로 ID_WORKER (Snowflake 기반) 전략을 사용합니다. 자동 증가를 원할 경우:

@Data
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    // ...
}

DB의 해당 컬럼도 AUTO_INCREMENT로 설정되어야 합니다.

2. 업데이트 작업

@Test
void testUpdate() {
    User user = new User();
    user.setId(2L);
    user.setName("Updated Name");
    userMapper.updateById(user);
}

MyBatis-Plus는 null 필드는 업데이트하지 않으며, 실제로 변경된 값만 반영됩니다.

3. 자동 필드 채우기 (생성일/수정일)

실제 운영 환경에서는 등록일과 수정일을 자동 관리하는 것이 좋습니다.

@Data
public class User {
    // ...

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

핸들러 클래스 작성:

@Component
@Slf4j
public class AutoFillHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }
}

4. 논리 삭제 (Soft Delete)

물리적 삭제 대신 상태 값으로 삭제 여부를 표시합니다.

-- 테이블에 deleted 컬럼 추가
ALTER TABLE user ADD COLUMN deleted TINYINT DEFAULT 0;

엔티티에 어노테이션 추가:

@TableLogic
private Integer deleted;

설정 파일에 전역 설정 추가:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1
      logic-not-delete-value: 0

이후 모든 삭제 쿼리는 UPDATE로 변환되고, 조회 시 deleted = 0인 레코드만 반환됩니다.

5. 낙관적 락 (Optimistic Locking)

동시성 제어를 위한 버전 번호 기반 메커니즘입니다.

-- version 컬럼 추가
ALTER TABLE user ADD COLUMN version INT DEFAULT 1;

엔티티에 추가:

@Version
private Integer version;

인터셉터 등록:

@Configuration
@MapperScan("com.example.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

6. 조건 쿼리 (QueryWrapper)

@Test
void testQueryWrapper() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();

    // 이름이 null이 아니고 이메일이 포함된 조건
    wrapper.isNotNull("name")
           .like("email", "test")
           .ge("age", 18);

    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

코드 자동 생성기 (Code Generator)

MyBatis-Plus는 코드 생성기를 제공하여 반복적인 코드 작성을 줄여줍니다.

public class CodeGenerator {

    public static void main(String[] args) {
        FastAutoGenerator.create(
                "jdbc:mysql://localhost:3306/mybatis_plus", "root", "password")
            .globalConfig(builder -> {
                builder.author("developer") // 작성자
                       .outputDir(System.getProperty("user.dir") + "/src/main/java"); // 출력 경로
            })
            .packageConfig(builder -> {
                builder.parent("com.example")
                       .moduleName("demo")
                       .entity("model")
                       .mapper("mapper")
                       .service("service")
                       .controller("controller");
            })
            .strategyConfig(builder -> {
                builder.entityBuilder()
                       .enableLombok()
                       .logicDeleteColumnName("deleted")
                       .versionColumnName("version");
                builder.mapperBuilder()
                       .enableBaseResultMap()
                       .enableBaseColumnList();
                builder.serviceBuilder()
                       .formatServiceFileName("%sService");
                builder.controllerBuilder()
                       .enableRestStyle();
                builder.addInclude("user"); // 생성할 테이블 지정
            })
            .execute();
    }
}

이 방식을 사용하면 엔티티, 매퍼, 서비스, 컨트롤러 코드를 몇 초 만에 생성할 수 있습니다.

태그: MyBatis-Plus Spring Boot jpa ORM 코드자동생성기

6월 19일 00:29에 게시됨