관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

닷넷 게시판 만들기 Part 40 본문

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 40

가이브 2011.05.31 15:21

2011/05/13 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 31
2011/05/16 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 32
2011/05/18 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 33
2011/05/19 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 34
2011/05/23 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 35
2011/05/25 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 36
2011/05/26 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 37
2011/05/27 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 38
2011/05/30 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 39


1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/7]
3. asp.net 컨트롤 [10/10]
4. 데이터베이스(DB) [7/7]
5. 닷넷 게시판을 만들어보기 전에.. [4/4]
6. 게시판 만들기 [10/..]
* 별로 길지 않은 내용인데 자르다보니 10회까지 왔네요.


이제 글 읽기 페이지를 만들어보자. 쓴 사람은 제목/내용/첨부파일(옵션) 이렇게 3개 정도만 입력했지만 글 읽기 페이지에서는 대부분의 모든 정보가 보여지게된다. 그래봐야 DB에 저장된 값일 뿐이다.

글 읽기 페이지는 받아온 카테고리(변수 c)와 글번호(변수 n)을 받아와서 카테고리와 글번호에 맞는 단 1개의 레코드의 자료를 가져온다. 리스트에서 방금 클릭한 제목의 글은 분명 존재할 것이다. 만약 아주 비슷한 시간에 글이 삭제되었다면 당연히 자료는 존재하지 않을 수 있다. 예외(Exception)나 오류(Error) 처리도 모두 개발자 몫이다.


예외(Exception)는 프로그램 코드의 문법이 맞으나, 일어날 수 있는 문제를 예상할 수 있는 것이라 볼 수 있다.
없는 값을 읽어오는건 오류다. 그런데 분명 값은 있을 수 밖에 없다. 앞에서 말했지만 글이 사용자로부터 삭제되었을 찰나에(리스트에는 방금 존재했었으나) 글읽기 페이지를 열 때, 이런 경우를 예외라고 볼 수도 있다.
네트워크에 연결하려고 하는데, (당연히 연결이 잘 되어야 하지만) 어떤 이유로 연결이 안 될 수 있기 때문에 이 역시 예외처리를 해줘야한다. 오류(Error)라는 것은 말 그대로 문법이 맞지 않거나 문법이 맞고 컴파일이 잘 작동했으나 원하는 결과가 안나오는 등의 실제 눈에 보이는 것을 오류라고 할 수 있겠다.


이번에는 디자인을 먼저 만들어볼까, 글 읽기 기능에 필요한 라이브러리를 먼저 만들어볼까? 만드는 사람 마음이다. 우리는 공부중이므로 국가의 원수라도 감놔라 배놔라 할 수 없으니 자유롭게 즐기며 학습하길 바란다. =)

Board.cs 를 열어서 글 읽기에 사용될 Read() 메서드를 만들어보도록 하자.
앞서 말했지만 "어디에 있는(카테고리) 어떤 글(글 고유 번호)" 이렇게 두 개의 자료만 있다면 자료를 구별해서 뿌려주는데에는 문제 없을 것 같다. 라이브러리는 외부에서 읽어오게 해야 하므로 public 접근한정자(제한자)를 쓰고, 리턴은 단 한 개의 레코드이지만 여러개의 컬럼을 2개 이상 리턴하므로 그냥 DataTable로 편하게 사용하도록 하자. (혹시 리턴으로 string[] 배열을 생각하셨다면 이 역시 매우 좋은 아이디어이다!) 그리고 조회에 필요한 값들은 string 으로 category, int 로 number 를 받자.


public DataTable Read(string category, int number)
{
..
}


이제 쿼리문을 만들고 결과를 리턴해주면 되겠다. 이미 머릿속에서 자료가 그려지지 않는가? 형태는 이전에 만든 List() 의 리스트 쿼리에서 board_id 가 "number 값"인 조건이 하나 더 붙는 것과 ORDER BY(정렬) 문이 없어지는 정도 밖에 되지 않는다.


Board.cs 에 추가된 글읽기 기능에 사용할 메서드

  public DataTable Read(string category, int number)
  {
   string query = String.Format("SELECT * FROM board WHERE category='{0}' AND board_id={1}", category, number);
   return DB.ExecuteQueryDataTable(query);         
  }



쿼리문에서 문자열 값은 작은 따옴표로 묶어지고, 정수형 값은 붙지 않는다. 이를 컴파일하자.

이제 글읽기 페이지 하단에 붙을 "댓글"관련 기능을 구현하기로 하자.
댓글은 해당 글에 대한 "쓰기, 목록, 수정, 삭제" 정도가 존재한다. 그러니까 다른건 필요없지만 현재 읽고 있는 글의 고유번호인 board_id 와 매치시키는 값이 있어야 한다.

DB관리툴을 열어서 예전에 만든 board_comment 테이블의 구조를 한번 살펴보자.


