๐Ÿ’– [JavaScript+mySQL] Ajax์œผ๋กœ ์ข‹์•„์š” ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

์ „์ฃผ์€ยท2022๋…„ 11์›” 24์ผ
1
post-thumbnail

๐Ÿงก ์ข‹์•„์š” ๊ตฌํ˜„ํ•˜๊ธฐ

๐Ÿ™„ ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—...

Ajax์„ ๋ฐฐ์› ๋‹ค๋ฉด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์“ฐ์ด๋Š”์ง€ ์ดํ•ดํ•˜๋Š”์ง€ ๊ถ๊ธˆํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‹น์‹ ์ด ์ธ์Šคํƒ€๊ทธ๋žจ์—์„œ ๋ˆ„๊ตฐ๊ฐ€์˜ ๊ฒŒ์‹œ๊ธ€์— ํ•˜ํŠธ๋ฅผ ๋ˆ„๋ฅธ๋‹ค๋ฉด ๊ทธ ๊ฒŒ์‹œ๊ธ€์—๋Š” ๋‚˜์˜ ์•„์ด๋””๋กœ ์ข‹์•„์š”๊ฐ€ ํ•˜๋‚˜๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ , ๋‹ค์‹œ ํ•˜ํŠธ๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋‚˜์˜ ์•„์ด๋””๊ฐ€ ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅธ ์‚ฌ๋žŒ ๋ชฉ๋ก์—์„œ ์ง€์›Œ์ง€๊ณ  ์ข‹์•„์š” ๊ฐœ์ˆ˜๊ฐ€ ํ•˜๋‚˜ ์ค„์–ด๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅธ๋‹ค๊ณ , ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ๋‹ค์‹œ๋กœ๋“œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€๋งŒ ๋ฐ”๋€Œ๊ฒŒ ๋˜๋Š” Ajax์˜ ์›๋ฆฌ๊ฐ€ ๋ฐ˜์˜๋ฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์ด๋ฒˆ๊ธ€์—์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„๋ฐฉ๋ฒ•๊ณผ ์›๋ฆฌ๋ฅผ ์„ค๋ช…ํ•  ๊ฒƒ์ธ๋ฐ ๋งŒ์•ฝ์— ์ง์ ‘ ํ•ด๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ๋กœ ๋“ค์–ด๊ฐ€์„œ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค!
๊ฒŒ์‹œํŒ ์ „์ฒด์ฝ”๋“œ github

โœ” step1. mySQL DB์— ์ข‹์•„์š” ํ…Œ์ด๋ธ” ์ƒ์„ฑํ•˜๊ธฐ

create table tb_like(
li_idx int auto_increment primary key,
li_userid varchar(20) not null,
li_boardidx int not null,
foreign key (li_boardidx) references tb_board(b_idx) on update cascade
);

3๊ฐ€์ง€ ์ •๋„ ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

1. ์ข‹์•„์š” ํ•˜๋‚˜ํ•˜๋‚˜์— ๋Œ€ํ•œ ๊ธฐ์ค€์ด ๋˜๋Š” li_idx
2. ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅธ ์‚ฌ๋žŒ li_userid
3. ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅธ ๊ฒŒ์‹œ๋ฌผ li_boardidx

foreign key (li_boardidx) references tb_board(b_idx) on update cascade ์ด๋ถ€๋ถ„์€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค
๊ฒŒ์‹œ๊ธ€ํ…Œ์ด๋ธ”(tb_board)์˜ ๊ฒŒ์‹œ๋ฌผ idx(b_idx)๋ฅผ li_boardidx์™€ foreign keykey๋กœ ์„ค์ •ํ•ด์ฃผ๊ณ , ON UPDATE CASCADE๋ฅผ ํ†ตํ•ด ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ๋„ ๊ฐ™์ด UPDATE ํ•˜๊ฒ ๋‹ค๋Š” ์ œ์•ฝ ์กฐ๊ฑด์„ ๊ฑธ์–ด์ค๋‹ˆ๋‹ค.
์ž์‹ ์ด ๊ฐ–๊ณ ์žˆ๋Š” ํ…Œ์ด๋ธ”์— ๋งž๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

โœ” step2. ์ข‹์•„์š” ๋ฒ„ํŠผ ๋ˆŒ๋ €์„๋•Œ Ajax์ฒ˜๋ฆฌํ•˜๋„๋ก javascriptํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

