중복 확인하기(ajax)

2024. 7. 9. 17:25JSP+Spring Boot

 

Controller

package com.kh.test.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.kh.test.service.GoodsItemService;

@RestController
public class GoodsItemController {
	
	@Autowired
	private GoodsItemService goodsItemService;
	
	//에러로 template [check]가 있다면 @Controller -> @RestController
	
	@GetMapping("/check")//ajax에서 url에 작성한 url값
	public Map<String, Boolean> existsByName(@RequestParam String itemName) {
		
		//만약에 상품명이 조회가 된다면 이미 존재하는 상품명입니다. 만들기	
		boolean isCheck = goodsItemService.existsByName(itemName);
		System.out.println(isCheck);
		Map<String, Boolean> res = new HashMap<>();
		
		//ajax는 html을 return 작성하지 않음
		// 왜냐하면 html 파일을 불러오는 것이 아니라 html 파일의 일부분만 설정하는 것이기 때문
		res.put("isCheck", isCheck);
		
		return res; //Map으로 전달된 key와 value를 다시 html 파일의 중복체크에 전달
	}

}

 

 

Mapper

package com.kh.test.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import com.kh.test.dto.GoodsItem;

@Mapper 
public interface GoodsItemMapper { 
	//Integer existsByName(String itemName); -> resultMap을 사용하지 않을 때 사용
	GoodsItem existsByName(@Param("itemName")String itemName); //-> resultMap을 사용해서 count(*)값을 넘길 떄 사용

}

 

Service

package com.kh.test.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kh.test.dto.GoodsItem;
import com.kh.test.mapper.GoodsItemMapper;

@Service
public class GoodsItemService {
	
	@Autowired
	private GoodsItemMapper goodsItemMapper;
	
	public boolean existsByName(String itemName) {
		// Integer로 맞춘 후 Integer을 boolean으로 변경해서 전달할 예정
		//Integer count = goodsItemMapper.existsByName(itemName); -> resultMap 사용하지 않는 방식
		GoodsItem count = goodsItemMapper.existsByName(itemName); //-> resultMap 사용 방식
		
		Integer totalCount = count != null ? count.getItemCount() : 0;
		//int totalCount = count != null ? count.getItemCount() : 0;
		// -> null이 아닐 때 false, null = 0
		
		return totalCount != null && totalCount > 0; //비교 연산자 결과 전달. return이 boolean의 역할을 하게 됨
	}
}

 

Mapper에서는 Integer을 작성하고, service에서 반납할 때는 boolean을 사용하기 때문에 타입이 불일치 할 수 있음
Mapper랑 Service 모두 Integer(int)로 작성하거나
Mapper랑 Service 모두 boolean으로 작성하기

 

 

DTO

package com.kh.test.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class GoodsItem {
	
	private int itemId;
	private String itemName;
	private String itemDes;
	//Count 결과를 받아서 저장할 변수명 추가
	private int itemCount;
}

 

 

XML

<?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.kh.test.mapper.GoodsItemMapper">

	<resultMap type="com.kh.test.dto.GoodsItem" id="goodsMap">
		<id column="item_id" property="itemId"></id>
		<result column="item_name" property="itemName"/>
		<result column="item_description" property="itemDes"/>
		<result column="COUNT(*)" property="itemCount"/>
	</resultMap>

	<select id="existsByName" resultType="java.lang.Integer" resultMap="goodsMap" parameterType="com.kh.test.dto.GoodsItem">

	SELECT COUNT(*) FROM goods_item WHERE item_name = #{itemName}	
	</select>
</mapper>

 

만약에 sql에 작성된 컬럼명과 DTO에 작성된 변수명이 일치하지 않을 때 작성하는 코드 => resultMap

resultMap = SQL 컬럼명과 DTO 모델의 변수명을 연결시켜줌
column = sql에 작성한 컬럼명
property = DTO에 작성한 변수명

Map이 시작하고 primary key는 id에 필수로 작성, 나머지는 result 에 작성

 

