its_jh_stroy

[Springboot] MyBatis 사용해보기 본문

Java

[Springboot] MyBatis 사용해보기

_J_H_ 2024. 6. 17. 23:10

MyBatis

SQL 문과 객체를 매핑하여 관계형 데이터베이스를 쉽게 사용할 수 있도록 지원하는 프레임워크

매퍼라는 파일을 통해 쿼리를 작성한다.

 

데이터베이스 구성하기

먼저 데이터베이스에서 테이블을 구성할 것이다.

mybatis에 집중할 수 있도록 최대한 간단하게 구성하였다.

CREATE TABLE employee (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    salary INT
);

 

 

프로젝트 구조 생성하기

실습에 사용될 DTO, Controller, Service, Repository를 생성할 것이다.

아래와 같은 이름으로 생성했고, 편의를 위해 동일한 경로에 생성하였다.

- EmployeeDTO

- EmployeeController

- EmployeeService

- EmployeeRepository

 

MySQL 데이터베이스와 연결하기

application.properties 또는 application.yml 파일에 데이터베이스와 MyBatis에 관련된 내용을 작성한다.

아래는 application.yml 형식으로 작성한 내용이다.

# database
# 포트가 3306인 MySQL에서 testdb 사용
# 접속 계정은 root / 1111이라고 가정
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/testdb?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
    username: root
    password: 1111

# MyBatis
# 매퍼와 MyBatis 설정 파일 위치 지정
mybatis:
  mapper-locations: classpath:mapper/*.xml
  config-location: classpath:mybatis-config.xml

 

 

mybatis 설정 파일 구성( mybatis-config.xml)

application.yml에서 지정한 설정 파일인 mybatis-config.xml을 생성한다.

생성 위치는 입력한 "config-location: classpath:mybatis-config.xml"에 따라 application.yml과 동일한 경로에 생성하였다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC
        "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <!-- com.employee.EmployeeDTO 클래스에 대해 employee 별칭 지정 -->
        <!-- 지정된 별칭은 매퍼 파일에서 사용할 수 있다. -->
        <typeAlias type="com.myprj.employee.EmployeeDTO" alias="employee"></typeAlias>
    </typeAliases>
</configuration>

 

 

SqlSessionTemplate 클래스 알아보기

매퍼 파일에 작성한 쿼리를 실행할 때는 SqlSessionTemplate 클래스를 활용한다.

관련 메서드는 아래와 같다.

- insert / update / delete

- selectList / selectOne

매퍼 파일과 코드 작성하기

사용할 쿼리를 매퍼 파일에 작성한다.

각 쿼리에 대해 id와 반환 타입, 파라미터 타입과 같은 항목을 지정한다.

소스에서는 namespace와 id를 통해 쿼리를 호출할 것이다.

<?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="Employee">
    <select id="findAll" resultType="employee">
        select id, name, salary
        from employee order by id
    </select>

    <select id="findById" parameterType="Long" resultType="employee">
        select id, name, salary
        from employee where id=#{id}
    </select>

    <insert id="save" parameterType="employee" useGeneratedKeys="true" keyProperty="id">
        insert into employee(name, salary)
        values(#{name}, #{salary})
    </insert>

    <update id="update" parameterType="employee">
        update employee
        set name = #{name}, salary = #{salary}
        where id = #{id}
    </update>

    <delete id="delete" parameterType="Long">
        delete from employee where id = #{id}
    </delete>
</mapper>

 

 

EmployeeDTO.java

편의를 위해 lombok을 설치하여 작성하였다.

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class EmployeeDTO {
    private Long id;
    private String name;
    private int salary;
}

 

 

EmployeeController.java

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    // http://localhost:8080/list
    @GetMapping("/list")
    public List<EmployeeDTO> findAll() {
        return employeeService.findAll();
    }

    // http://localhost:8080/list/3
    @GetMapping("/list/{id}")
    public EmployeeDTO findById(@PathVariable("id") Long id) {
        return employeeService.findById(id);
    }

    // http://localhost:8080/save
    // { "name": "kim","salary": 200 }
    @PostMapping("/save")
    public void save(@RequestBody EmployeeDTO employeeDTO) {
        employeeService.save(employeeDTO);
    }

    // http://localhost:8080/update
    // { "id": 1, "name": "lee", "salary": 300 }
    @PostMapping("/update")
    public void update(@RequestBody EmployeeDTO employeeDTO) {
        employeeService.update(employeeDTO);
    }

    // http://localhost:8080/delete
    // { "id": 2 }
    @PostMapping("/delete")
    public void delete(@RequestBody EmployeeDTO employeeDTO) {
        employeeService.delete(employeeDTO.getId());
    }
}

 

EmployeeService.java

@Service
public class EmployeeService {
    @Autowired
    private EmployeeRepository employeeRepository;

    public List<EmployeeDTO> findAll() {
        return employeeRepository.findAll();
    }

    public EmployeeDTO findById(Long id) {
        return employeeRepository.findById(id);
    }

    public void save(EmployeeDTO employeeDTO) {
        employeeRepository.save(employeeDTO);
    }

    public void update(EmployeeDTO employeeDTO) {
        employeeRepository.update(employeeDTO);
    }

    public void delete(Long id) {
        employeeRepository.delete(id);
    }
}

 

EmployeeRepository.java

@Repository
@RequiredArgsConstructor
public class EmployeeRepository {
    private final SqlSessionTemplate sql;

    public List<EmployeeDTO> findAll() {
        return sql.selectList("Employee.findAll");
    }

    public EmployeeDTO findById(Long id) {
        return sql.selectOne("Employee.findById", id);
    }

    public void save(EmployeeDTO employeeDTO) {
        sql.insert("Employee.save", employeeDTO);
    }

    public void update(EmployeeDTO employeeDTO) {
        sql.update("Employee.update", employeeDTO);
    }

    public void delete(Long id) {
        sql.delete("Employee.delete", id);
    }
}