Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

dearbeany

[SpringBoot] KeyProperty과 useGeneratedKeys | resultType과 resultMap (Product 실습 에러 해결) 본문

Spring

[SpringBoot] KeyProperty과 useGeneratedKeys | resultType과 resultMap (Product 실습 에러 해결)

dearbeany 2022. 10. 28. 11:04

ProductRestController 작성

- 테스트는 Talend에서 한다.

@RestController
@RequestMapping("/api")
public class ProductRestController {
	@Autowired
	private ProductService pService;

	@GetMapping("/product")
	public ResponseEntity<List<Product>> selectAll() {
		return new ResponseEntity<>(pService.selectAll(), HttpStatus.OK);
	}

	@GetMapping("/product/{id}")
	public ResponseEntity<Product> selectOne(@PathVariable() int id) {
		return new ResponseEntity<>(pService.selectOne(id), HttpStatus.OK);
	}

	@PostMapping("/product")
	public ResponseEntity<String> insert(Product product) {
		pService.insert(product);
		return new ResponseEntity<>("등록완료", HttpStatus.OK);
	}

	@PostMapping("/product/{id}")
	public ResponseEntity<String> delete(@PathVariable() int id) {
		pService.delete(id);
		return new ResponseEntity<>("삭제완료", HttpStatus.OK);
	}

 

- form 태그의 name속성의 값에 값을 적어준다

 

 

 

 

KeyProperty / useGeneratedKeys

 

Product를 insert할 때, jsp의 <form>으로부터 상품명(name), 상품가격(price), 상품설명(desc)을 입력받는다. id는 입력받지 않는데, 이는 자동 증가되는 serial 이기 때문이다. 상품등록하면, 자동 증가되는 값이다.

CREATE TABLE product(
    p_id INT auto_increment primary key,
    p_name VARCHAR(20),
    p_price INT,
    p_description VARCHAR(50)
);

 

<에러상황>

1. id는 int값인데 속성을 지정하지 않으니, null 값이 들어가면서 에러가 발생했었다.

2. id가 0번으로 들어가면 각 상품 상세보기(detail)를 할 때 id값으로 접근할 수 없었다.

	<insert id="insert" parameterType="Product" keyProperty="id" useGeneratedKeys="true">
		INSERT INTO product (p_name, p_price, p_description)
		VALUES (#{name}, #{price}, #{desc})
	</insert>

사용하는 DB가 Mysql과 같이 auto_increment키를 지원한다면, 위 옵션들을 통해 insert된 데이터의 key값을 리턴 받을 수 있다.

KeyProperty : 리턴될 키값들을 어느 필드에 세팅할 건 지를 설정. 여러 개 사용할 경우 ,(콤마)를 구분자로 나열
useGeneratedKeys : (insert, update에만 적용) 자동생성된 키값들을 가져올 거라고 명시. true로 설정한다. (default는 false)

 

 

 

 

 

 

resultType / resultMap

resultType : 반환타입으로 클래스 자체를 가져와 참조
resultMap : 반환타입으로 개발자가 xml 내에서 임의로 정의한 형식으로 참조(DB컬럼명을 선언 후 자바에서 원하는 이름으로 뽑아내고 싶다)

 

<에러 상황>

1. 다른 사람들은 resultType="Product" 가 정상동작했으나, 나는 resultMap="ProductMap"만 동작됐었다. (DB가 아예 불러와지지 않음)

2. 다른 사람들은 DB의 경우 테이블의 컬럼명(description)과 Product의 필드명(description)이 일치했지만, 나의 경우 DB의 컬럼명(p_description)과 Product의 필드명(description)이 달랐었다.

3. 이런 경우엔 resultMap으로 다른 필드명에 대해 매핑시켜서 받아와야 한다

<mapper namespace="com.ssafy.product.model.dao.ProductDao">
	<resultMap type="Product" id="ProductMap">
		<result column="p_id" property="id"/>
		<result column="p_name" property="name"/>
		<result column="p_price" property="price"/>
		<result column="p_description" property="desc"/>
	</resultMap>
    
	<select id="selectAll" resultMap="ProductMap">
		SELECT * 
		FROM product
	</select>
    
	<update id="update" parameterType="Product">
		UPDATE product
		SET p_name = #{name}, p_price = #{price}, p_description = #{desc}
		WHERE p_id = #{id} 
	</update>	
..

- resultMap을 이용해 상이한 DB컬럼명에 대해 매핑해주자.

- resultMap: type은 typeAlias로 지정한 클래스명(Product)으로 적고, id는 내가 지칭할 이름으로 지정하자.

public class Product {
	private int id;
	private String name;
	private int price;
	private String desc;
 ..

- 쿼리문은 DB의 컬럼명, #{ } 안에 값은 Product 클래스의 필드명과 일치시키도록 하자.