์ข‹์•„์š” ๊ธฐ๋Šฅ์— ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ ๊ณ  ์ƒ๋žตํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ „์ฒด ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด, github๋ฅผ ๋‹ค์šด๋ฐ›์•„ webcontent > board > view.jsp๋ฅผ ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค!

<%
	//... ์ƒ๋žต
	//์ƒ๋‹จ์— ๋ณ€์ˆ˜ 2๊ฐœ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
	//... ์ƒ๋žต
	Boolean isLike=false;		//๐Ÿ’–1.๋ณ€์ˆ˜์ถ”๊ฐ€ ์ข‹์•„์š”ํ•œ ๊ธ€์ธ๊ฐ€?
	int b_like = 0;				//๐Ÿ’–2.boardํ…Œ์ด๋ธ” like๋ณ€์ˆ˜์ถ”๊ฐ€
	
	// mysql board ๋‚ด์šฉ ์ „์ฒด๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ๋ถˆ๋Ÿฌ์˜ฌ๋•Œ ๋‚ด๊ฐ€ ์ข‹์•„ํ•œ ๊ฒŒ์‹œ๋ฌผ์ธ์ง€ ํ™•์ธํ•ด์•ผํ•˜๋‹ˆ๊นŒ์š”!
	try{
		conn = Dbconn.getConnection();
      	// ... ์ƒ๋žต
		if(conn != null){
			sql = "select b_userid,b_name,b_title,b_hit,b_regdate,b_like,b_content from tb_board where b_idx=?;";
			pstmt= conn.prepareStatement(sql);
			pstmt.setString(1,b_idx);
			rs= pstmt.executeQuery();
			//๐Ÿ’–3. ์ „์ฒด ๋‚ด์šฉ์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์ข‹์•„์š”ํ•œ ๊ฒŒ์‹œ๊ธ€์ธ์ง€ ํ™•์ธํ•˜๊ธฐ
			if(rs.next()){
				sql="select li_idx from tb_like where li_boardidx=? and li_userid=?";
				pstmt= conn.prepareStatement(sql);
				pstmt.setString(1,b_idx);//์ด๊ธ€์— ํ˜น์‹œ ์ข‹์•„์š” ํ–ˆ๋‚˜?(get์œผ๋กœ ๋ฐ›์€๊ฐ’)
				pstmt.setString(2,userid);//์ง€๊ธˆ ๋กœ๊ทธ์ธํ•œ์‚ฌ๋žŒ์ด?(์„ธ์…˜๊ฐ’)
				ResultSet rs_like= pstmt.executeQuery();
				if(rs_like.next()){
                  //๐Ÿ’–3. select์˜ ๊ฒฐ๊ณผ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ์ข‹์•„์š”ํ•œ ๊ฒŒ์‹œ๊ธ€์ด๋‹ค. => isLike=true;
					isLike =true;
				}
                //์ข‹์•„์š”๋ž‘ ๊ด€๊ณ„์—†์ด ํ•„์š”ํ•œ ๊ฒŒ์‹œ๊ธ€์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค
				b_title = rs.getString("b_title");
				b_userid = rs.getString("b_userid");
				b_name = rs.getString("b_name");
				b_regdate = rs.getString("b_regdate");
				b_content = rs.getString("b_content");
				b_hit = rs.getInt("b_hit");
				b_like = rs.getInt("b_like");
			}
		}
	}catch(Exception e){
		e.printStackTrace();
	}
	
%>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>๊ธ€๋ณด๊ธฐ</title>
<script>
  
  //๐Ÿ’–4. like() ํ•จ์ˆ˜: ํ•˜ํŠธ ๋ˆ„๋ฅผ๋•Œ title on <-> title off ํ•˜๋ฉด์„œ Ajax์„ ์ด์šฉํ•ด mysql DB์— like+1 or like-1ํ•ด์ค๋‹ˆ๋‹ค.
	function like(){
		const isHeart = document.querySelector("img[title=on]");
		if(isHeart){
			document.getElementById('heart').setAttribute('src','./like_off.png');
			document.getElementById('heart').setAttribute('title','off');
		}else{
			document.getElementById('heart').setAttribute('src','./like_on.png');
			document.getElementById('heart').setAttribute('title','on');
		}
		//์‚ฌ์ง„๊ฒฝ๋กœ๋Š” ๋ณธ์ธ์—๊ฒŒ ๋งž๊ฒŒ ์ˆ˜์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
		const xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function(){
			if(xhr.readyState == XMLHttpRequest.DONE && xhr.status ==200){
				document.getElementById('like').innerHTML = xhr.responseText;
			}	
		}
		xhr.open('get','like_ok.jsp?b_idx=<%=b_idx%>',true);
		xhr.send();
	}