** <select id="existsByName" resultType="java.lang.Integer" resultMap="goodsMap" parameterType="com.kh.test.dto.GoodsItem">

상품명이 존재하는지 확인하는 select 쿼리   
   java.util.Map -> COUNT(*) 숫자이기 때문에 Integer 숫자 객체로 변경할 수 있음 
   resultType    = com.kh.test.dto.GoodsItem 넣어도되고, Map이나 Integer, String을 넣어도 됨
   parameterType = com.kh.test.dto.GoodsItem 설정해서 일일이 맞춰줌
   resultMap     = 위에서 작성한 resultMap의 id값을 넣어줌 goodsMap

   <select id="existByName" resultType="java.lang.Integer" parameterType="com.kh.test.dto.GoodsItem">
   로 작성해서 숫자값만 넘겨줄 수 있음

 

 

HTML

<!DOCTYPE html>
<html xmlns:th="www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>Ajax로 중복 확인하기</title>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
	$(document).ready(function() {	
		$('#checkDup').click(function(){
			var itemName =$('#itemName').val(); 
			//값 가져오기가 완료 되었으면 ajax를 통해 controller와 연결, db에 일치하는 값이 있는지 확인
			console.log("itemName 값 : " + itemName);
			$.ajax({
				
				url:"/check", //cotroller와 연결할 url 설정
				type:"get", //@GetMapping에 작성된 주소를 연결
				data:{itemName : itemName},
				/*
				itemName 대신 $('#itemName').val() 사용 가능
				 -> data:{name : $('#itemName').val()}
				
				name 이라는 이름으로 controller에 itemName에 담긴 값을 전달
				key : name , value : itemName
				
				key와 value를 모두 itemName으로 통일하려면
				data:{itemName : itemName}
				*/
				
				//중복확인을 db와 비교하고 성공했을 경우
				success: function(data){
					if(data.isCheck){ //controller에서 put으로 가져온 isCheck를 사용해 true / false 확인
						//alert("사용할 수 있는 상품명");
						$('#dupMsg').text('이미 존재하는 상품명 입니다.');
					}
					else{
						//alert("이미 사용중인 상품명");
						$('#dupMsg').text('사용가능한 상품명 입니다.');
					}
				},
				error: function(){
					alert("알 수 없는 오류 발생");
				}
				
			})
		})
	})
</script>
</head>
<body>
	<h1>Ajax를 활용한 상품 중복 확인</h1>
	<label for="itemName">상품명</label>
	<input type="text" id="itemName" name="itemName">
	<button id="checkDup" type="button">중복확인</button>
	<p id="dupMsg"></p>
	<pre>
		Ajax를 활용해 Controller에 상품명이 이미 DB에 존재하는 지 중복확인을 실시간으로 진행할 수 있음
		jQuery를 사용하는 것이 효율적. -> 단순화 처리해주기 때문
	</pre>
	<code>
		-- goods_item Table
		CREATE TABLE goods_item (
		    item_id NUMBER PRIMARY KEY,
		    item_name VARCHAR2(100) NOT NULL,
		    item_description VARCHAR2(500)
		);
		
		-- goods_item Sequence
		CREATE SEQUENCE goods_item_seq
	</code>
</body>
</html>

 

data:{itemName : itemName},

itemName 대신 $('#itemName').val() 사용 가능
 -> data:{name : $('#itemName').val()}

name 이라는 이름으로 controller에 itemName에 담긴 값을 전달
key : name , value : itemName

key와 value를 모두 itemName으로 통일하려면
data:{itemName : itemName}

 

실행 결과

DB에 있는 이름 입력 시
DB에 없는 이름 입력 시

 

'JSP+Spring Boot' 카테고리의 다른 글

JPA + Modal 맛보기  (0) 2024.08.20
공공 데이터 가져오기  (0) 2024.08.19
이메일 인증  (0) 2024.06.26
마이페이지 조회,수정, 삭제, 검색  (0) 2024.06.25
로그인  (0) 2024.06.25