검색기능 구현 by Object
1. 먼저 검색을 위한 Search 객체를 생성한다.
package bean;
public class Search {
private String[] area;
private String searchKey;
public Search(){}
public String[] getArea() {
return area;
}
public void setArea(String[] area) {
this.area = area;
}
public String getSearchKey() {
return searchKey;
}
public void setSearchKey(String searchKey) {
this.searchKey = searchKey;
}
}
<Search.java>
2. mybatis-config.xml 의 typeAlias에 별칭을 설정 및 mappers에 mapper 매칭
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="bean.Board" alias="Board"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/oracle"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/Board.xml"/>
</mappers>
</configuration>
<mybatis-config.xml>
3. board.xml 및 BoardMapper 설정
<?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">
<!--namespace는 변별성을 주기위해 앞에 붙여주는 느낌
아래의 listBoard를 호출하기 위해서는 mapper.BoardMapper.listBoard-->
<mapper namespace="mapper.BoardMapper">
<cache/>
<!-- board table을 Board 객체로 반환-->
<select id="listBoard" parameterType="Search" resultType="Board">
select *
from board
<if test="area != null">
<where>
<!-- -->
<!-- where (title LIKE %JSP% OR writer LIKE %JSP)-->
<foreach collection="area" item="item" separator="OR"
open="(" close=")">
<!--column명은 ${}로 감싸야함-->
${item} LIKE #{searchKey}
</foreach>
</where>
</if>
order by seq desc
</select>
</mapper>
<board.xml>
package mapper;
import bean.Board;
import bean.Search;
import java.util.List;
public interface BoardMapper {
// bean/BoardDao2
List<Board> listBoard(Search search);
}
<BoardMapper.java>
4. search 객체 생성 및 입력 값을 통해 초기화
<%@ page import="bean.Board" %>
<%@ page import="java.util.List" %>
<%@ page import="bean.BoardDao2" %>
<%@ page contentType="text/html;charet=UTF-8" language="java"
pageEncoding="utf-8"%>
<%
request.setCharacterEncoding("utf-8");
Search search = new Search();
search.setArea(request.getParameterValues("area"));//getParameterValues = 배열을 반환
search.setSearchKey("%" + request.getParameter("searchKey") + "%"); //request.getParameter = String을 반환
BoardDao2 dao = BoardDao2.getInstance();
List<Board> list = dao.listBoard(search);
%>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="insert_form.jsp">글쓰기</a>
<table border="1">
<tr>
<td>글번호</td>
<td>제목</td>
<td>작성자</td>
<td>작성일자</td>
<td>조회수</td>
</tr>
<%
for (int i = 0; i < list.size(); i++) {
Board board = list.get(i);
%>
<tr>
<td><%=board.getSeq()%></td>
<td><a href="detail.jsp?seq=<%=board.getSeq()%>"><%=board.getTitle()%></a></td>
<td><%=board.getWriter()%></td>
<td><%=board.getRegdate()%></td>
<td><%=board.getHitcount()%></td>
</tr>
<%}%>
</table>
<br><br>
<form action="list.jsp" method="get">
<input type="checkbox" name="area" value="title"> 제목
<input type="checkbox" name="area" value="writer"> 작성자
<input type="text" name="searchKey" size="10">
<input type="submit" value="검색">
</form>
</body>
</html>
<list.jsp>
* request.getParameterValues("{name}") : 배열을 반환
request.getParameter("{key}") : String을 반환
검색 기능 구현 by Map
이전 코드를 기반으로 수정하여, 수정된 부분만 기록하겠다.
...
<%
request.setCharacterEncoding("utf-8");
Map map = new HashMap();
map.put("area", request.getParameterValues("area"));
map.put("searchKey", "%" + request.getParameter("searchKey") + "%");
BoardDao2 dao = BoardDao2.getInstance();
List<Board> list = dao.listBoard(map);
%>
...
<list.jsp>
...
<select id="listBoard" parameterType="java.util.Map" resultType="Board">
select *
from board
<if test="area != null">
<where>
<!-- -->
<!-- where (title LIKE %JSP% OR writer LIKE %JSP)-->
<foreach collection="area" item="item" separator="OR"
open="(" close=")">
<!--column명은 ${}로 감싸야함-->
${item} LIKE #{searchKey}
</foreach>
</where>
</if>
order by seq desc
</select>
...
<Board.xml>
...
List<Board> listBoard(Map map);
...
<BoardMapper.xml>
MyBatis foreach문
* 이번 수업에서 핵심 부분은 Board.xml에서 foreach를 사용하여 query문을 생성하는 방식이였다.
Board.xml을 위주로 이해하면 도움이 될 것 같다.
Attribute
collection : 전달 받을 인자 (type : List or Array)
item : collection을 통해 전달 받은 인자 값을 alias로 대체
open : 구문이 시작될 때 삽입할 문자열
close : 구문이 종료될 때 삽입할 문자열
separator : 인자의 index가 바뀔 때, 삽입할 문자열
#{}, ${}차이
#{}
<select id="test" resultType="..." parameterType="Study">
SELECT *
FROM
TEST
WHERER
ID = #{ID}
</select>
3행에 WHERE ID = #{ID}는 쿼리문이 실행 시 WHERE ID = ?로 파싱
#{} 생성 시 PreparedStatement가 생성되며 위의 ? 값에 파라미터가 바인딩 (재활용(캐싱)이 가능해서 효율적)
parameterType의 ID 필드 값의 앞뒤에 ' 가 붙기 때문에 '#{id}'와 같은 식으로 쿼리문을 작성할 필요가 없다.
${}
<select id="test" resultType="..." parameterType="Study">
SELECT *
FROM
TEST_${INDEX}
WHERER
ID = #{ID}
#{}과는 다르게 값이 먼저 들어가고 파싱이 진행된다.
따라서 파라미터 값이 바뀔 때마다 쿼리문을 파싱을 다시 진행해야한다.
#{}과는 다르게 파라미터 값이 바인딩 될 때, '가 붙지 않기 때문에
TEST_${INDEX}와 같이 이름을 동적으로 사용할 수 있다.
* ${}는 SQL Injection에 취약
<select id="test" resultType="..." parameterType="Study">
SELECT *
FROM
TEST
WHERER
ID = '${ID}' AND password = '${password}'
</select>
외부에서 id에 id'-'를 입력 시
ID = 'admin'-' AND password = '${password}'
이런 식으로되어 비밀번호에 대한 조건이 사라지게 되어 id만가지고도 입력할 수 있어 보안에 매우 취약
참고 : https://madplay.github.io/post/difference-between-dollar-sign-and-sharp-sign-in-mybatis
'kosta > Servlet,JSP,JDBC,MyBatis' 카테고리의 다른 글
[MyBatis] 기초 및 초기 설정 (0) | 2022.04.22 |
---|---|
[MVC] Mybatis, JSP, JNDI를 기반으로 MVC 구현 (PW:0) (0) | 2022.04.21 |
[MyBatis] 실습 (0) | 2022.04.14 |
[JDBC] JDBC 이론 및 JDBC를 이용한 DB와 JSP 연동 1 (PW:0) (0) | 2022.04.14 |
[JSP,Servlet] 기초 (작성중) (0) | 2022.04.14 |
댓글