관리 메뉴

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

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

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 38

가이브 2011.05.27 18:32

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


1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/7]
3. asp.net 컨트롤 [10/10]
4. 데이터베이스(DB) [7/7]
5. 닷넷 게시판을 만들어보기 전에.. [4/4]
6. 게시판 만들기 [8/..]


이번 시간에는 게시판 리스트를 만들어보자. 
4장 데이터베이스(DB)의 Part 25 에서 데이터베이스 리스트에 대해 이미 다뤄봤었다. (지금까지 6장을 진행하면서 처음으로 만난 녀석이 없다)

(게시판) 리스트라고 하면, 데이터베이스에 SELECT 쿼리 명령을 이용해 결과를 받아서 출력하는 것이다. 이 강의에서는 DataSet 으로 결과를 받아오는데, DataSet은 DataTable 의 묶음이라고 보면 된다고 했다.

쉽게 DBMS의 모습을 떠올리면 된다. DataSet은 DB로 보면되고, DataTable은 우리가 하나하나 컬럼과 형식을 지정한 테이블로 보면 된다. DB는 1개 이상의 테이블이 있으니, DataSet.Tables 컬렉션에서 첫번째인 DataSet.Tables[0] 을 사용하면 된다. 회원관리 하기 전에 만들었던 Database 라이브러리의 소스 중 여러개의 결과를 받는(리스트 등의 용도로 사용하는) 메서드를 살펴보자.

  public DataTable ExecuteQueryDataTable(string query)
  {
   DataSet ds = new DataSet();
   DBOpen();

    SqlDataAdapter da = new SqlDataAdapter(query, dbcon);
    da.Fill(ds, "tmp");

   DBClose();

   return ds.Tables[0];   

  }



Part 25 에서 자세히 설명했었는데, SqlDataAdapter 클래스를 이용해서 쿼리의 결과를 인스턴스화 된 DataSet 에 채워준다. 그리고 그것의 첫번째 DataTable(테이블)을 리턴하는 기능이다.

쉽게 DBMS 에서 쿼리문을 날린 형식 그대로가 리턴된다고 보면 된다.
DataTable 에는 DataRows (사용할 때에는 Rows) 라는 컬렉션이 존재하는데, 이것은 실제 자료에 접근할 수 있는 행(Record)라고 생각하면 되고, 각각의 행은 동일한 컬럼(Column) 이 있다. 일반적으로 컬렉션을 생략하고 DataRows 컬렉션의 컬렉션으로 사용하면 된다.

다음은 Part 25 의 자료를 긁어온 내용이다.


(........)
DataTable 은 DataTable.Rows 라는 컬렉션이 있기 때문에 모든 자료를 훑어오는 방법은 현재 dt.Rows.Count (가지고 있는 레코드 수)만큼 루프를 돌리면 된다. 그리고 각각의 컬럼은 간단하게 dt.Rows[현재레코드번호][컬럼컬렉션] 형식으로 읽어오는 것을 볼 수 있다.

DataTable은 SqlDataReader 와 다르게 특정 자료를 그대로 읽어올 수 있다.



dt.Rows[2][3] - 세 번째 레코드의 세 번째 컬럼인 "닷넷초보"
dt.Rows[0][1] - 첫 번째 레코드의 첫 번째 컬럼인
"test_id"
dt.Rows[1]["user_password"] - "1234"

(........)

이것만 이해한다면 여러분들은 닷넷에서 DB를 연동하는 기본을 마스터 하셨기 때문에 어떤 자료라도 DB로부터 가져와 요리할 수 있다. 

DataTable 로 가져온 자료는 역시 Part 25 에서 해본 것 처럼 닷넷 asp.net 서버컨트롤이라 부르는 웹폼을 이용해서 매우 쉽게 출력(표현)할 수 있다.

(...)

dg1.DataSource = ds.Tables[0];

dg1.DataBind();

(...)
<form runat="server">
<ASP:DataGrid id="dg1" runat="server" />
</form>

(...)

위의 내용도 Part 25 에서 예제로 해봤던 내용이다. 웹폼의 '데이터 처리 컨트롤'은 여러가지가 있는데 그 중에서 DataGrid 라는 녀석이다. 

이제 잘 알고 있으시겠지만, 서버컨트롤은 렌더(Render)라는 것을  (이벤트) 통해서 실제 <tag>로 변환된다. TextBox는 <input type="text"> 이고 Label 은 <span>이듯이, 위의 예제에서 DataGrid 의 렌더링 결과물은 <table>태그이다. 달력컨트롤인 Calender 도 <table>태그로 렌더링된다.