</script>
</head>
<body>
	<h2>๊ธ€๋ณด๊ธฐ</h2>
	<table>
		<tr><th>์ œ๋ชฉ</th><td><%=b_title%></td></tr>
		<tr><th>๋‚ ์งœ</th><td><%=b_regdate%></td></tr>
		<tr><th>์ž‘์„ฑ์ž</th><td><%=b_userid%>(<%=b_name%>)</td></tr>
		<tr><th>์กฐํšŒ์ˆ˜</th><td><span id="hit"><%=b_hit %></span></td></tr>
<!-- ๐Ÿ’–4.์ข‹์•„์š” ํ•˜ํŠธ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ํ•˜๊ณ  onclick๋˜์—ˆ์„ ๋•Œ like() ํ•จ์ˆ˜ ํ˜ธ์ถœ!-->
		<tr>
			<th>์ข‹์•„์š”</th><td> <%if(isLike){%><img id="heart" src="./like_on.png" alt="์ข‹์•„์š”" onclick="like()">
			<%}else{%><img id="heart" src="./like_off.png" alt="์ข‹์•„์š”" onclick="like()"><%}%> <span id="like"><%=b_like %></span></td>
		</tr>
		<tr><th>๋‚ด์šฉ</th><td><%=b_content %></td></tr>
<!-- ๋’ท๋‚ด์šฉ ์ƒ๋žต -->

โœ” step3. Ajax์œผ๋กœ ์ข‹์•„์š” ์ˆ˜ ๋ฐ˜์˜ํ•ด์ฃผ๊ธฐ!

์ด์ œ like_ok.jsp ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  Ajax์„ ์ฒ˜๋ฆฌํ•ด์ค„ ์ฝ”๋“œ๋ฅผ ์งœ๋ณผ๊ฒ๋‹ˆ๋‹ค.
์ฝ”๋“œ๊ฐ€ ๊ธธ์ง€ ์•Š์•„ ๋ชจ๋‘ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค!

  • import๋Š” 2๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.
    1. java.sql.* : mysql๊ณผ ์—ฐ๊ฒฐํ•˜๋„๋ก ๋„์™€์ฃผ๋Š” ์ž๋ฐ”ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
    2. Dbconn : DB์—ฐ๊ฒฐ์„ ๋•๋Š” ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ž…๋‹ˆ๋‹ค.
      ์—ฌ๊ธฐ์„œ ์„ค๋ช…ํ•˜๋ฉด ๋ณต์žกํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด ๋ˆ„๊ตฐ๊ฐ€ ์ž˜ ์„ค๋ช…ํ•ด๋‘” ๊ธ€์„ ์ฐธ๊ณ ํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.
  • ํ•„์š”ํ•œ sql ๊ตฌ๋ฌธ
    select li_idx from tb_like where li_boardidx=? and li_userid=?;
    ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ์ด ์ด๊ธ€์— ์ข‹์•„์š”ํ•œ์ ์žˆ์–ด? ์žˆ์œผ๋ฉด, ์ข‹์•„์š”์ทจ์†Œ(likeํ…Œ์ด๋ธ” ๊ธฐ๋ก ์‚ญ์ œ)ํ•˜๊ณ , ๊ฒŒ์‹œ๊ธ€ ์ข‹์•„์š”์ˆ˜ ํ•˜๋‚˜ ์ค„์ด์ž!
    update tb_board set b_like = b_like-1 where b_idx=?
    delete from tb_like where li_boardidx=? and li_userid =?
    ์—†์œผ๋ฉด, ์ข‹์•„์š”(likeํ…Œ์ด๋ธ”์— ๊ธฐ๋ก ์ถ”๊ฐ€)ํ•˜๊ณ , ๊ฒŒ์‹œ๊ธ€ ์ข‹์•„์š”์ˆ˜ ํ•˜๋‚˜ ๋Š˜๋ฆฌ์ž! ๊ทธ๋ž˜์„œ ์ด ๊ฒŒ์‹œ๋ฌผ ์ด ์ข‹์•„์š” ๊ฐœ์ˆ˜๊ฐ€ ์–ผ๋งˆ๋‚˜๋˜์ง€?
    select b_like from tb_board where b_idx=?
    ๊ทธ๊ฑฐ ๋ฐ˜ํ™˜ํ•ด์ค˜! = out.println(b_like) ์ด๋Ÿฐ ๋Š๋‚Œ์ž…๋‹ˆ๋‹ค.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/sessioncheck.jsp"%>