comment_id 는 댓글의 고유번호로 정했었다. board 테이블의 board_id 와 컬럼명이 같은 board_id 컬럼이 현재 읽고 있는 글과 매치될 녀석이다. 우리가 만약 (카테고리는 어디인지 모르겠지만) 고유번호 5번 글을 클릭해서 들어간 후, 5번 글에 댓글이 작성되면 board_comment 테이블의 board_id 는 5가 들어가면 되겠다. 댓글은 2개 이상 있을 수 있으니 중복되어도 상관없으나, comment_id 는 계속해서 자동으로 늘어나게된다. 머릿속에 꼭 그려보도록 한다. 대부분 댓글 기능 뿐만 아니라 연관성을 주는 프로그램은 이렇게 값을 서로 매치시켜 주면서 구현된다. 

그렇다면 댓글 쓰기에 필요한 값은 어떤 것들이 있는가? 필자가 강조했듯, 테이블에 값을 넣을때는 (1)사용자의 입력값(2)프로그램에서 필요한 값의 형태를 나누어서 생각하자고 했다.


comment_id : 자동으로 늘어나는 값
board_id : 댓글이 엮이는 게시판 고유 글 번호
user_id, user_name : 글쓴이 정보
content : 댓글내용
regdate : 작성일시



가만보니 사용자 입력값은 content 컬럼 단 1개이다. 댓글 역시 로그인 된 사용자만 작성할 수 있으니 게시판에 값을 넣는 형식과  별반 다를게 없어보인다. 프로그램에서 필요한 값 역시 board_id, user_id, user_name 컬럼 3개가 될 수 있겠다. comment_id, regdate 는 자동으로 채워지니 놔두면 된다. 그래서 총 4개.


한번 생각해보자. Board.cs 에서 user_id, user_name 값, "세션변수" 값을 바로 사용할 수 없을까?
그러니까, 라이브러리를 사용하는 쪽에서 값을 Board.cs 의 메서드로 그냥 넘기지 않고 세션변수를 읽으면 일부러 값을 넘길 필요가 없을것이다.
결론을 말씀드리면 세션 변수를 /bin 에 들어있는 라이브러리에서 사용할 수 있다.

