반응형
MyBatis 어노테이션 기반 문법 요약
이 문서는 제공된 BatisMapper.java 예제를 기반으로, 어노테이션을 사용하는 기본 MyBatis 문법을 요약합니다.
1. @Mapper 어노테이션
이 어노테이션은 인터페이스에 선언하여 Spring에게 해당 인터페이스가 MyBatis 매퍼임을 알려주는 역할을 합니다. Spring은 이 인터페이스의 구현체를 자동으로 생성하여 Spring 컨테이너에 등록하며, 다른 컴포넌트에서 의존성 주입(DI)을 통해 사용할 수 있게 해줍니다.
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BatisMapper {
// ... 메소드들
}
2. SQL 조작 어노테이션
MyBatis는 SQL 쿼리를 Java 코드에 직접 작성할 수 있도록 여러 어노테이션을 제공합니다.
@Insert
SQL INSERT 구문을 정의할 때 사용합니다. 메소드의 반환 타입은 보통 int로 하며, 이는 삽입된 레코드(행)의 수를 의미합니다.
- 예시:
@Insert("insert into student (name, kor, math) values (#{name} , #{kor} , #{math}) ") int save( StudentDto studentDto); - 파라미터:
#{...}구문은studentDto객체의 필드 값에 접근하기 위해 사용됩니다. (예:#{name}은studentDto.getName()에 해당합니다.)
@Select
SQL SELECT 구문을 정의할 때 사용합니다. 반환 타입은 쿼리 결과에 맞춰 지정해야 하며, 단일 객체, List, Map 등 다양한 형태가 될 수 있습니다.
- 예시 (전체 조회):이 쿼리는
student테이블의 모든 레코드를 반환하며, MyBatis가 각 레코드를StudentDto객체에 자동으로 매핑해줍니다. @Select("select * from student") List<StudentDto> findAll();- 예시 (개별 조회):
#{sno}는 메소드의 파라미터sno값을WHERE절의 조건으로 사용합니다. 조회 결과는Map형태로 반환되며, 여기서 키는 컬럼명, 값은 해당 컬럼의 데이터가 됩니다. @Select("select * from student where sno = #{sno}") Map<String, Object> find(int sno);
@Delete
SQL DELETE 구문을 정의할 때 사용합니다. 보통 삭제된 레코드의 수를 의미하는 int를 반환합니다.
- 예시:
@Delete("delete from student where sno = #{sno}") int delete(int sno); - 파라미터: 기본 자료형 파라미터
sno는#{sno}형태로 직접 참조됩니다.
@Update
SQL UPDATE 구문을 정의할 때 사용합니다. 이 역시 보통 수정된 레코드의 수를 의미하는 int를 반환합니다.
- 예시:
@Update("update student set name = #{name} , kor = #{kor} , math = #{math} where sno = #{sno}") int update(StudentDto studentDto); - 파라미터:
@Insert예시와 마찬가지로,studentDto객체의 필드 값들이 수정할 데이터로 사용됩니다.
3. #{}를 이용한 파라미터 매핑
#{} 구문은 MyBatis에서 SQL 쿼리로 파라미터를 전달하는 표준 방식입니다. 이 방식은 내부적으로 PreparedStatement를 사용하여 SQL 인젝션 공격을 방지하므로 안전합니다.
- DTO/객체 사용 시:
#{필드명}은 해당 객체의 getter 메소드를 호출하여 값을 가져옵니다. (예:#{name}은studentDto.getName()을 호출) - 기본 자료형(int, String 등) 사용 시:
#{파라미터명}은 메소드의 파라미터를 직접 참조합니다. (예:delete메소드의#{sno})
1) Controller
package example.day06;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping ("/day06/batis")
@RequiredArgsConstructor // final 변수에 대해 자동 생성자 만들어줌
public class BatisController {
// * Mapper 객체 DI
private final BatisMapper batisMapper;
// 1. 학생 등록
// URL : http://localhost:8080/day06/batis
// BODY : { "name" : "유재슥" , "kor" : 97 , "math" : 86 }
// RETURN : 1(성공) 0(실패)
@PostMapping("")
public ResponseEntity<Integer> save(@RequestBody StudentDto studentDto){
Integer result = batisMapper.save(studentDto);
return ResponseEntity.status(200).body(result);
}
// 2. 전체 학생 조회
// URL : http://localhost:8080/day06/batis
@GetMapping("")
public ResponseEntity<List<StudentDto>> findAll(){
// 현재 예제는 서비스를 생략
List<StudentDto> result = batisMapper.findAll();
// ResponseEntity 응답객체
return ResponseEntity.status(200).body(result);
}
// 3. 개별 학생 조회
// URL : http://localhost:8080/day06/batis/find?sno=1
@GetMapping("/find")
public ResponseEntity<Map<String , Object>> find(@RequestParam int sno){
Map<String , Object> result = batisMapper.find(sno);
return ResponseEntity.status(200).body(result);
}
// 4. 개별 학생 삭제
// URL : http://localhost:8080/day06/batis?sno=1
// RETURN : 1(성공) 0(실패)
@DeleteMapping("")
public ResponseEntity<Integer> delete(@RequestParam int sno){
int result = batisMapper.delete(sno);
return ResponseEntity.status(200).body(result);
}
// 5. 개별 학생 수정
// URL : http://localhost:8080/day06/batis
// BODY : { "sno" : 2 , "name" : "유재슥" , "kor" : 97 , "math" : 86 }
// RETURN : 1(성공) 0(실패)
@PutMapping("")
public ResponseEntity<Integer> update(@RequestBody StudentDto studentDto){
Integer result = batisMapper.update(studentDto);
return ResponseEntity.ok(result); // ok는 200번
}
} // class end
2) Mapper
package example.day06;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
@Mapper // 해당 인터페이스를 마이바티스(스프링 컨테이너)에 등록, DAO 역할 대신
public interface BatisMapper {
// 1. 학생 등록 : ? 대신에 #{매개변수} 들어감
@Insert("insert into student (name, kor, math) values (#{name} , #{kor} , #{math}) ")
int save( StudentDto studentDto); // 추상메소드
// int : insert된 레코드 수를 반환 , 1 : 성공 , 0 실패
// 2. 전체 학생 조회
@Select("select * from student")
List< StudentDto > findAll();
// 3. 개별 학생 조회 (Map 테스트)
@Select("select * from student where sno = #{sno}")
Map< String , Object > find(int sno);
// 4. 개별 학생 삭제
@Delete("delete from student where sno = #{sno}")
int delete( int sno ); // 추상메소드
// 5. 개별 학생 수정
@Update("update student set name = #{name} , kor = #{kor} , math = #{math} where sno = #{sno}")
int update( StudentDto studentDto );
} // inter end
3) Dto
package example.day06;
import lombok.*;
@Data @Builder
@NoArgsConstructor @AllArgsConstructor
public class StudentDto {
private int sno;
private String name;
private int kor;
private int math;
}
3) SQL
DROP DATABASE IF EXISTS springweb2;
CREATE DATABASE springweb2;
USE springweb2;
-- --------------------------------------- 실습1 ----------------------------------------
CREATE TABLE products (
product_id INT PRIMARY KEY AUTO_INCREMENT, -- 상품 ID (자동 증가)
product_name VARCHAR(255) NOT NULL, -- 상품명
stock_quantity INT NOT NULL -- 재고 수량
);
INSERT INTO products (product_name, stock_quantity) VALUES
('무선 이어폰', 25),
('스마트워치', 12),
('게이밍 키보드', 30),
('기계식 마우스', 8),
('휴대용 충전기', 15);
-- --------------------------------------- day06 example ----------------------------------------
-- 학생 테이블
CREATE TABLE student (
sno INT AUTO_INCREMENT, -- 학생 번호 (자동 증가)
name VARCHAR(50) NOT NULL, -- 이름
kor INT NOT NULL, -- 국어 점수
math INT NOT NULL, -- 수학 점수
CONSTRAINT PRIMARY KEY (sno) -- 기본키 제약 조건 추가
);
INSERT INTO student (name, kor, math) VALUES ('홍길동', 85, 90);
INSERT INTO student (name, kor, math) VALUES ('김철수', 78, 88);
INSERT INTO student (name, kor, math) VALUES ('이영희', 92, 95);
INSERT INTO student (name, kor, math) VALUES ('박지민', 70, 65);
INSERT INTO student (name, kor, math) VALUES ('최유리', 88, 82);
select * from student;
반응형
'백엔드 > 스프링' 카테고리의 다른 글
| [Spring] 5장: Spring Security를 이용한 인증과 인가 (0) | 2025.09.18 |
|---|---|
| [Spring] 4장: JPA와 Spring Data JPA로의 도약 (0) | 2025.09.18 |
| [Spring] 3장: MyBatis를 이용한 데이터베이스 연동 (0) | 2025.09.18 |
| [Spring] 2장: Spring MVC와 웹 요청 처리 (0) | 2025.09.18 |
| [Spring] 1장: Spring Boot와 제어의 역전(IoC) / 의존성 주입(DI) (0) | 2025.09.18 |
| [Spring] Spring Boot 로드맵: 실무 역량을 갖춘 백엔드 개발자로 거듭나기 (0) | 2025.09.18 |
| [Spring] 자바 스프링 프레임워크 개론 (0) | 2025.09.16 |
| [Spring] WebSocket 요약 정리 (0) | 2025.09.15 |