게시판 만들기 - 검색하기(펌)
![]() ![]() |
정말 지루하게 오래 지속되어 온 강좌도.. 이제 마지막 '검색하기' 부분만 남겨놓고 있습니다.
작년 가을에 시작된 강좌가 봄에 끝났으니.. 정말 게으르다는 말을 들어도 할 말이 없네요. -_-a
아는 것도 없으면서 덜컥~ 맡아버린 강좌였는데.. 어찌어찌 하다보니 여기까지 오고 말았군요.
개인적으로 아쉬움이 많이 남는 강좌였지만 나름대로 보람도 컸던 것 같습니다.
자.. 이제 칠판에 마지막으로 한마디만 쓰겠습니다.
"프랑스 만세..." (http://www.kyowoni.com/kid/kidroom/story/fine_09_01.asp)
오늘의 강좌는 '검색하기 ' 부분이 되겠습니다.
아마도 여러분들께서는.. 게시판에서 '검색' 하는 부분을 많이 접하셨을텐데요.
오늘은 그중에서도 가장 기본적인 검색 방법을 알아보도록 하겠습니다.
오늘 작성할 '검색하기' 페이지가 어떻게 작동하는지 강좌에 들어가기 전에 잠시 말씀드리면요...
검색하고픈 분류(이름, 제목, 내용)를 선택한 후, 검색할 단어를 입력합니다. 그리고 '검색' 버튼을 누르면
검색 조건에 일치하는 게시들만 추려서 '목록보기' 페이지의 형식으로 보여지게 할 것입니다.
'검색' 을 하기 위한 가장 핵심 사항은.. '기존 쿼리문에 조건문을 어떻게 주느냐 ' 는 것입니다.
사실.. 기존의 '목록보기' 쿼리문은 아무런 조건 없이 board 라는 테이블에 있는 모든 게시들을 전부~ 가져오는
것이었습니다. 단지 그 정보들을 순차적으로 정렬(ORDER BY) 했을 뿐이지요.
우리는 이미 지난 '리스트 보기(list)' 페이지 강좌에서 '조건문' 의 역할을 접해본 적이 있습니다.
기억이 안나신다면.. 잠시 다녀오시는 것도 나쁘지 않을 것 같습니다...만, 버뜨 그러나~~
여러분이나 저나, 피차.. 한곳에 몰두했을 때 다른 쪽으로 집중이 분산되는 것을 무척 싫어하는 사람들이
아니겠습니까? 더더군다나 그것이 클릭을 몇번씩이나 해야 하는 귀찮은 일이라면 더더욱 말이지요.. ^^
(사담입니다만.. 저희 사장님께서는 '프로그래머들은 적당히 게을러야 한다' 고 항상 말씀하십니다.
그래야만 자신이 귀찮기 싫어서 더 좋은 UI(User Interface)를 생각해 낼 수 있다는 의미지요)
해서.. 오랜만에 Query Analyzer 를 가지고 몇가지 테스트를 해보도록 하겠습니다. (두둥~)
자.. 간만에 나오는 Query Analyzer. 순간 움찔하셨던 분들을 위해서 어떻게 실행하는지 말씀드리면요.
'시작 -> 프로그램 -> Microsoft SQL Server -> Query Analyzer' 를 실행하시면 됩니다.
그러면 로그인 하는 화면이 나오는데요. (화면 이미지까지 다시 올리지는 않아도 되겠지요?)
계정(Login name)과 비밀번호(password)는 여러분들 각자의 환경에 맞는 값들을 입력해 주시기 바랍니다.
(혹시 아직도 'sa' 와 '공백 비밀번호'를 쓰고 계시다면.. 이 참에 비밀번호라도 바꿔주는 것이 좋겠지요. ^^)
자.. 간만에 보는 반가운 Query Analyzer 화면이 떴습니다.
이제 우리는 검색에 관련된 테스트를 해보려고 합니다.
처음이니까.. 아주 간단하게 '김덕영' 이라는 사람이 쓴 게시만을 검색해 보도록 하겠습니다.
그렇다면 쿼리문을 어떻게 작성하면 될까요? 다음과 같이 작성하시면 되겠습니다.
Select * from board Where strName = '김덕영'
<그림 1>
페이지 나누기를 위해서 게시를 많이 입력했더니 상당히 많은 결과가 나오게 되었네요. ^^a
'훗.. 이정도야 이젠 유치하지' 싶으시지요? 자.. 그렇다면 이 상태에서 조금 더 진보된 검색을 알아보겠습니다.
글 쓴 사람중에.. '덕영'이가 있다는 것을 알고 있는데, 그 사람이 김덕영인지 이덕영인지.. 도무지 모르겠다
싶으면 어떻게 할까요?
Select * from board Where strName = '덕영'
혹시 이 방법을 생각하셨습니까? 아쉽게도.. 이렇게 하면 한개의 게시도 검색할 수가 없습니다.
이 조건문은 게시를 쓴 사람의 이름이 정확하게 '덕영' 인 경우 에만 해당하기 때문이지요.
그렇다면 어떻게 하면 좋을까요?
이런 경우에는 'like' 를 사용합니다.
이것은 '%' 문자와 함께 쓰이며, 조건에 해당하는 문자가 있는 경우를 모두 검색 합니다.
'%' 문자가 '%덕영' 처럼 앞에 있는 경우에는 문자열의 앞은 신경쓰지 않고, 마지막이 '덕영' 으로 끝나는 모든 게시를 검색하고, '덕영%' 의 경우에는 '덕영' 이라는 문자로 시작하는 게시를 모두 검색 합니다.
그렇다면 '%' 문자를 앞뒤로 모두 넣는 경우에는 어떻게 될까요? '%덕영%' 처럼 말이지요.
네.. 짐작하신 대로 문자열 전체를 통틀어서 '덕영' 이라는 문자가 존재하는 모든 게시를 가져오게 됩니다.
말만 자꾸하면 머리 아프시지요? 자.. 다음 쿼리문을 한번 실행해 보시지요.
Select * from board Where strName like '%영%'
<그림 2>
자 어떻습니까? 보신 것처럼 이름에 '영' 자가 들어간 사람은 '영'자의 위치와 상관없이 모두 검색이 된 것을
보실 수가 있습니다.
게시판에서 사용자들이 검색을 함에 있어서, 게시판 개발자로서 알아두어야 할 사항은...
대부분의 사용자들은 결코 '완전한' 단어로 검색하려 하지 않는다는 것 입니다.
예를 들어서, 글 제목이 ' 너무너무 감동적인 글입니다. 꼭 읽어봐 주세요' 라는 글이 있는데 이 글을 검색하고자
한다면.. 아마도 '감동' 과 같은 짧은 단어로 검색하려 할 것입니다. 이것마저 길다고 생각하시는 분들은 '꼭'
이라고 입력한 후 검색하기도 하지요. (제가 후자의 경우에 들어갑니다. ^^)
그렇기 때문에 검색에 있어서 like 검색은 선택이 아니라 필수사항이 되는 것입니다.
자. 그럼 우리가 쿼리문에서 like 검색을 하기 위해서는 꼭 필요한 두가지를 받아와야 하겠습니다.
그 하나는 '검색 조건' 이고, 또 하나는 '검색어 ' 가 되겠습니다. 다시 쓰면 다음과 같습니다.
Select * from board Where + 검색 조건 + like + 검색어
만약 '제목'(검색조건) 중에서 '강추'(검색어) 라는 단어가 들어간 게시를 검색하려면 어떻게 할까요?
네. 오른쪽과 같이 하면 되겠습니다. (Select * from board Where strSubject like '%강추%')
그렇다면 '내용' 중에서 '입니다' 라는 단어가 들어간 게시를 찾고싶다면?
이번에도 오른쪽과 같이 하시면 됩니다. (Select * from board Where strContent like '%입니다%')
자.. 우리는 위와 같은 결과를 보면서 이 검색의 규칙을 파악할 수가 있겠습니다.
'검색 조건' 과 '검색어' 만 넘겨주면 아주 간단하게 검색을 할 수 있다는 사실이 바로 그것이지요.
아주 간단하기에.. 우리는 '검색하기'를 위한 새로운 페이지를 만들지 않고, 기존의 list 페이지에서
'검색하기' 기능이 추가된 '업그레이드된 list.asp' 페이지를 만들어보고자 합니다.
사실.. 새로운 '검색 결과' 페이지를 만들까.. 고민을 했습니다.
하지만 저희 형 책인 <taeyo's ASP> 에서 검색 결과를 새로운 페이지로 만드는 부분을 이미 다루었고,
제가 준비한 강좌가 그 책의 내용과 상당부분 겹치게 되는 까닭에 다른 방법을 택하기로 결심했습니다.
(많은 분들께서 taeyo's ASP 책의 게시판 만들기 부분과 병행하면서 공부하신다는 메일을 주시더군요.)
그래서 우리는.. 새롭게 검색 결과를 보여주는 페이지를 만들지 않을 생각입니다.
기존의 list.asp 페이지에 검색 기능을 더한, 조금은 업그레이드된 list.asp 페이지를 만들도록 하겠습니다.
자.. 그러면 이제 바뀐 소스를 살펴볼 시간입니다.
'list.asp' 페이지를 살포시~ 열어주시고요. 빨갛게 표시된 부분을 중심으로 수정해 주시기 바랍니다.
<list.asp>
01 |
<% |
자.. 그럼 위의 소스를 천천히 분석해 보도록 하겠습니다.
우선 10, 11번 줄에서 검색에 관련된 변수들을 선언하였습니다.
strSearchWord 는 검색 조건, strSearchString 은 검색어를 의미하고, strSearchSQL 은 검색에 관련된
조건문을 추가할 때 붙을 SQL 문 이 들어갈 변수가 되겠습니다.
blnSearch 는 현재 이 페이지가 검색이 실행되었는지(true) 아닌지(false) 를 나타내는 변수가 되겠습니다.
그리고 14~16번 줄까지는 각각의 변수들에 해당하는 값을 받아오거나 지정하는 부분이 되겠습니다.
14, 15번 줄은 '검색 조건' 과 '검색어' 를 get 방식으로 받아오는 부분이 되고요.
기본적으로 리스트 페이지는 검색 하지 않은 상태라고 가정하고 blnSearch 값을 false 로 주었습니다.
그리고.. 24번 줄에서 '검색어' 에 해당하는 strSearchString 이라는 변수의 길이(Len)가 0이 아닌 경우
25~27번 줄의 내용을 실행하게 됩니다. 검색어(strSearchString) 의 길이가 0이 아니라는 의미 는 검색을
위해 검색어를 입력받았다는 의미가 되는 것 이기 때문이지요.
'무슨 소리야? 왜 검색어를 입력받았다는 의미가 되는데?' 라고 의문을 가지는 분들이 계실것 같아서 잠시 이 부분에 대한 부연 설명을 드리고 넘어가겠습니다. 우리는 잠시 후 아래부분(76~84번줄)에서 검색을 위한 select 컨트롤과 text 하나를 추가할 것입니다. 그 곳에서 '검색할 분류' 를 선택하고 '검색하려는 단어' 를 입력한 후에 '검색' 버튼을 누르게 되면 그 값들이 다시 자기 자신의 페이지(list.asp)로 전송이 되도록 할 것입니다. 그렇게 넘겨진 값들이 14, 15번 줄에서 각각의 해당하는 변수로 들어가게 되는데요. list.asp 페이지가 처음 보여지거나 또는 다른 페이지로 이동하는 작업만을 수행했다면 14, 15번의 변수에는 아무런 값들도 들어가게 되지 않을 것입니다. (아무런 값을 받지 못했으니까요) 하지만 '검색어' 를 입력하고 '검색' 버튼을 눌렀을 경우에는 위의 변수에 그에 해당하는 값들이 들어가게 될 것입니다. 여기에서는 검색어에 해당하는 변수 strSearchString 에 값이 있는지 없는지를 검사하여 검색한 상태인지 검색하지 않은 상태인지를 판별한다는 의미가 되겠습니다. |
검색어가 있는 경우의 처리는.. 우선 검색실행 여부를 나타내는 변수인 blnSearch 를 true 로 변경하고요.
26~27번 줄에서는 조건문을 담을 쿼리문인 strSearchSQL 를 작성 하게 됩니다.
이해를 돕기 위해 26~27번 줄을 한줄로 나타내면 다음과 같게 될 것입니다.
strSearchSQL = " Where " & 검색조건 & " like '%" & 검색어 & "%'" (띄어 쓰기에 유의하세요)
만약 검색조건이 이름(strName) 이고, 검색어가 '꽤싸뚜' 였다면 위의 쿼리문은 다음과 같이 될 것입니다.
strSearchSQL = " Where strName like '%꽤싸뚜%'"
자.. 그럼 여기서 초수퍼울트라에로틱스릴러판타스틱깜짝돌발퀴즈(-_-;)를 드리도록 하겠습니다.
지금 작성한 이 '조건절 쿼리문' (strSearchSQL) 은 list.asp 페이지에서 언제나,항상,꼭 사용해야 하는 것일까요?
"네에~!!!" 라고 망설임 없이 대답하신 분이라면.. OX 퀴즈에 상당히 약한 분이십니다.
강좌에 조금 더 집중해 주시기 바라고요.. 아쉽지만 다음 기회에 다시 도전을 해주시기 바랍니다.
이 '조건절 쿼리문' 은 항상 실행되는 것이 아니라 '검색이 실행되는 경우에만 ' 실행되어야 할 것입니다.
즉, blnSearch = true 인 경우에만 실행된다는 의미지요.
그래서.. 33~35번 줄과 54~56번 줄에서는 기존의 쿼리문에다가 조건절 쿼리문을 추가하였습니다.
항상? 아닙니다. '검색이 실행되었을 때에만' 이 조건절 쿼리문을 추가하는 것이지요.
그런데.. 54~56번 줄에 들어가는 '조건절 쿼리문' 의 경우 위치를 주의하셔야 합니다. '조건' 을 타나태는
Where 절의 경우 ORDER BY 절보다는 앞서 나와야 하기에 쿼리문 중간에 끼워넣은 것입니다.
그리고 넘어가서.. 69번 줄에서는 값을 전달하기 위해 <form> 을 지정하는 것을 보실 수가 있습니다.
form 의 이름은 검색(search)을 위한 폼이기에 searchForm 이라고 지어보았습니다.
그리고 방식(method)은 get 방식을 선택했습니다. 그런데.. 웬지, 무언가가 허전하지 않습니까?
네에~. 그렇습니다. 값을 전달받는 페이지를 지정하는 action 이 빠져있지요.
action을 생략하면 값들은 자기 자신의 페이지로 넘겨지게 됩니다 .
그러므로 우리는 그렇게 받아온 값들을 14, 15번 줄에서 적절하게 처리하는 것이지요.
76~84번 줄까지는 '검색 분류' 를 위한 select 컨트롤과 '검색어' 를 위한 text 컨트롤을 만드는 부분이
되겠습니다. 이 중에서 option value 에 주의해 주셔야 하는데요. 여기서.. value 값이 board 테이블의
컬럼 이름과 동일 하다는 것을 눈치채셨는지요? 눈치채셨다면 눈썰미가 대단한 분이십니다. ^^
이렇게 value 값과 테이블 컬럼 이름이 같게 되면 '조건절 쿼리문' 에서 그대로 사용할 수 있습니다.
그렇기에 대부분의 검색에서 option value 값을 검색하고자 하는 table 컬럼명으로 많이 사용하지요.
어쨌든.. 검색을 위해 select 컨트롤과 text 컨트롤, 그리고 submit 버튼을 하나 만든 것 외에는 이부분에서
별다른 것이 없어 보입니다. 이해하기 어렵지 않은 부분이리라 생각합니다.
그렇게 주욱~ 진행하다가 '페이지 나누기' 부분에서 반복되어 붙어 있는 어떤 부분을 보실 수가 있습니다.
138~139, 150~151, 162~163번 줄에 나와있는 아래 내용이 바로 그것입니다...
"&search_word=" & strSearchWord & _
"&search_string=" & strSearchString & _
'search 라는 단어가 자꾸 들어가는 것으로 미루어 보아 아무래도 검색에 관련된 값들이겠군..' 싶으시지요?
빙고~입니다. 이 부분은 검색을 위해서 받아온 '검색분류' 와 '검색어' 값들을 페이지가 이동될 때 Get 방식으로
넘겨주는 부분이 되겠습니다.
그렇다면... 도대체 왜 이 값들을 페이지가 이동될 때마다 추가해서 넣어주는 것일까요?
그 이유는.. '검색 후의 페이지 나누기 ' 가 필요할 수 있기 때문입니다.
예를 들어 보겠습니다.
여러분들께서 만든 '태지 보드' 게시판의 인기가 아주 높아서.. 게시가 상당히 많은데요.
그 게시판은 페이지 크기(intPageSize)가 10 이고, 그 게시들 중 '꽤싸뚜' 님이 작성한 글은
모두 29개가 있다고 가정해 보겠습니다.
'검색 조건' 을 '이름' 으로, '검색어' 를 '꽤싸뚜' 로 입력한 후 '검색' 버튼을 누르면 어떻게 되겠습니까?
아마도 검색 결과가 29개가 나올 것이고, 검색한 결과는 모두 3페이지가 나올 것입니다.
그렇다면 검색이 된 상태에서 다음 페이지로 이동하면 어떻게 될까요?
우리는 검색된 두번째 페이지로 이동하기를 원하고 있습니다. 하지만 저 위의 두줄이 없다면..
두번째 페이지는 '검색 결과의 두번째 페이지' 가 아닌 '전체 목록의 두번째 페이지 ' 로 이동하게 됩니다.
으음... 이것은 예측하지 못한 사태입니다. 우리는 이런 결과를 원한 것이 아닌데 말이지요.
왜 이런 현상이 발생하는고 하니.. 페이지가 이동되면서 '검색 조건' 과 '검색어' 를 담는 변수(14,15줄)에
아무런 정보를 전달해 주지 못했기 때문입니다.
이 문제를 해결하는 방법은 생각보다 간단합니다.
'검색조건(strSearchWord)' 과 '검색어(strSearchString)' 에 담겨져 있는 값을 페이지가 이동할 때마다
Get 방식으로 넘겨주기만 하면 되는 것입니다. 그 변수에 값이 들어가 있건 없건 상관없이 말이지요.
(값이 없다면 24번 줄의 조건을 만족시키지 못해 26~27번 줄의 조건절 쿼리문(strSearchSQL) 이 만들어지지
않을 테고, 값이 있다면 조건절 쿼리문이 작성되어서 검색된 결과의 다음 페이지가 보여지게 될 것입니다.)
그래서 위의 두줄이 필요했던 것입니다. 검색에 관련된 값들을 Get 방식으로 넘기기 위해서 말이지요.
기억력이 좋은 분이시라면 제가 지난 시간에 137~140 번줄까지를 '한줄로 입력하세요' 라고 말씀드렸던 기억이 나실 것입니다. 하지만 이 부분에서 에러를 만나시는 분들이 생각보다 많고, 또 그다지 보기도 좋지 않아서.. 오늘의 강좌에서는 한줄로 쓰지 않아도 되는 방법을 사용하였습니다. (아마도 이미 다들 알고 계시는 내용인데 뒷북을 치는 것인지도 모르겠네요. 두우웅~~~~~~) 행을 바꾸지만 시스템에 한줄로 인식시키는 방법은 '연결기호(&) + 언더스코어(_) ' 가 되겠습니다. 즉.. 아래의 두 문장은 같다는 의미가 되는 것이지요. (물론 보여지는 결과 역시 똑같습니다.) Response.Write "How do you do~ " & _ "(너 두유를 어떻게 할거니~)" Response.Write "How do you do~ (너 두유를 어떻게 할거니~)" 혹시 모르셨다면 유용하게 사용하시기를 바랍니다. ^^ (너 두유를어떻게할거니~개그는 최광년(mobil313) 구독자님께서 보내주셨습니다. 감사합니다) |
페이지 나누기 부분을 지나 170~172번 줄에서는 (기본)목록으로 돌리는 링크를 만들어 놓았습니다.
이 부분은 검색이 이루어졌을 때에만 보이게끔 되어 있는데요. 그 이유는 검색이 이루어진 페이지에서
다시 원래의 목록보기 페이지로 돌아갈 수 있게 해주기 위함 입니다. 친절하지 않습니까?
자.. 이렇게 해서 검색부분까지 모두 알아보았습니다.
어떻습니까? 리스트 페이지 안에서 검색까지 모두 마치게 되니까 꽤 편리하다는 생각이 들지 않으십니까?
오늘 강좌의 서두에서 잠시 말씀드렸지만, 저희 형님께서 taeyo's ASP 책에서 검색 페이지를 따로 만드는
방식을 선택했기 때문에, 저는 list.asp 페이지에 통합시키는 방법을 선택했습니다.
어느 방법이 더 좋다, 또는 어느 방법이 더 빠르다~ 는 비교를 하려는 의도는 아니고요.
단지 꼭 하나의 방법이 아니라.. 이런 방법도 있고, 저런 방법도 있다는 말씀을 드리고 싶었던 것입니다.
사실 제가 지금까지 초보 분들을 위해서 '게시판 만들기' 강좌를 진행해 왔지만..
그것이 '게시판은 무조건 이렇게 만들어야 한다' 는 의도는 아니었음을 꼭 말씀드리고 싶습니다.
제가 진행한 '게시판 만들기' 강좌는 일반적, 보편적인 기준에서 이미 널리 알려진 게시판의 형식을
따다가 여러분들께 말씀드린 것 뿐이지요.
지금껏 강좌를 보던 여러분의 머릿속에 불현듯 '저런 부분은 저렇게 하는 것보다 이렇게 하는게 낫지 않을까?'
하는 생각이 들 수도 있습니다. 그렇다면 그 생각이 사라지기 전에 직접 실행하시고, 또 도전하십시오.
잘 모르겠거든 알때까지 관련 서적을 찾아보십시오. 책을 찾아도 모르겠다면, 알만한 사람 하나 붙잡고
의문이 풀릴때까지~ 물어보십시오. ^^
이 강좌를 읽고 계신 여러분들은(저를 포함해서) 아직 '초보운전' 의 딱지를 못떼신 분이라고 생각합니다.
그렇다면 우리는 우리가 잘 모르는 새로운 내용들을 받아들이는 것을 두려워해서는 안될 것입니다.
아쉬운 현실이지만, 지금 현재의 우리보다 ASP 를 잘하는 고수들은 서울에서 김서방 찾기만큼 쉬운 일이
되어 버렸습니다. 그리고 그분들은 C# 이네, 닷넷이네.. 하면서 끝없이 달려나가고 있습니다.
재미로 게시판을 하나 만들어보기 위해... 이 강좌를 참고하신 분들께는 해당사항이 없는 말이겠지만,
본격적으로 웹 프로그래밍을 업으로 삼으시려는 분이라면, 이제 가속을 붙일 시간이 되었습니다.
달려나가는 고수분들보다 더 앞서나가기 위해서는... 그 분들보다 더 열심히 달리는 수밖에 없지 않겠습니까?
(오오... 멋진 말이지 않습니까? 형님한테 들은 말입니다. -_-a)
그동안 지루하고 부족한 강좌에 관심 가져주시고, 질책 및 격려해주신 많은 분들께..
이 자리를 빌어서 감사의 말씀을 드리고 싶습니다. 한분 한분 인사드리지 못한 것을 죄송하게 생각합니다.
모두모두 항상 건강하시고, 늘 행복하시기를 기도드립니다.
특히 강좌 전체를 통틀어 많은 도움을 주신 꽤싸뚜(cassatt)님과 꼬마앙마(comadevil)님께 특히~
감사하다는 말씀을 전해드리고 싶습니다.
이상으로 '초보자도 할 수 있다 - 게시판 만들기' 강좌를 마치도록 하겠습니다. 감사합니다.
P.S (추신, 덧붙임..)
저번 강좌에서 약속드린대로.. 이 게시판이 초보용을 지나 제법 쓸만한 게시판이 되기 위해
'번외편' 을 조금씩 올리도록 하겠습니다. (이게 무슨 장편 무협 소설두 아니구... 흠흠)
'번외편' 에서는 여러가지 에러 체크나 몇가지 기능의 추가 등이 있을 예정입니다.
'My work space > JSP/Servlet' 카테고리의 다른 글
jsp/Servlet 기본2 (0) | 2008.09.08 |
---|---|
JSP/Servlet 기본 (0) | 2008.09.08 |
게시판만들기-페이지나누기(펌)ASP (0) | 2008.09.08 |
게시판 만들기 - 수정, 삭제하기(펌) (0) | 2008.09.08 |
Database Connection Pool (DBCP)의 사용 (0) | 2008.09.08 |