Spring study -4주차-

ChapJun·2021년 12월 17일
0

✔ Mybatis

Mybatis는 자바 오브젝트와 SQL사이의 자동 매핑 기능을 지원하는 ORM(Object relational Mapping)프레임워크이다.

특징

  1. 쉬운 접근성과 코드의 간결함
    • JDBC의 모든 기능을 Mybatis가 대부분 제공한다.
    • 복잡한 JDBC코드를 걷어내며 깔끔한 소스코드를 유지할 수 있다.
    • 수동적인 파라미터 설정과 쿼리 결과에 대한 맵핑 구문을 제거할 수 있다.
  2. SQL문과 프로그래밍 코드의 분리
    • SQL에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일하지 않아도 된다.

✔ Springboot-MyBatis 설정

# pom.xml

<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>2.1.4</version>
</dependency>
# application.yml

mybatis: 

  # resultType을 쉽게 쓰기 위해서 dto 패키지를 type-aliaes에 설정 
  type-aliases-package: com.example.tacocloud.domain
  
  # mapper의 위치 지정
  mapper-locations: classpath:mapper/**/*.xml
  

Mapper 파일 생성

@Mapper

  • Spring IoC 컨테이너에 서비스 Bean으로 등록
  • 해당 인터페이스에 등록된 SQL Annotation을 토대로 실제 SQL문을 실행시켜 준다.
  • 3이상 버전부터 mapper.xml 대신 interface 클래스의 Annotation을 통해 SQL을 사용할 수 있다.
package com.example.tacocloud.mapper;

import com.example.tacocloud.domain.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserMapper {

//    @Select("select * from user")
    List<User> findAll();

//    @Select("select * from user where username = #{username}")
//    User findByUsername(@Param("username") String username);

    User findByUsername(String username);

    int save(User user);

}

쿼리파일 작성

  • mapper namespace -> mapper 파일 경로와 동일하게 설정
  • select or insert id -> mapper 파일의 메소드명과 동일하게 설정
<?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.tacocloud.mapper.UserMapper">

    <select id="findAll" resultType="User">
        SELECT * FROM user;
    </select>

    <select id="findByUsername" resultType="User">
        select * from user where username = #{username}
    </select>

    <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">

        <selectKey keyProperty="id" resultType="long" order="BEFORE">
            SELECT  NVL(MAX(id), 0) + 1  FROM user
        </selectKey>

        insert into user (id, username, password, full_name, street, city, state, zip, phone_number)
        VALUES (#{id}, #{username}, #{password}, #{fullName}, #{street}, #{city}, #{state}, #{zip}, #{phoneNumber})

<!--        <selectKey keyProperty="id" resultType="long" order="AFTER">-->
<!--            SELECT SCOPE_IDENTITY()-->
<!--        </selectKey>-->

    </insert>

</mapper>

※ selectKey before 없을 시 id 자동생성이 안됨. (H2의 특성인지? - auto increment X)
※ Insert 시 리턴 값을 등록한 ID로 받고싶은데, after 설정 시 오류 (before, after 동시사용 불가능)


서비스단에서의 사용

package com.example.tacocloud.controller;

import com.example.tacocloud.domain.User;
import com.example.tacocloud.dto.RegistrationForm;
import com.example.tacocloud.mapper.UserMapper;
import com.example.tacocloud.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Slf4j
@Controller
@RequestMapping("/users")
public class UserController {

    private final UserRepository userRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private UserMapper userMapper;

    public UserController(UserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userRepository = userRepository;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @GetMapping
    public String registerForm() {
        return "registration";
    }

    @PostMapping
    public String processRegistration(RegistrationForm form) {

        User user = form.toUser(bCryptPasswordEncoder);
        log.info(user.toString());
        log.info("ID : " + userMapper.save(form.toUser(bCryptPasswordEncoder)));
//        userRepository.save(form.toUser(bCryptPasswordEncoder));
        return "redirect:/login";
    }
}
profile
Chap Chap

0개의 댓글