본문 바로가기
CLASS/SPRING,JSTL

#9-2 / notice list + category 검색기능( 동적 query문 ), delete

by hingu 2024. 7. 24.

👀 start 시 파일 생성 👀 

 

- notice table

 

- dao

package api;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class notice_dao {
	int nidx;
	String n_title,n_pass,n_subject,n_text,n_date;
}


=> 

// config.xml 에 해당 dao 연결 추가
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration 
PUBLIC "-//mybatis.org//DTD configuration 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
	<typeAlias  alias="noticeDAO" type="api.notice_dao"/>
</typeAliases>
</configuration>

 

 

- controller

@Controller
public class notice_controller {
	@Resource(name="notice")
	private notice_module nm;
}

 

- module

package api;

import javax.annotation.Resource;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

@Repository("notice")
public class notice_module {
	@Resource(name="template2")
	private SqlSessionTemplate tm;
}




/* template2 는 config.xml에서 세팅한 bean id값 => databae 연결 */
<bean id="template2" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="close">
    <constructor-arg name="sqlSessionFactory" ref="sqlfact2"></constructor-arg>
</bean>

=> config.xml에서 https://dev-eunse.tistory.com/240 요렇게 db 연결함

 


 

/*--------------------- list 출력 (+ 검색 select ) ----------------------*/

 

1. notice_list.jsp

<body>
	<table border="1">
		<thead>
			<tr height="30">
				<th width="500">제목</th>
				<th width="100">글쓴이</th>
				<th width="100">등록일자</th>
			</tr>
		</thead>
		<tbody>
			<cr:forEach var="data" items="${result}">
				<tr height="30">
					<td align="left">${data.n_subject}</td>
					<td>${data.n_title}</td>
					<td>${data.n_date}</td>
				</tr>
			</cr:forEach>
		</tbody>
	</table>
	<br><br>
	<form id="frm" onsubmit="search_gopage()">
		<select name="search_part" select_data="${search_part}" id="search_part">
			<option value="0" class="option">제목 + 내용</option>
			<option value="1" class="option">제목</option>
			<option value="2" class="option">글쓴이</option>
		</select>
		<input type="text" name="search_word" value="${search_word}">
		<input type="submit" value="검색">
	</form>
</body>

<script type="text/javascript">
	//현재 select한 category selected 처리
	var ea = document.getElementById("search_part").children.length;
	var tg = document.querySelectorAll("option")
	var w=0;
	while(w<ea){
		if(tg[w].value == document.getElementById("search_part").getAttribute("select_data")){
			tg[w].setAttribute("selected","selected");
		}
		w++;
	}

	function search_gopage(){
		if(frm.search_word.value == ""){
			alert("검색할 단어를 입력하세요")
			frm.search_word.focus();
			return false;
		}else{
			frm.method="get";
			frm.action="./notice_list.do";
			frm.submit();
		}
	}
</script>

 

2. mapper.xml  - list 출력시 만들어 놓은 일일데이터만 출력하는 mapper 재사용!

