17주차 - Spring(18) ajax를 데이터베이스와 연동해보자 - 2

2022. 10. 24. 16:49Spring framwork

이번의 목표

01. 두개의 데이터를 전달하고 값을 받아오자.


지난 시간에는 데이터베이스와 연동하여 키워드에 따른 값을 출력하는 코드를 작성했습니다.

이번에는 페이지에서 두개의 데이터를 보내고 검증하여, 해당하는 데이터를 출력하는 코드를 작성해보겠습니다.

지난 번과 다른 점이라면 데이터를 보낼때, hashmap의 형식으로 두개의 키:값을 보내고 이를 검증한다는 것입니다.

 여기서 제가 선택하고자 했던 방법은 두가지였습니다.

첫째. Service에서 데이터를 전부 검증하고 데이터베이스와 연결하는 방법

둘째. Mapper에서 동적SQL을 사용하여 데이터베이스와 연결하는 방법

 

컨트롤러까지의 코드는 동일하기 때문에 서비스, Mapper의 코드를 비교하여 보겠습니다.

 

첫번째 해결 방법.

01. 페이지 코드
02. 컨트롤러 코드
03. 서비스 코드
04. Mapper 코드

01. 페이지 코드

<head>
<meta charset="UTF-8">
<title>ex06</title>
<script type="text/javascript">
var req;
function send() {
		var title = document.getElementById('title').value
		console.log("title : "+title)
		req = new XMLHttpRequest();
		req.onreadystatechange = changeText
		req.open('post','ex06')
		req.setRequestHeader('Content-Type',"application/json; charset=UTF-8")
		req.send(title)
	}

	function changeText() {
		if(req.readyState==4 && req.status==200){
			var tbody = document.getElementById('tbody')
			tbody.innerHTML = "아직은 데이터가 없음"
			var resData = JSON.parse(req.responseText)
			var printData =''
			for(i = 0; i < resData.list.length; i++){
				printData += "<tr><td>"+resData.list[i].title+"</td>"
				printData += "<td>"+resData.list[i].artist+"</td>"
				printData += "<td>"+resData.list[i].price+"</td></tr>"
			}
			tbody.innerHTML = printData
		}
	}
</script>
</head>
<body onload="send()">
<input type="text" id="title" onkeyup="send()"> 
<table border="1">
	<thead>
		<tr>
			<th>title</th>
			<th>artist</th>
			<th>price</th>
		</tr>
	</thead>
	<tbody id="tbody"></tbody>
</table>
</body>

02. 컨트롤러 코드

	@GetMapping("ex06")
	public String ex06Get() {
		return "ajax/ex06";
	}
	
	@ResponseBody
	@PostMapping(value="ex06", produces = "application/json; charset=UTF-8")
	public String ex06Post(@RequestBody(required = false) String title){
		ArrayList<AjaxDTO> lists = service.find(title);
		String data = "{\"list\":[";
		for(int i =0;i<lists.size();i++) {
		AjaxDTO list = lists.get(i);
		if(data.contains(list.getTitle())) {
			continue;
		}
		
		data += "{\"title\":\"" + list.getTitle()+"\"";
		data += ", \"artist\":\""+list.getArtist()+"\"";
		data += ", \"price\":\""+list.getPrice()+"\"},";
		}
		data = data.substring(0,data.length()-1);
		data += "]}";
		return data;
	}

03. 서비스 코드

	public ArrayList<AjaxDTO> findOp(@RequestBody(required = false)HashMap<String, String> map){
		ArrayList<AjaxDTO> lists = new ArrayList<AjaxDTO>();
		
		String option = map.get("option");
		String keyword = map.get("keyword");
		
		// 키워드 없으면 모든 리스트
		if(map.get("keyword").isEmpty()) {
			lists = repo.viewAll();
			return lists;
		}
		
		// 옵션이 "제목" 일때
		if(option.equals("제목")) {
			lists = repo.findWithTitle(keyword);
		}
		
		// 옵션이 "아티스트" 일때
		if(option.equals("아티스트")) {
			lists = repo.findWithArtist(keyword);
		}
		
		// 옵션이 "가격" 일때
		if(option.equals("가격")){
			lists = repo.findWithPrice(keyword);
		}
		
		// 검색 결과가 없을때
		if(lists.size()==0) {
			lists = repo.viewAll();
		}
		return lists;
	}

04. Mapper 코드

<mapper namespace="com.care.ajax.AjaxRepository">
<select id="findWithTitle" 
parameterType="String"
resultType="com.care.ajax.AjaxDTO">
	SELECT * FROM ajax WHERE lower(title) LIKE lower('%'||#{keyword}||'%')
</select>

<select id="findWithArtist" 
parameterType="String"
resultType="com.care.ajax.AjaxDTO">
	SELECT * FROM ajax WHERE lower(artist) LIKE lower('%'||#{keyword}||'%')
</select>

<select id="findWithPrice" 
parameterType="String"
resultType="com.care.ajax.AjaxDTO">
	SELECT * FROM ajax WHERE lower(price) LIKE lower('%'||#{keyword}||'%')
</select>
</mapper>

두번째 해결 방법.

01. Service 코드
02. Mapper 코드

01. Service 코드

	public String fromJson(ArrayList<AjaxDTO> list) {
		String data = "{\"cd\" : [";
		for(AjaxDTO tmp : list) {
			data += "{ \"title\" : \"" + tmp.getTitle() + "\",";
			data +=	 " \"artist\" : \"" + tmp.getArtist() + "\",";
			data += " \"price\" : \"" + tmp.getPrice() +"\" },";
		}
		data = data.substring(0, data.length()-1);
		data += "]}";
		return data;
	}
    
    	public String choose(HashMap<String, String> map) {
		ArrayList<AjaxDTO> list = repo.choose(map);
		if(list.isEmpty() == true)
			return "";
		return fromJson(list);
	}

02. Mapper 코드

<mapper namespace="com.care.ajax.AjaxRepository">
<select id="choose" resultType="com.care.ajax.AjaxDTO">
		SELECT * FROM ajax
		<where>
			<if test="sel.equals('title')">
				title like '%'||#{inputData}||'%'
			</if>
			<if test="sel.equals('artist')">
				artist like '%'||#{inputData}||'%'
			</if>
			<if test="sel.equals('price')">
				price like '%'||#{inputData}||'%'
			</if>
		</where>
	</select>
    </mapper>

 

실행 화면

각각의 옵션과 입력값에 따른 결과 화면

검증 단계는 Service에서 모두 끝마쳐야한다고 생각한다면 Service에서 모두 검증을 하고 데이터베이스와 연결되면 될것입니다. 다만 이 경우에는 그만큼 경우의 수만큼 메서드가 많아질 것이라는 단점이 있습니다.

반대로 Mapper에서 동적 SQL쿼리문을 사용하면 메서드가 보다 깔끔해진다는 장점이 있습니다. 습관처럼 Service에서 검증을 하려고하지만 말고 이런 경우에는 동적 SQL문을 사용하는 것을 고려해보는 편이 더 좋았을 것 같습니다.