HttpContext.Current.[...]
(http://msdn.microsoft.com/ko-kr/library/system.web.httpcontext(v=VS.80).aspx 클릭해서 읽어보자)

간단하게 설명하면, 이렇게 앞에 HttpContext.Current. 를 붙여준다 생각하고 Session, Response, Request, Server 등을 사용할 수 있다.

string logged_id = HttpContext.Current.Session["login_id"];

위처럼 Board.cs 뿐만 아니라 Database.cs 에서도 사용할 수 있다. AAA.aspx 에서 Board 라이브러리를 사용한다고 하면, AAA.aspx 페이지에서 Board 를 요청할 때의 그 상태값을 사용할 수 있다는 말이다.

그러나 '라이브러리'의 용도 자체가 말했듯이 '독립적으로 사용가능'한 녀석이라고 했다.
물론 지금 만드는 게시판 라이브러리인 Board.DLL 은 홈페이지 게시판 용도이지만 모바일 어플(앱)에서도 사용할지 모른다. 또는 윈도우 어플리케이션 개발 용도로 사용할 수도 있다. 심지어 콘솔(Console)용으로도 만들 수 있다. 지금은 게시판 라이브러리를 만들지만 다른 라이브러리도 수 없이 존재한다.

그러므로 이렇게 라이브러리에서 세션값을 직접 사용하는 것을 지양하는 버릇을 들이자. 그래서 우리는 세션값을 일부러(아니, 당연히) string 형으로 넘겨줄 것이다.


댓글쓰기 메서드의 이름은 CommentWrite 로 하고, 정의해보면..


public void CommentWrite(int board_id, string user_id, string user_name, string content)
{
..
}


이렇게 되겠고, 게시판 글 쓰기처럼 INSERT INTO 로 board_comment 테이블에 넘어온 값을 넣으면 되겠다.

  public void CommentWrite(int board_id, string user_id, string user_name, string content)
  {
   string query = String.Format("INSERT INTO board_comment(board_id, user_id, user_name, content) VALUES({0}, '{1}', '{2}', '{3}')",
        board_id, user_id, user_name, content);

   DB.ExecuteQuery(query);
  }


board_id 컬럼은 int 자료형이고 나머지는 varchar 자료형이므로 작은 따옴표를 구분하자. 컴파일을 하면 문법 오류를 확인할 수는 있겠지만 실제 잘 작동할지는 알 수 없다.

초보에게 개발하면서 유용한 팁은, 잘 작동하는지 확인하기 위해서 꼭 프로그램이 필요한 것은 아니다. 가상의 상수값을 넣어서 테스트를 할 수 있다. board_list.aspx 파일을 열어서, Page_Load() 에 맨 밑에 다음처럼 넣어보자.


실제 댓글 작성에 사용할 것 처럼 테스트해본다. 오류가 발생한다면 어딘가 잘못되었을 것이다. 그렇지 않으면 아무 문제 없이 리스트가 열리면서 값이 들어가게 될 것이다.
board_comment 테이블에 값이 잘 들어갔는지 확인해보자.


별 일 없다면(?) 당연히 잘 들어갈 것이다. 자료를 저장하기 위해 사용하는 DB연동의 목적은 "변수"를 잘 조리해서 넣어주는 개념이다. 또한 '쓰기' 기능을 꼭 먼저 만들 필요는 없다. 테이블에 직접 수동으로 값을 넣어주고 리스트나 보기 같은 조회 기능을 먼저 만들면 되겠다.


이제 댓글 리스트를 메서드르 생각해보자. 게시판 리스트와 별 다를게 없다. 게시판의 카테고리가 현재 조회중인 글의 고유 글번호인 board_id 컬럼 값과 동일한 개념이다. 메서드 이름을 CommentList() 로 하고, board_id 를 인수로 받자. 정렬은 최근 댓글이 위로 올라올지 맨 밑으로 내려갈지는 여러분들의 선택이다. 필자는 최근에 작성도니 댓글이 밑으로 내려가게 해보겠다. 자료의 리턴 역시 DataTable 로 하자.

  public DataTable CommentList(int board_id)
  {
   string query = "SELECT * FROM board_comment WHERE board_id=" + board_id + " ORDER BY comment_id";
   return DB.ExecuteQueryDataTable(query);   
  }



이제 별 달갑지 않겠지만 페이지를 디자인 할 시간이다. 늘 말씀드리지만 자기 마음대로 자유롭게 꾸며보자. 어떤 내용을 뿌려줄지도 생각해보자. 일반적으로 봐왔던 게시판도 생각해보자. 들어갈 값들은 미리보기 위해 가상으로 넣어주기로 한다. 파일명은 board_view.aspx 로 한다. 이 때까지 해왔듯 index.aspx 를 다른 이름으로 저장하자.


이 페이지에서는 총 2개의 DataTable 을 가져올 것이다. 하나는 글 본문내용인 board 테이블에서 가져오는 내용이고, 하나는 아래쪽에 있는 댓글 목록인 board_comment 에서 가져오는 DataTable 리스트이다.

board 테이블에서 가져오는 1개의 자료는 지금 위의 그림처럼 디자인된 화면에서 서버컨트롤로 뿌려주면 그만이다. 페이지가 로드될 때 게시물을 가져와서 해당 내용을 그자리에 넣기로 하자. 서버컨트롤은 <span>태그로 렌더링 되는 Label 로 한다.


일단 댓글은 제외하고 이렇게 여섯 개의 Label 컨트롤을 각각에 배치하도록 하자. 배치 후에는 당연히 해당 항목은 비어있을 것이다.

이제 라이브러리와 DataTable 을 사용하기 위해 aspx 상단에 Namespace 를 2개 참조한다. 페이지가 열릴 때 자료를 넣어줘야 하므로 리스트(board_list.aspx)처럼 Page_Load() 메서드를 만든다. 그리고 카테고리, 게시물 고유 번호를 라이브러리에 던져줘서 DataTable 로 결과를 받자. 복잡할 것도 없다. 우리가 해봤던 비슷한 것들일 뿐이다. 거기서 거기다.

(클릭하면 크게 보입니다)


위의 그림이 앞에서 말한 플로우대로 작성한 코드이다. 쭉 대충 읽어봐도 어떤 내용인지 알 수 있을 것이다.
31,32번째 줄의 조회수/추천수는 int 형이다. int 형은 (string)으로 변환하지 못한다. 서버컨트롤 Label.Text 속성은 string 형이다. 그러므로 Object.ToString() 으로 간단하게 변환해서 넣어주면 되겠다.

첨부 파일은 글 작성시 넣을 수도, 넣지 않을수도 있다. 첨부파일을 넣지 않으면 컬럼은 공백이므로 (string)row["file_attach"] 이 빈 값인지 체크해서 파일 첨부가 되었는지 아닌지를 알 수 있다. 파일첨부가 되었다면 39번째 줄 처럼 <a>..</a> 태그를 이용해 '/upload/파일명' 으로 링크를 바로 걸어준다. 매우 간단한 방법이다.


다음 첨부파일은 지금까지 진행한 (필자의)소스 파일이다. 결과물은 아~무 의미가 없다. 결과물을 100번 읽어서 이해하시더라도 직접 한번 이해하면서 해보는 것보다 못하다. 공부는 여러분들이 스스로 하시는 것이다. 



미리 댓글 관련 기능을 구현해보시길.. 이번 Part 는 여기까지이다.


0 Comments
댓글쓰기 폼