<%@ page import = "java.sql.*" %>
<%@ page import = "com.koreait.db.Dbconn" %>
<%
	String b_idx= request.getParameter("b_idx");
	String userid = (String)session.getAttribute("userid");
	request.setCharacterEncoding("UTF-8");
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	try{
		conn = Dbconn.getConnection();
		if(conn != null){
			int b_like=0;
			
			String sql = "select li_idx from tb_like where li_boardidx=? and li_userid=? ";
			pstmt= conn.prepareStatement(sql);
			pstmt.setString(1,b_idx);
			pstmt.setString(2,userid);
			rs= pstmt.executeQuery();
			if(rs.next()){
				sql="update tb_board set b_like = b_like-1 where b_idx=?";
				pstmt= conn.prepareStatement(sql);
				pstmt.setString(1,b_idx);
				pstmt.executeUpdate();	
				
				sql="delete from tb_like where li_boardidx=? and li_userid =?;";
				pstmt= conn.prepareStatement(sql);
				pstmt.setString(1,b_idx);
				pstmt.setString(2,userid);
				pstmt.executeUpdate();	
				
				
				
			}else{
				sql="update tb_board set b_like = b_like+1 where b_idx=?";
				pstmt= conn.prepareStatement(sql);
				pstmt.setString(1,b_idx);
				pstmt.executeUpdate();
				sql="insert into tb_like(li_userid, li_boardidx) values (?,?)";
				pstmt= conn.prepareStatement(sql);
				pstmt.setString(1,userid);
				pstmt.setString(2,b_idx);
				pstmt.executeUpdate();
	
			}
			sql="select b_like from tb_board where b_idx=?";
			pstmt= conn.prepareStatement(sql);
			pstmt.setString(1,b_idx);
			rs= pstmt.executeQuery();
			if(rs.next()){
				b_like = rs.getInt("b_like");
				out.println(b_like);
			}
			if(pstmt != null) conn.close();
		}
	}catch(Exception e){
		e.printStackTrace();
	}
%>

โœ” ๊ธ€์„ ๋งˆ์น˜๋ฉฐ๐Ÿ’จ

Ajax์„ ์จ๋ณด๋ฉด, ์ƒˆ๋กœ๊ณ ์นจ์ด ๋˜์ง€์•Š๊ณ  ๋ฐ”๋กœ ๊ทธ ๋ถ€๋ถ„๋งŒ ์ˆ˜์ •์ด ๋˜๊ธฐ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๋กœ ํ•˜์—ฌ๊ธˆ ๋ถˆํŽธํ•œ ๋Š๋‚Œ์„ ๋œ์–ด์ฃผ๊ณ , ์ „์ฒด๋ฅผ ๋กœ๋“œํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋‹ˆ ์„œ๋ฒ„๊ฐ€ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ์–‘์„ ์ค„์—ฌ์ฃผ์ฃ ! ์š”์ฆ˜์€ Ajax๋ณด๋‹ค๋Š” fetch์™€ promise๋ฅผ ๊ฒฐํ•ฉํ•œ ๊ฒƒ์„ ๋” ๋งŽ์ด ์“ด๋‹ค๊ณ  ํ•˜์ง€๋งŒ, ๊ฐ„๋‹จํ•œ ์ž‘์—…์„ ํ• ๋•Œ๋Š” ๋‚˜์˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐํšŒ๊ฐ€ ๋œ๋‹ค๋ฉด fetch์™€ promise๋ฅผ ์ด์šฉํ•ด์„œ ์ผ๋ถ€๋งŒ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€