https://github.com/codingspecialist/Springboot-MyBatis-Setting
에서 프로젝트를 다운받아 MyBatis가 세팅된 상태로 시작하자.
[설정방법]
MyBatisConfig 파일 필요
resources/mapper/*.xml 파일 필요
Users 엔티티 필요
UsersDao 인터페이스 생성 필요
꼭 users파일을 읽어서 데이터 추가가 잘 되었는지 확인하자. (일일히 insert를 해준 뒤 마지막으로 commit을 해야 한다.)
[Controller 세팅 코드]
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
import site.metacoding.red.domain.users.Users;
import site.metacoding.red.domain.users.UsersDao;
@RequiredArgsConstructor
@RestController
public class UsersController {
private final UsersDao usersDao;
@GetMapping("/users/{id}")
public Users getUsers(@PathVariable Integer id) {
return usersDao.findById(id);
}
}
IOC에 등록된 모든 객체는 생성자 주입을 통해 받을 수 있다.
파이널로 정의한 필드는 class가 new될 때 무조건 들어와야 한다.
해당 객체가 new될 때 반드시 값이 있어야 한다.
new될 때 값이 있으려면 생성자를 만들어주면 값이 들어온단 말야.
private final UsersDao usersDao;
UsersController는 UsersDao에 의존하므로 DI를 해주어야 한다.
@RequiredArgsConstructor (lombok기능)
final이 붙어있는 애들로만 생성자를 만들어라
public UsersController(UsersDao usersDao){
this.usersDao=usersDao;
}
역할을 해주는 것
@AllArgsConstructor를 사용하면 생성자를 주입받지 않아도 되는 필드값이 있는데 그것을 구분해주지 못하기 때문에 final 문법을 사용하는게 좋음
DI할 수 있는 조건 : UsersDao가 IOC 컨테이너에 떠 있어야 함 <- UsersDao가 MapperScan을 통해 떠 있음 (domain에 있는 모든 DAO를 띄워놓음)
domain에 Users를 안 띄우고 UsersDao를 띄우는 이유 : mapper에 namespace=UsersDao를 걸어놨기 때문
null (MyBatis가 MapperScan으로 읽어서 BoardsDao를 IOC에 띄웠기 때문에 @RestController만 있어도 BoardsDao 생성자 주입이 된 것)
디폴트와 초기화 중 사용하면 디폴트가 실행됨. BoradsDao
그럼나중에 BoradsDao가 null이라 BoradsDao.메서드 실행이 안 됨
@Autowired
IOC컨테이너에 있는걸 다이렉트로 받음 생성자 안 만들어도
@GetMapping("/users/{id}")
public Users getUsers(@PathVariable Integer id) {
return usersDao.findById(id);
}
Object 타입으로 return 되므로 MessageConverter가 json형식으로 convert 해준다.
insert할거면 insert를 사용
update할거면 update를 사용하는 등 문법이 있음
package site.metacoding.red.domain.users;
import java.util.List;
public interface UsersDao {
public void insert(Users users);
public Users findById(Integer id);
public List<Users> findAll();
}
신경쓸거
(List<Users>)
이거보고 MyBatis에 쿼리 만들어~
Mapper 코드
<select id="findAll" resultType="site.metacoding.red.domain.users.Users">
SELECT * FROM users ORDER BY id DESC
</select>
resultType이 List인데 Users로 정해뒀는데요?
안에 잇는 return될 값만 적어주면 돼 알아서 List로 나옵니다 ^^ (컬렉션은 안 적어도 됨)
왜요? 몰라나도 해주니까 해주더라고
Controller 코드
@GetMapping("/users")
public List<Users> getUserList(){
return usersDao.findAll();
}
public interface UsersDao {
public void insert(Users users);
public Users findById(Integer id);
public List<Users> findAll();
}
Mapper 코드
<insert id="insert">
INSERT INTO users(id, username, password, email, createdAt)
VALUES(users_seq.nextval, #{username}, #{password}, #{email}, sysdate)
</insert>
Controller코드
@PostMapping("/users")
public Integer insert(Users users) {
usersDao.insert(users);
return 1;
}
Post를 Form(www타입)으로 받을거니까 Users users로 받음. (json으로 받는다면 앞에 @ResquestBody를 붙여야 함)
이 상태로 실행을 하면 오브젝트가 받는 것인데 MyBatis(Mapper)가 오브젝트안의 키값에 자동으로 바인딩 해줌
UsersDao
public interface UsersDao {
public Integer insert(Users users);
public Users findById(Integer id);
public List<Users> findAll();
}
Controller
@PostMapping("/users")
public Integer insert(Users users) {
Integer result = usersDao.insert(users);
return result;
}
Insert Update 쿼리는 변경된 행을 return함 (1, 0 ,-1)
@PostMapping("/users")
public ResponseEntity<?> insert(Users users) {
Integer result = usersDao.insert(users);
return new ResponseEntity<>(HttpStatus.CREATED); // 201번
}
지금 바디가 없으므로 상태코드만 적어주기