만약 여러분들이 테이블 형태가 아닌 데이터를 리스트로 표현하려면 DataGrid 컨트롤을 사용해서는 안된다. 데이터 하나하나가 <td>..</td> 안에 들어가기 때문이다. 대신 이런 컨트롤들의 장점은  많은 기능을 제공해주기 때문에 구현이 쉽다는 것이다. 또 역으로 생각하면 많은 기능을 제공해주는 대신에 이를 구현해주는 기능이 없다면 새로운 기능을 구현하기가 까다롭다는 점이다.

이러한 이유로 asp.net 2.0 에서 제공하는 컨트롤에서 렌더링이 될 때 <table>태그로 되는 녀석들은 다루지 않겠다. 앞에서 DataGrid 를 예제로 쓴 이유는 웹폼의 특징을 설명하기 위해서, 그리고 데이터베이스에서 가져온 자료의 내용을 한눈에 보여주기 위해서 사용했다. 비슷한 녀석으로 DataList 라는 녀석도 존재하는데 이것도 렌더링 결과는 <table>태그이다. (사실 DataGrid 는 버전 2로 오면서 GridView 라는 이름으로 재탄생 되었다고 볼 수 있다.)

GridViewDataList ■ Repeater

위의 링크는 ASP.NET 2.0 Quickstart 라는 MS에서 제공해주는 예제 위주의 문서이다. 영문이지만 실행해보며 설명을 읽어보도록 하자. 이 외에도 데이터 관련 웹폼이 존재하나 생략하도록 하겠다. 본인이 따로 찾아보고 해보시기 바란다.

결론을 말하면, 이렇게 DataTable 로 되어있는 SELECT 의 결과를 받아서 for() 루프를 돌며 자료를 뿌려주는 방법이 있긴 하지만, 앞서 설명한 데이터관련 웹폼을 이용하면 좀 더 편리하다는 말이다. 그리고 웹폼들 중에서 렌더링 될 때 그 결과로 아무런 태그가 붙지 않는 Repeater 컨트롤을 추천해주고 싶다. 렌더링시 태그가 붙지 않기 때문에 여러분들이 매우 자유롭게 꾸며낼 수 있다는 장점이 있다. 이에 대한 단점은 손이 많이 간다는 거..

4장 데이터베이스의 마지막이었던 Part 26 에서 Repeater 컨트롤을 다루었었다.

필자는 확신했었다. 4장까지 모두 숙지하셨다면 이미 게시판을 만들 수 있는 스킬을 가지고 있다고.. 결코 틀린 말이 아니다. 그래서 이렇게 게시판을 함께 만들어 보며 확신을 하는 것이다.

글쓰기에서는 디자인을 먼저 했었는데, 이번에는 Board 라이브러리에서 글 목록 용도의 메서드를 먼저 만든 후에 디자인을 하고 구현해보도록 하자.

메서드명은 List() 로 하기로 한다. 라이브러리는 외부에서 사용할 수 있게 public 으로 접근한정(제한)자를 쓴다. 리턴형은? DataTable.

public DataTable List()
{
    ..
}


이렇게 리스트를 가져오는데.. 조건이 있어야 할 것이다. 일단은 생각할 수 있는 값이 바로 "카테고리"이다. GET으로 변수 "c"를 계속 넘기고 있는데, 지금 테스트로 사용하는 카테고리는 "test" 값이다. 즉, 데이터베이스의 board 테이블의 자료를 가져오는데, category 컬럼이 test 인 것을 가져오면 다른 게시판의 내용을 제외하고 test 만 가져올 수 있는 것이다. 방법으로는 쿼리문에서 WHERE 로 조건을 만들어 쓰면 되겠다.

public DataTable List(string category)
{
    ..
}


또 다른 처리를 위해 받을 값이 더 있다면 차후에 수정하거나 메서드 오버로딩을 이용해서 하나 더 만들어주기로 하자. 우리같은 하수는 몇 천번은 뜯어고쳐야 쓸만한 라이브러리가 완성된다.
다음처럼 일단 리스트의 자료를 가져올 쿼리문을 만들고..

public DataTable List(string category)
{
      string query = "SELECT * FROM board WHERE category='" + category + "'";
}