<!-- 동적쿼리문 -->
<mapper namespace="noticeDB">
	<select id="notice_all" resultType="noticeDAO">
		select * from notice order by nidx desc;
	</select>

	<select id="notice_search" resultType="noticeDAO" parameterType="Map">
		select * from notice 
		<where>
			<if test="search_part==0"> <!-- 제목+내용으로 검색할 경우  -->
				n_subject like concat('%',#{search_word},'%') or
				n_text like concat('%',#{search_word},'%')
			</if>
			<if test="search_part==1"> <!-- 제목으로 검색할 경우  -->
				n_subject like concat('%',#{search_word},'%')
			</if>
			<if test="search_part==2"> <!-- 글쓴이로 검색할 경우  -->
				n_title = #{search_word}
			</if>
		</where>
		 order by nidx desc;
	</select>
</mapper>

 

❗ 동적 쿼리문

<select></select>안에 where if 문 사용 가능! 

where 태그는 sql에 where문과 동일한 방법으로 사용

조건문 사용시 주의사항 : 

숫자는 ' ' 있이 , 문자는 ' ' 없이 핸들링 (!! 우리가 알고있는거랑 반대 !!)

 

and , or을 이용하여 추가 조건을 핸들링 할 수 있음

choose -> when -> where 쓰는 경우도 있음 

 

❗ map으로 담아서 던지는 경우 parameterType="map" 으로 받아야함!

 

concat 

mybatis에서 사용하는 검색 class (cmd에서는 사용 x) - like 검색시 사용  

mysql , mariadb => like concat('%',변수값)  / like concat('%',변수값,'%') 

oracle =>  like concat('%'||변수) / like concat('%'||변수||'%')

mssql => like '%'+변수 / like '%'+변수+'%' 

 

 

 

3. @Controller

@GetMapping("/notice/notice_list.do")
public String notice_list(Model m,
        @RequestParam(defaultValue = "", required = false) String search_part,
        @RequestParam(defaultValue = "", required = false) String search_word,
        HttpServletResponse res) {
    //@RequestParam : 값 필수 여부 지정

    //검색값에 따라 조건문으로 result값이 나뉘어야해서 전역변수로 올림
    List<notice_dao> result = null;
    try {
        if(search_part.equals("") && search_word.equals("")) {
            result = nm.alldata();
        }else {
            result = nm.alldata(search_part,search_word);
            m.addAttribute("search_part",search_part);
            m.addAttribute("search_word",search_word);
        }
        //=> 다른 모듈임! 

        m.addAttribute("result",result);

    }catch(Exception e) {
        System.out.println(e);
        System.out.println("query error");
    }

    return "/notice/notice_list";
}

 

4. Module

//게시판 게시물 전체 출력 메소드
public List<notice_dao> alldata() {
    List<notice_dao> rs = new ArrayList<notice_dao>();
    rs = tm.selectList("noticeDB.notice_all"); 

    return rs;
}

//게시판 게시물 검색 메소드
public List<notice_dao> alldata(String search_part, String search_word) {
    List<notice_dao> rs = new ArrayList<notice_dao>();

    //mapper에 인자값은 단 한개의 값만 적용할 수 있음 
    Map<String, String> m = new HashMap<String, String>();
    m.put("search_part", search_part);
    m.put("search_word", search_word);

    //무조건 값은 하나만 던질 수 있음 => 키배열로 던짐
    rs = tm.selectList("noticeDB.notice_search",m); 

    return rs;
}

 

❗ mapper에 인자값은 단 한개의 값만 적용할 수 있음 (seletOne,selectList,insert 등 모든 클래스) 

   => 값이 여러개여서 map 으로 배열화시킨 후 던짐!

 

 

검색잘됨ㅎ

 

 

/*------------------------ 삭제 --------------------------*/

 

<table border="1">
    <thead>
        <tr height="30">
            <th><input type="checkbox" id="all"></th>
            <th width="500">제목</th>
            <th width="100">글쓴이</th>
            <th width="100">등록일자</th>
        </tr>
    </thead>
    <tbody>
        <cr:forEach var="data" items="${result}">
            <tr height="30">
                <td><input type="checkbox" name="ck" value="${data.nidx}"></td>
                <td align="left" title="${data.n_text}">${data.n_subject}</td>
                <td>${data.n_title}</td>
                <td>${data.n_date}</td>
            </tr>
        </cr:forEach>
    </tbody>
</table>



<!---- script ---->
<script>
	var allck = document.getElementById("all");
	var ck = document.getElementsByName("ck");

	allck.addEventListener("click",function(){
		var cked = this.checked
		var w=0;
		while(w<ck.length){
			ck[w].checked = cked;
			w++;
		}
	})
	
	var sum=0;
	var ww=0;
	while(ww<ck.length){
		ck[ww].addEventListener("click",function(){
			if(this.checked == true){
				sum++;
			}else{
				sum--;
			}
			
			if(sum == ck.length){
				allck.checked=true;
			}else{
				allck.checked=false;
			}
		})
		ww++;
	}


	function select_del(){
		if(sum == 0){
			alert('아무것도 선택 안하셨습니다');
		}else{
			if(confirm("정말 삭제하시겠습니까?")){
				frm2.method = 'POST';
				frm2.action = './notice_deleteok.do';
				frm2.submit();			
			}
		}
	}
</script>

 

- mappaer

<delete id="notice_del">
    delete from notice where nidx=#{del} order by nidx desc;
</delete>



<!-- 
5,6 이런식으로 get으로 받을경우 이렇게 처리해도 됨
단, module에서 map 배열로 변환 후 전달해야함!
-->

<!-- mapper - 배열을 ,기준으로 foreach를 이요하여 순서대로 삭제(다중처리) -->
<delete id="notice_del3">
    delete from notice where nidx in(
    <foreach collection="array" item="list" separator=",">
        #{list}
    </foreach>
    ) 
</delete>

<!-- module - 이렇게 -->
public int notice_del(String nidx) {
    String list[] = nidx.split(",");
    int callback = tm.delete("noticeDB.notice_del",list);

    return callback;
}

 

- controller

@PostMapping("/notice/notice_deleteok.do")
public void notice_delteok(String[] ck,HttpServletResponse res) throws Exception{
    res.setContentType("text/html;charset=utf-8");
    this.pw = res.getWriter();
    try {
        int callback = nm.notice_del(ck);
        System.out.println(callback); //삭제한 체크박스수만큼 출력됨
        if(callback > 0) {
            this.pw.write("<script>"
            + "alert('모두 삭제 완료했습니다');"
            + "location.href = './notice_list.do';"
            + "</script>");
        }else {
            this.pw.write("<script>"
            + "alert('데이터 오류로 인해 삭제 실패');"
            + "location.href = './notice_list.do';"
            + "</script>");
        }
    }catch(Exception e) {
        System.out.println(e);
        System.out.println("database 오류 발생!");
    }finally {
        this.pw.close();
    }
}

 

- module

public int notice_del(String ck) {
    int result = 0;
    int w=0;
    while(w<ck.length) {
        result += tm.delete("noticeDB.notice_del",ck[w]);	
        w++;
    }

    return result;
}

❗ 반복문은 module에 적는걸 추천 ( controller에 뭘 쓰려구 하지 마세요... )

 

체크박스 추가 화면