query 문자열의 예상되는 값은 SELECT * FROM board WHERE category='test' 이다. 문자열 결합일 뿐.. 닷넷은 query 문자열 변수가 쿼리문인지 커리문인지 알 필요가 없다. 즉, asp.net 과 DB는 아~무 관련 없다. (... 좋게 말하면 관련있어 보일 뿐이다

그리고 다음처럼 Database 라이브러리에게 실행하라고 시킨 후,

public DataTable List(string category)
{
       string query = "SELECT * FROM board WHERE category='" + category + "'";
     DB.ExecuteQueryDataTable(query);
}


다음처럼 그대로 리턴해주자.

public DataTable List(string category)
{
      string query = "SELECT * FROM board WHERE category='" + category + "'";
     return DB.ExecuteQueryDataTable(query);
}

(당연히) 이 녀석은 코드 단 1줄로도 변경이 가능하다.

public DataTable List(string category)
{
     return DB.ExecuteQueryDataTable("SELECT * FROM board WHERE category='" + category + "'");
}


라이브러리의 또 다른 장점이다. 만들어 놓으면 쓰는 코드가 간단해질 수 있다는 거..
이 메서드를 Board.cs 에 넣어주고 컴파일하자. 컴파일러가 군말 없어야 성공한 것이다.

이제 Board.cs 파일의 소스가 좀 더 늘어났을 것이다. 지금까지 작성한 필자의 Board.cs 는 다음과 같다.

using System;
using System.Data;

// Database 라이브러리를 이용하기 위한 참조
using Study;

namespace Study
{
 public class Board
 {
  Database DB;

  public Board()
  {
   DB = new Database();
  }


  // 게시판 글쓰기
  public void Write( string category, string user_id, string user_name,
       string title, string content, string upload_file)
  {
   string query = String.Format("INSERT INTO board (category, user_id, user_name, title, content, file_attach) VALUES('{0}', '{1}', '{2}', '{3}', '{4}', '{5}')", 
           category, user_id, user_name, title, content, upload_file);
   
   DB.ExecuteQuery(query);

  }

  // 게시판 목록
  public DataTable List(string category)
  {
    return DB.ExecuteQueryDataTable("SELECT * FROM board WHERE category='" + category + "'");
  }

 }
 
}




Board.DLL 파일은 asp.net 게시판 라이브러리이고, 현재 2개의 메서드를 제공한다.

public void Write( string category, string user_id, string user_name,
string title, string content, string upload_file);

  리턴 
  void 
  인수설명
  category : 저장할 게시판 카테고리 이름
  user_id : 회원ID
  user_name : 회원이름
  title : 글제목
  content : 글내용
  upload_file : 업로드 된 파일명
  메서드설명
  이 메서드는 게시판에 새 글을 쓰는 기능을 합니다.


public DataTable List(string category)

  리턴 
  System.Data.DataTable
 인수설명
  category : 리스트를 불러올 게시판 카테고리 대상이름
 메서드설명 
 category 의 글목록을 DataTable 자료로 리턴합니다.


그럴싸하지 않는가? ^_^

이제 리스트 디자인을 해보자. 아무래도 <table>..</table>이 줄 간격을 맞출 수도 있고 정렬하기가 편하다. 여러분들이 나름대로 우리가 가진 테이블 자료에 맞게 리스트를 꾸며보도록 하자. (지금은 가상의 값을 하드코딩하여 디자인만 꾸며보도록 한다) 

파일명은 board_list.aspx 로 하기로 하자. 전과 마찬가지로 index.aspx 를 다른이름으로 저장하여 시작하면 편하겠다. 그리고 top.ascx 에서 "자유게시판"링크를 board_write.aspx 에서 board_list.aspx로 바꾸는 것도 잊지말자. 다른 곳에서 봤던 게시판을 상상하며 글쓰기 버튼도 배치하자.

(... 본인의 디자인에 너무 한심해 하는 개발자가 되지 말자)

필자는 이 정도로 꾸며보았다. 리스트 하단에 "새글쓰기"로 <a>태그로 <a href="board_write.aspx?c=test">새글쓰기</a> 이렇게 링크를 걸었다.

게시판에는 하단에 페이지를 이동하는 기능이 들어가는데, 언제나 "천천히"가도록 하자. 한번에 여러개를 소화하기는 힘들다. 그리고 개발의 결과물이 나오는 이유는 '기능이 필요하기 때문'이다. 지금은 디자인일 뿐이니, 조금씩 완벽한 게시판을 위해 모래성을 쌓듯 하나 둘 기능을 추가하도록 한다. 결과물은 언젠가 나오게 되어 있다.


여기까지 끊고 다음에 계속하기로 하자.
예습하실 내용은 필자의 예시처럼 나름대로 게시판 디자인을 완료한 후, Board 라이브러리의 List(string category); 메서드를 호출해서 (Part 26 을 참고하면서 Repeater 컨트롤로) 실제 board_write.aspx 에서 여러분들이 막 갈겨썼던 내용을 저대로 실제 자료를 불러오는 것을 해보도록 한다. 아마 스스로 가능할 것이다. ^_^

다음 파일은 여기까지 진행한 (필자의) 전체 소스이다.

 

0 Comments
댓글쓰기 폼