• 40 minutes to read

13 CRUD(Create, Read, Update, Delete) 작업 데이터베이스 프로그래밍에서 가장 많이 이루어지는 작업인 데이터 입력, 조회, 수정, 삭제 등을 CRUD라고 합니다. ADO.NET을 사용하여 데이터 처리를 위한 입력, 출력, 상세보기, 수정, 삭제, 검색 등의 패턴을 코드로 정리합니다. 참고로 CRUD는 ‘크러드’라고 읽습니다.

13.1 CRUD란?
데이터베이스를 다룰 때 Create(입력), Read(출력), Update(수정), Delete(삭제) 등의 기능을 줄여서 CRUD 또는 CRUD 작업(Operation)이라고 합니다. 이번 강의에서는 데이터베이스에 대한 CRUD 작업인 입력, 출력, 상세 보기, 수정, 삭제, 검색 등의 로직을 수행하는 데이터베이스 처리 패턴을 정리해보겠습니다. 참고로, REST Web API에서는 Post, Get, Put, Delete의 4가지 단어를 사용합니다.

13.1.1 CRUD와 연관된 메서드 이름
CRUD 관련 메서드 이름을 지을 때에는 Add, Get, Update, Remove 등의 단어를 많이 사용합니다. 이러한 단어를 접두사 또는 접미사로 사용하는 것은 권장 사항이지 필수 사항은 아닙니다.  Add()  AddHero()  Get()  GetAll(): 최근에 GetAll() 메서드 이름을 많이 사용하는 경향이 있습니다.  GetHeroes()  GetById()  GetHeroById()  Update()  UpdateHero()  Remove()  RemoveHero() 일반적으로 CRUD 관련해서 이름 지을 때 데이터 출력은 Get, 입력은 Create, Add, New 수정은 Update, Modify, Edit, Change 그리고 삭제는 Delete, Remove 중 하나를 사용합니다. 또는 기억하기 편하게 빵을 의미하는 “BREAD”로 표현할 수도 있습니다. Bread는 Browse(보기), Read(읽기), Edit(편집), Add(추가), Delete(삭제)의 앞자를 따서 기억하면 됩니다. 추가적으로 검색(Seach)을 이름에 넣을 수 있습니다. 참고로, 오랜기간 내가 가장 많이 사용한 단어는 입력(Write), 출력(List), 상세(View), 수정(Modify), 삭제(Delete), 검색(Search)입니다.

13.1.2 CRUD와 연관된 저장 프로시저 이름 짓기
테이블명이 Products라면 그 뒤에 Create, Read, Update, Delete를 접미사로 붙이는 방법도 하나의 방법으로 사용됩니다. 접미사 및 접두사 붙이는 방법에 대한 내용은 공식은 따로 없습니다. 필요할 때마다 메서드 또는 저장 프로시저의 이름을 읽기 편하게 하면 되는 것입니다.  Create  ProductsCreate  ProductsInsertCommand  Read  ProductsRead  ProductsReadByProductId  ProductsSelectCommand  Update  ProductsUpdate  ProductsUpdateCommand  Delete  ProductsDelete  ProductsDeleteCommand

13.1.3 CRUD 구현을 위한 공식과 같은 학습 단계
입력, 출력, 상세, 수정, 삭제, 검색, 페이징, 소팅, 에디팅(팝업), 딜리팅(팝업), 업로드(파일), 다운로드(파일), 차트, 임포트(엑셀), 익스포트(엑셀), 로깅, 지도, 캐싱, 답변, 비디오, 캘린더, …

건수, 입력, 출력, 상세, 수정, 삭제, 검색, 페이징, 소팅, 팝업, 차트, 캐싱, 로깅, 매핑, 보고서, …  입력(Add)  출력(Read)  상세(Browse)  수정(Edit)  삭제(Delete)  검색(Search)  자동 완성(Auto Complete)  페이징(Paging)  소팅(정렬, Sorting, Ordering)  팝업(Popup, Modal)  차트(Chart)  캐싱(Caching)  로깅(Logging)  매핑(Mapping)  보고서(Reporting)  엑셀(Excel)  워드(World)  PDF 일반적으로 CRUD + Chart, 지도, 보고서 등의 기능을 구현할 줄 알면 일반적인 닷넷 프로젝트에서 ASP.NET 기술로 일을 할 수 있는 기초(또는 경력)가 됩니다.

13.1.4 BREAD SHOP: CRUD 관련 개체 이름 짓기 패턴
데이터 저장소 관련 이름 짓기가 고민일 때에는 제과점(Bread Shop)을 생각합니다. 아래 메서드 이름은 필자가 만든 NuGet 패키지인 Dul.dll 파일의 Dul.Data.IBreadShop 인터페이스에 정의되어 있습니다.  Browse: 상세  Read: 출력  Edit: 수정  Add: 입력  Delete: 삭제  Search: 검색  Has: 건수  Ordering: 정렬  Paging: 페이징

13.1.5 CRUD와 관련된 파일 이름
CRUD 관련 페이지 또는 파일 이름은 다음을 많이 사용합니다. 이 패턴은 MVC의 스캐폴딩에서 주로 사용되는 이름입니다.  Create: 입력  Index: 출력  List: 리스트도 파일 이름 또는 접미사로 많이 사용됨  Details: 상세 보기  Edit: 수정 또는 삭제  Delete: 삭제  Manage: 관리  Empty: 빈 페이지 페이지 명도 Delete, Search, Reply와 같은 접미사를 붙여서 파일을 만들 수 있습니다.

[그림] Blazor 게시판의 폴더 및 파일 구조

13.1.6 Seed 메서드로 기본 값 초기화하기
특정 클래스에 Seed() 이름의 메서드를 만들고 특정 조건에 맞는 데이터를 미리 준비할 수 있습니다. 예를 들어 1월부터 12월까지의 데이터를 한번에 만들어 놓고 각각의 데이터를 추후 채워나가는 형태의 구조에서는 Seed() 메서드가 어울립니다.

13.1.7 입력, 출력, 상세, 수정, 삭제, 검색, 페이징, 소팅 등
웹 페이지 작성시 가장 많이 하는 작업은 이 절의 제목인 입력, 출력, 상세보기, 수정, 삭제, 검색, 페이징, 정렬, 자동완성, 팝업(모달), 엑셀 업로드 및 다운로드, 차트 표현, 캐싱 등의 기능을 둘 수 있습니다. 이러한 기능들은 하나의 모듈화된 기능을 구현할 때 공식처럼 사용하는 기능이기에 숙달해두면 개발에 편리함을 느낄 수 있습니다.

13.2 웹 응용 프로그램 제작의 첫 번째 패턴 익히기: 입력 13.2.1 데이터 입력(Write/Add/Insert/Save/Persist) 패턴 웹 응용 프로그램을 제작하다 보면 여러 가지 패턴이 나오는데 그 중에서 데이터를 저장하는 입력 패턴이 있습니다. 프로그래밍 API 작성 시 Write, Add, Insert와 같은 접두사 또는 접미사를 주로 사용합니다. 13.2.2 입력 패턴의 사용 예  게시판 글쓰기  회원 가입  일정 등록  상품 등록

13.3 [실습] Memos 테이블에 데이터 입력하기 13.3.1 소개 데이터 입력 시 가장 기본이 되는 코드를 살펴보겠습니다.

13.3.2 따라하기 (1) Visual Studio를 실행한 후 <파일 > 열기 > 프로젝트/솔루션> 메뉴를 클릭하여 DevADONET 웹 프로젝트를 불러옵니다.

(2) 솔루션 탐색기에서 DevADONET 웹 프로젝트에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 다음 FrmMemoWrite.aspx라는 이름으로 웹 프로젝트에 웹 폼을 추가합니다. 그리고 웹 프로젝트에 있는 Models 폴더에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 다음 클래스를 선택하고 Memo.cs 이름으로 클래스 파일을 생성합니다. 템플릿 이름 이름 웹 폼 FrmMemoWrite.aspx 클래스 /Models/Memo.cs

(3) Models 폴더의 Memo.cs 클래스 파일을 다음과 같이 작성합니다. Memo.cs, MemoModel.cs, MemoViewModel.cs 형태로 만드는 모델 클래스들은 일반적으로 테이블의 이름과 일대일입니다. 테이블의 데이터는 List<Memo> 형태의 컬렉션에 담긴다.

using System;

namespace DevADONET.Models
{
    /// <summary>
    /// Memos 테이블과 일대일 매핑되는 Memo 클래스
    /// </summary>
    public class Memo
    {
        public int Num { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Title { get; set; }
        public DateTime PostDate { get; set; }
        public string PostIp { get; set; }
    }
}

(4) FrmMemoWrite.aspx 페이지에 다음과 같이 입력합니다.

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="FrmMemoWrite.aspx.cs" Inherits="DevADONET.FrmMemoWrite" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>입력 패턴</title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <h3>데이터 입력</h3>
    이름: <asp:TextBox ID="txtName" runat="server"></asp:TextBox><br />
    이메일: <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox><br />
    메모: <asp:TextBox ID="txtTitle" runat="server"></asp:TextBox><br />
    <asp:Button ID="btnWrite" runat="server" Text="저장" 
        OnClick="btnWrite_Click" />&nbsp;
    <asp:Button ID="btnList" runat="server" Text="리스트" 
        OnClick="btnList_Click" />
    <hr />
    <asp:Label ID="lblDisplay" runat="server"></asp:Label>
</div>
</form>
</body>
</html>

웹 폼에 등록된 컨트롤의 주요 속성은 다음과 같습니다. 컨트롤 속성 값 TextBox ID txtName txtEmail txtTitle Button ID btnWrite Text 저장 Button ID btnList Text 리스트 Label ID lblDisplay

(5) FrmMemoWrite.aspx.cs 파일을 열고 다음과 같이 코드를 작성합니다.

using System;
using System.Configuration;
using System.Data.SqlClient;
using DevADONET.Models;

namespace DevADONET
{
    public partial class FrmMemoWrite : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnWrite_Click(object sender, EventArgs e)
        {
            // [0] 변수 선언부
            Memo memo = new Memo();
            memo.Name = txtName.Text;
            memo.Email = txtEmail.Text;
            memo.Title = txtTitle.Text;
            memo.PostDate = DateTime.Now;
            memo.PostIp = Request.UserHostAddress;
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("WriteMemo", con);
            //cmd.Connection = con;
            //cmd.CommandText = "WriteMemo";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [!] 파라미터 추가
            cmd.Parameters.AddWithValue("@Name", memo.Name);
            cmd.Parameters.AddWithValue("@Email", memo.Email);
            cmd.Parameters.AddWithValue("@Title", memo.Title);
            cmd.Parameters.AddWithValue("@PostIP", memo.PostIp);
            // [!] 실행
            cmd.ExecuteNonQuery(); 
            // [3] 마무리
            con.Close();
            lblDisplay.Text = "저장되었습니다.";
        }

        protected void btnList_Click(object sender, EventArgs e)
        {
            Response.Redirect("FrmMemoList.aspx");
        }
    }
}

<설명> 명령어를 담당하는 커멘드 개체는 아래 3줄짜리 코드를 생성자를 사용하여 1줄로 줄일 수 있습니다. SqlCommand cmd = new SqlCommand(); cmd.Connection = con; cmd.CommandType = "WriteMemo";

  • 에서 - SqlCommand cmd = new SqlCommand("WriteMemo", con);
  • 으로 -

이렇게 코드를 줄여서 표현하는 것은 SqlConnection과 SqlCommand와 같은 ADO.NET 클래스들은 모두 생성자와 속성을 통해서 여러 가지 모양으로 표현될 수 있습니다. </설명>

(6) FrmMemoWrite.aspx에 마우스 오른쪽 버튼을 클릭하여 <시작 페이지로 설정> 메뉴를 선택하고 [Ctrl]+[F5]를 눌러 실행하면 웹 브라우저에 다음과 같이 출력됩니다.

그림 13 1 입력 패턴 웹브라우저 실행 결과

데이터 입력 폼이 출력되면 값을 입력합니다. <저장> 버튼을 클릭하면 위 그림과 같이 “저장되었습니다.”라는 메시지가 출력됩니다.

13.3.3 마무리 12장에서 만든 Memos 테이블에 데이터를 저장하는 WriteMemo 저장 프로시저를 호출하여 데이터를 저장하는 웹 페이지를 제작해보았습니다.

13.4 웹 응용 프로그램 제작의 두 번째 패턴 익히기: 출력 13.4.1 출력(List/Get/Select) 패턴 웹 응용 프로그램을 제작하다 보면 여러 가지 패턴이 나오는데 그 중에서 데이터를 출력하는 패턴이 있습니다. 프로그래밍 API 작성시 List, Get, Select와 같은 접두사 또는 접미사를 주로 사용합니다.

13.4.2 출력 패턴의 사용 예  게시판 리스트  회원 리스트  상품 리스트

13.5 [실습] Memos 테이블의 모든 데이터 출력하기 13.5.1 소개 데이터 출력 시 가장 기본이 되는 코드를 살펴봅니다.

13.5.2 따라하기 (1) Visual Studio를 실행한 후 <파일 > 열기 > 프로젝트/솔루션> 메뉴를 클릭하여 DevADONET 웹 프로젝트를 불러옵니다.

(2) 솔루션 탐색기에서 DevADONET 웹 프로젝트에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 다음 FrmMemoList.aspx라는 이름으로 웹 프로젝트에 웹 폼을 추가합니다. 템플릿 이름 이름 웹 폼 FrmMemoList.aspx

(3) FrmMemoList.aspx 페이지를 열고 다음과 같이 입력합니다.

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="FrmMemoList.aspx.cs" Inherits="DevADONET.FrmMemoList" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>출력 패턴</title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <h3>메모 리스트</h3>
    <asp:GridView ID="ctlMemoList" runat="server" AutoGenerateColumns="false">
        <Columns>
            <asp:BoundField HeaderText="번호" DataField="Num" />
            <asp:BoundField HeaderText="작성자" DataField="Name" />
            <asp:HyperLinkField HeaderText="메모" 
                DataTextField="Title" 
                DataNavigateUrlFormatString="FrmMemoView.aspx?Num={0}"
                DataNavigateUrlFields="Num" />
            <asp:TemplateField HeaderText="작성일">
                <ItemTemplate>
                    <%# Eval("PostDate") %>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    <hr />
    <asp:HyperLink ID="lnkMemoWrite" runat="server"
        NavigateUrl="~/FrmMemoWrite.aspx">글쓰기</asp:HyperLink>
</div>
</form>
</body>
</html>

<설명> GridView 컨트롤에서 사용할 수 있는 HyperLinkField 컨트롤은 DataTextFiled 속성에 지정한 값이 링크의 텍스트로 표현되고 DataNavigateUrlFormatString 속성에 지정된 형태로 링크가 만들어지되 {0} 자리에는 DataNavigateUrlFields 속성이 자동으로 채워진다. 조금 복잡해 보일 수 있으나 몇 번 연습해보면 GridView 내에서 하이퍼링크를 만드는데 어려움이 없을 것입니다. </설명>

웹 폼에 등록된 컨트롤의 주요 속성은 다음과 같습니다. 컨트롤 속성 값 GridView ID ctlMemoList HyperLink ID lnkMemoWrite NavigateUrl ~/FrmMemoWrite.aspx Text 글쓰기

(4) FrmMemoList.aspx.cs 파일을 열고 다음과 같이 코드를 작성합니다.

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace DevADONET
{
    public partial class FrmMemoList : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("ListMemo", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [3] 데이터어댑터
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            // [4] 데이터셋
            DataSet ds = new DataSet();
            da.Fill(ds, "Memos");
            // [5] 출력
            ctlMemoList.DataSource = ds;
            ctlMemoList.DataBind(); 
            // [6] 마무리
            con.Close();
        }
    }
}

(5) FrmMemoList.aspx에 마우스 오른쪽 버튼을 클릭하여 <시작 페이지로 설정> 메뉴를 선택하고 [Ctrl]+[F5]를 눌러 실행하면 웹 브라우저에 다음과 같이 출력됩니다. Figure 13 1 리스트 페이지 실행 결과

13.5.3 마무리 ListMemo 저장 프로시저를 사용하여 출력 패턴에 사용되는 코드를 작성해보았습니다.

<참고> Eval() 메서드의 값 가공하기 Eval() 메서드로 출력된 내용을 가지고 새롭게 쿼리를 읽어서 사용하고자할 때에는 아래와 같은 형태로 소스 코드에서 코드 비하인드로 값을 넘긴 후 코드 비하인드에서 그 값을 사용하여 새롭게 쿼리를 조회하여 결과값을 사용할 수 있습니다. Id에 해당하는 Title 등을 읽어올 때 이와 같은 방법을 사용할 수 있습니다. *.aspx 영역

<asp:GridView ID="ctlPostList" runat="server">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <%# FuncGet(Eval("PostId")) %>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

*.aspx.cs 영역

protected string FuncGet(object postId)
{
    // 넘겨온 postId에 해당하는 쿼리 진행
    return postId.ToString(); 
}

13.6 웹 응용 프로그램 제작의 세 번째 패턴 익히기: 상세 13.6.1 상세(View/Content/Details/Check) 패턴 웹 응용 프로그램을 제작하다 보면 여러 가지 패턴이 나오는데 그 중에서 단일 데이터를 조회하는 상세 패턴이 있습니다. 프로그래밍 API 작성시 View, Content, Details, Check와 같은 접두사 또는 접미사를 주로 사용합니다.

13.6.2 상세 패턴의 사용 예  게시판 내용 보기  회원 정보 보기  상품 상세 보기

13.7 [실습] Memos 테이블에서 단일 데이터 출력하기 13.7.1 소개 단일 레코드를 읽어서 각각의 컨트롤에 출력하는 기능을 살펴보겠습니다.

13.7.2 따라하기 (1) Visual Studio를 실행한 후 <파일 > 열기 > 프로젝트/솔루션> 메뉴를 클릭하여 DevADONET 웹 사이트를 불러옵니다.

(2) 솔루션 탐색기에서 DevADONET 웹 프로젝트에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 다음 FrmMemoView.aspx라는 이름으로 웹 프로젝트에 웹 폼을 추가합니다. 템플릿 이름 이름 웹 폼 FrmMemoView.aspx

(3) FrmMemoView.aspx 페이지를 열고 다음과 같이 입력합니다.

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="FrmMemoView.aspx.cs" Inherits="DevADONET.FrmMemoView" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>상세 보기 패턴</title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <h3>상세 보기</h3>
    번호:
    <asp:Label ID="lblNum" runat="server"></asp:Label><br />
    이름:
    <asp:Label ID="lblName" runat="server"></asp:Label><br />
    이메일:
    <asp:Label ID="lblEmail" runat="server"></asp:Label><br />
    메모:
    <asp:Label ID="lblTitle" runat="server"></asp:Label><br />
    작성일:
    <asp:Label ID="lblPostDate" runat="server"></asp:Label><br />
    IP 주소:
    <asp:Label ID="lblPostIP" runat="server"></asp:Label><br />
    <hr />
    <asp:HyperLink ID="lnkMemoModify" runat="server">수정</asp:HyperLink>
    <asp:HyperLink ID="lnkMemoDelete" runat="server">삭제</asp:HyperLink>
    <asp:HyperLink ID="lnkMemoList" runat="server" 
        NavigateUrl="~/FrmMemoList.aspx">리스트</asp:HyperLink>
</div>
</form>
</body>
</html>

웹 폼에 등록된 컨트롤의 주요 속성은 다음과 같습니다. 컨트롤 속성 값 Label ID lblNum Text (빈 문자열) ID lblName Text (빈 문자열) ID lblEmail Text (빈 문자열) ID lblTitle Text (빈 문자열) ID lblPostDate Text (빈 문자열) ID lblPostIP Text (빈 문자열)

(4) FrmMemoView.aspx.cs 파일을 열고 다음과 같이 코드를 작성합니다.

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace DevADONET
{
    public partial class FrmMemoView : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 넘어온 쿼리스트링 값이 없다면
            if (String.IsNullOrEmpty(Request["Num"]))
            {
                Response.Write("잘못된 요청입니다.");
                Response.End();
            }
            else
            {
                DisplayData();
                lnkMemoModify.NavigateUrl = 
                    $"FrmMemoModify.aspx?Num={Request["Num"]}";
                lnkMemoDelete.NavigateUrl = 
                    $"FrmMemoDelete.aspx?Num={Request["Num"]}";
            }
        }

        private void DisplayData()
        {
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("ViewMemo", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [!] 파라미터 추가
            cmd.Parameters.Add("Num", SqlDbType.Int); // 정수형
            cmd.Parameters["Num"].Value = Convert.ToInt32(Request["Num"]);
            // [3] 데이터리더
            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.Read())
            {
                // [!] 각각의 컨트롤에 바인딩
                this.lblNum.Text = Request["Num"];
                this.lblName.Text = dr["Name"].ToString();
                this.lblEmail.Text = dr[2].ToString();
                this.lblTitle.Text = dr.GetString(3);
                this.lblPostDate.Text = dr.GetDateTime(4).ToString();
                this.lblPostIP.Text = dr.GetString(5);
            }
            else
            {
                Response.Write("없는 데이터입니다.");
                Response.End();
            }
            // [4] 마무리
            dr.Close();
            con.Close(); 
        }
    }
}

(5) FrmMemoView.aspx에 마우스 오른쪽 버튼을 클릭하여 <시작 페이지로 설정> 메뉴를 선택하고 [Ctrl]+[F5]를 눌러 실행하면 웹 브라우저에 다음과 같이 출력됩니다.

그림 13 2 FrmMemoView.aspx 페이지 기본 실행 결과

(6) 정확한 내용이 출력되려면 쿼리스트링 값으로 ‘?Num=3’ 같은 방식으로 값을 전달해야 합니다. 나의 환경에서는 현재 Num 필드의 값이 1, 2, 3, 세 개의 레코드가 들어있기에 그 중 하나를 요청하기 위해서 웹 브라우저 주소란에 /FrmMemoView.aspx?Num=3 형식으로 요청을 다시합니다. 그러면 다음과 같이 정상적으로 출력됩니다. 이때 상세 보기 페이지는 FrmMemoView.aspx?Num=3와 같이 번호값이 띄어쓰기 없이 반드시 쿼리스트링으로 넘어 와야 제대로 출력됩니다. 이러한 쿼리스트링 전송은 리스트 페이지에서 링크를 통해 전달됩니다.

그림 13 3 상세 보기 패턴 웹브라우저 실행 결과

13.7.3 마무리 상세보기 페이지는 일반적으로 리스트(인덱스) 페이지에서 하이퍼링크(제목)를 클릭했을 때 자동으로 쿼리스트링을 상세 페이지로 전송하고 그 값을 출력하는 방식으로 표현됩니다.

13.8 웹 응용 프로그램 제작의 네 번째 패턴 익히기: 수정 13.8.1 수정(Modify/Edit/Update) 패턴 웹 응용 프로그램을 제작하다 보면 여러 가지 패턴이 나오는데 그 중에서 데이터를 수정하는 수정 패턴이 있습니다. 프로그래밍 API 작성시 Modify, Edit, Update와 같은 접두사 또는 접미사를 주로 사용합니다.

13.8.2 수정 패턴의 사용 예  게시판 글 수정  회원 정보 수정  상품 수정

13.8.3 Update 구문 처리 관련 코드 조각 다음 코드는 메서드로 구현한 내용의 일부로 Update 관련 저장 프로시저를 호출하는 코드입니다.

/// <summary>
/// 프로필 정보 업데이트
/// </summary>
/// <param name="model">UserViewModel 개체</param>
/// <returns>업데이트 되었으면 1 그렇지 않으면 0</returns>
public int UpdateUserProcess(UserViewModel model)
{
    SqlConnection objCon = new SqlConnection(
        ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
    objCon.Open();

    SqlCommand objCmd = new SqlCommand("UpdateUser", objCon);
    objCmd.CommandType = CommandType.StoredProcedure;

    objCmd.Parameters.AddWithValue("@Email", model.Email);
    objCmd.Parameters.AddWithValue("@Description", model.Description);
    objCmd.Parameters.AddWithValue("@DomainID", model.DomainID);
    objCmd.Parameters.AddWithValue("@PhoneNumber", model.PhoneNumber);

    int result = Convert.ToInt32(objCmd.ExecuteScalar());
    objCon.Close();
    return result;
}

13.9 [실습] Memos 테이블의 데이터 수정하기 13.9.1 소개 데이터를 수정하는 기본 코드를 살펴봅니다. 이 실습에서는 쿼리스트링에서 넘겨받은 번호가 데이터에 해당합니다. 데이터 수정 패턴은 상세보기 패턴과 입력 패턴의 합쳐진 형태입니다.

13.9.2 따라하기 (1) Visual Studio를 실행한 후 <파일 > 열기 > 프로젝트/솔루션> 메뉴를 클릭하여 DevADONET 웹 사이트를 불러옵니다.

(2) 솔루션 탐색기에서 DevADONET 웹 프로젝트에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 후 다음 FrmMemoModify.aspx라는 이름으로 웹 프로젝트에 웹 폼을 추가합니다. 템플릿 이름 이름 웹 폼 FrmMemoModify.aspx

(3) FrmMemoModify.aspx 페이지에 다음과 같이 입력합니다.

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="FrmMemoModify.aspx.cs" Inherits="DevADONET.FrmMemoModify" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>수정 패턴</title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <h3>데이터 수정</h3>
    번호:
    <asp:Label ID="lblNum" runat="server"></asp:Label><br />
    이름:
    <asp:TextBox ID="txtName" runat="server"></asp:TextBox><br />
    이메일:
    <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox><br />
    메모:
    <asp:TextBox ID="txtTitle" runat="server"></asp:TextBox><br />
    <asp:Button ID="btnModify" runat="server" Text="수정"
        OnClick="btnModify_Click" />
    <asp:Button ID="btnList" runat="server" Text="리스트"
        OnClick="btnList_Click" />
</div>
</form>
</body>
</html>

웹 폼에 등록된 컨트롤의 주요 속성은 다음과 같습니다. 컨트롤 속성 값 Label ID lblNum Text (빈 문자열) TextBox ID txtName txtEmail txtTitle Button ID btnModify Text 수정

(4) FrmMemoModify.aspx.cs 파일을 열고 다음과 같이 코드를 작성합니다.

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using DevADONET.Models;

namespace DevADONET
{
    public partial class FrmMemoModify : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 넘어온 쿼리스트링 값이 없다면
            if (String.IsNullOrEmpty(Request["Num"]))
            {
                Response.Write("잘못된 요청입니다.");
                Response.End();
            }
            else  
            {
                // 처음 로드 시만 읽어오고, 수정 버튼 클릭 시에는 해당 기능만 구현
                if (!Page.IsPostBack)
                {
                    DisplayData();
                }
            }
        }

        private void DisplayData()
        {
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("ViewMemo", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [!] 파라미터 추가
            cmd.Parameters.Add("Num", SqlDbType.Int); // 정수형
            cmd.Parameters["Num"].Value = Convert.ToInt32(Request["Num"]);
            // [3] 데이터리더
            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.Read())
            {
                // [!] 각각의 컨트롤에 바인딩
                this.lblNum.Text = Request["Num"];
                this.txtName.Text = dr["Name"].ToString();
                this.txtEmail.Text = dr[2].ToString();
                this.txtTitle.Text = dr.GetString(3);
            }
            else
            {
                Response.Write("없는 데이터입니다.");
                Response.End();
            }
            // [4] 마무리
            dr.Close();
            con.Close();
        }

        protected void btnModify_Click(object sender, EventArgs e)
        {
            // [0] 변수 선언부
            Memo memo = new Memo();
            memo.Num = Convert.ToInt32(Request["Num"]);
            memo.Name = txtName.Text;
            memo.Email = txtEmail.Text;
            memo.Title = txtTitle.Text;
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("ModifyMemo", con);
            //cmd.Connection = con;
            //cmd.CommandText = "WriteMemo";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [!] 파라미터 추가
            cmd.Parameters.AddWithValue("@Name", memo.Name);
            cmd.Parameters.AddWithValue("@Email", memo.Email);
            cmd.Parameters.AddWithValue("@Title", memo.Title);
            cmd.Parameters.AddWithValue("@Num", memo.Num);
            // [!] 실행
            cmd.ExecuteNonQuery();
            // [3] 마무리
            con.Close();
            Response.Redirect("FrmMemoView.aspx?Num=" + Request["Num"]); 
        }

        protected void btnList_Click(object sender, EventArgs e)
        {
            // 리스트 페이지로 이동
            Response.RedirectPermanent("FrmMemoList.aspx");
        }
    }
}

(5) FrmMemoList.aspx에 마우스 오른쪽 버튼을 클릭하여 <시작 페이지로 설정> 메뉴를 선택하고 [Ctrl]+[F5]를 눌러 실행합니다. 리스트에서 메모 링크를 클릭하여 상세보기로 이동한 후 수정 버튼을 클릭하면 웹 브라우저에 다음과 같이 출력됩니다. 경우에 따라서는 웹 브라우저 주소란에 직접 쿼리스트링을 입력하는 방식으로 요청할 수도 있습니다. 이 폼에서 기존 데이터를 읽어와 제대로 출력되는지 확인한 뒤 값을 변경합니다. 수정 버튼을 클릭하면 데이터가 수정되고, 다시 상세 보기 페이지로 이동해서 수정된 내용을 확인할 수 있습니다. 데이터 수정 페이지도 반드시 웹 브라우저 주소에 FrmMemoModify.aspx?Num=3 형태로 쿼리스트링으로 수정하고자하는 글의 번호 값을 제공해야 합니다. 그림 13 4 수정 패턴 웹브라우저 실행 결과

13.9.3 마무리 데이터는 수정 패턴을 작성할 때 반드시 넘어 온 Num 값을 기준으로 각각의 컨트롤에 미리 출력합니다. 이때 페이지가 처음 로드할 때만 출력해야 한다는 점에 주의하라.

13.10 웹 응용 프로그램 제작의 다섯 번째 패턴 익히기: 삭제 13.10.1 삭제(Delete/Remove) 패턴 웹 응용 프로그램을 제작하다 보면 여러 가지 패턴이 나오는데 그 중에서 데이터를 삭제하는 삭제 패턴이 있습니다. 프로그래밍 API 작성시 Delete, Remove와 같은 접두사 또는 접미사를 주로 사용합니다.

13.10.2 삭제 패턴의 사용 예  게시판 글 삭제  회원 탈퇴  상품 제거

13.11 [실습] Memos 테이블에서 데이터 삭제하기 13.11.1 소개 쿼리스트링에서 넘겨받은 번호에 해당하는 데이터를 삭제하는 가장 기본이 되는 코드를 살펴봅니다.

13.11.2 따라하기 (1) Visual Studio를 실행한 후 <파일 > 열기 > 프로젝트/솔루션> 메뉴를 클릭하여 DevADONET 웹 프로젝트를 불러옵니다.

(2) 솔루션 탐색기에서 DevADONET 웹 프로젝트에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 다음 FrmMemoDelete.aspx란 이름으로 웹 프로젝트에 웹 폼을 추가합니다. 템플릿 이름 이름 웹 폼 FrmMemoDelete.aspx

(3) FrmMemoDelete.aspx 페이지에 다음과 같이 입력합니다.

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="FrmMemoDelete.aspx.cs" Inherits="DevADONET.FrmMemoDelete" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>삭제 패턴</title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <h3>글 삭제</h3>
    <asp:Label ID="lblNum" runat="server"></asp:Label>번 글을 삭제하시겠습니까?
    <asp:Button ID="btnDelete" runat="server" Text="삭제"
        OnClientClick="return confirm('정말로 삭제하시겠습니까?');"
        OnClick="btnDelete_Click" />
    <asp:HyperLink ID="lnkList" runat="server" 
        NavigateUrl="~/FrmMemoList.aspx">리스트</asp:HyperLink>
</div>
</form>
</body>
</html>

웹 폼에 등록된 컨트롤의 주요 속성은 다음과 같습니다. 컨트롤 속성 값 Label ID lblNum Text (빈 문자열) Button ID btnDelete Text 삭제

<참고> 버튼 컨트롤의 OnClientClick 이벤트 처리기 코드에는 OnClick가 실행되기 전에 클라이언트 측에서 먼저 처리해야할 자바스크립트 코드가 위치합니다. 위 예제에서처럼 삭제 확인 기능을 할 때 많이 사용합니다. </참고>

(4) FrmMemoDelete.aspx.cs 파일을 열고 다음과 같이 코드를 작성합니다.

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI;

namespace DevADONET
{
    public partial class FrmMemoDelete : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 넘어온 쿼리스트링 값이 없다면
            if (String.IsNullOrEmpty(Request["Num"]))
            {
                Response.Write("잘못된 요청입니다.");
                Response.End();
            }
            else
            {
                // 처음 로드 시만 읽어오고, 수정 버튼 클릭 시에는 해당 기능만 구현
                if (!Page.IsPostBack)
                {
                    lblNum.Text = Request["Num"];
                }
            }
        }

        protected void btnDelete_Click(object sender, EventArgs e)
        {
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("DeleteMemo", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [!] 파라미터 추가
            cmd.Parameters.Add("Num", SqlDbType.Int);
            cmd.Parameters["Num"].Value = Convert.ToInt32(Request["Num"]);
            // [!] 실행
            cmd.ExecuteNonQuery();
            // [3] 마무리
            con.Close();
            Response.Redirect("FrmMemoList.aspx");
        }
    }
}

(5) FrmMemoList.aspx에 마우스 오른쪽 버튼을 클릭하여 <시작 페이지로 설정> 메뉴를 선택하고 [Ctrl]+[F5]를 눌러 실행합니다. 리스트에서 메모 링크를 클릭하여 상세보기로 이동한 후 <삭제> 버튼을 클릭하면 웹 브라우저에 다음과 같이 출력됩니다. 경우에 따라서는 웹 브라우저 주소란에 직접 쿼리스트링을 입력하는 방식으로 요청할 수도 있습니다. 일반적으로 <삭제> 버튼을 누를 때 “정말로 삭제 하시겠습니까”와 같은 <확인> 대화 상자를 출력한 후 <확인>을 누르면 삭제를 진행하고 <취소>를 누르면 삭제가 진행되지 않는 자바스크립트 코드를 넣습니다. 그림 13 5 삭제 패턴 웹브라우저 실행 결과

13.11.3 마무리 데이터 삭제는 신중하게 다뤄야 합니다. 자바스크립트를 사용하여 한 번 더 확인을 하고, 추후 인증된 사용자 또는 자신의 글만 삭제할 수 있는 방식으로 제한을 거는 기능으로 확장할 수 있어야 합니다.

13.12 웹 응용 프로그램 제작의 여섯 번째 패턴 익히기: 검색 13.12.1 검색(Search/Find) 패턴 웹 응용 프로그램을 제작하다 보면 여러 가지 패턴이 나오는데 그 중에서 데이터를 검색하는 검색 패턴이 있습니다. 프로그래밍 API 작성시 Search, Find와 같은 접두사 또는 접미사를 주로 사용합니다. 검색 패턴은 출력 패턴과 동일하나 매개변수를 전달해서 해당 조건에 맞는 데이터만을 조회해 오는 기능을 구현할 때 사용되는 코드 패턴으로 나누어 보았습니다.

13.12.2 검색 패턴의 사용 예  게시판 글 검색  상품 검색  데이터 검색  페이징(Paging) 및 정렬(Sorting)

13.12.3 검색 패턴 사용 코드 샘플 다음 샘플 코드는 검색어를 받아서 이를 검색 관련 저장 프로시저에 전달해서 그 결괏값을 SqlDataReader로 받는 내용의 일부 코드입니다. 코드 중 CommandBehavior.CloseConnection 옵션은 실행 후 데이터리터 값을 반환받고서 바로 커넥션을 종료시켜 줍니다.

public SqlDataReader GetProductsBySearchString(string searchString)
{
    // 커넥션
    SqlConnection objCon =
        new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

    // 커멘드
    SqlCommand objCmd = new SqlCommand("ProductSearch", objCon);
    objCmd.CommandType = CommandType.StoredProcedure;

    // 파라미터
    SqlParameter parameterSearch = new SqlParameter("@Search", SqlDbType.NVarChar, 255);
    parameterSearch.Value = searchString;
    objCmd.Parameters.Add(parameterSearch);

    // 명령 실행
    objCon.Open();
    SqlDataReader result = objCmd.ExecuteReader(CommandBehavior.CloseConnection);

    // 데이터리더 개체 반환
    return result;
}

13.13 [실습] Memos 테이블에서 데이터 검색하기 13.13.1 소개 데이터를 검색하는 가장 기본이 되는 코드를 살펴봅니다.

13.13.2 따라하기 (1) Visual Studio를 실행한 후 <파일 > 열기 > 프로젝트/솔루션> 메뉴를 클릭하여 DevADONET 웹 프로젝트를 불러옵니다.

(2) 솔루션 탐색기에서 DevADONET 웹 프로젝트에 마우스 오른쪽 버튼을 클릭하여 <추가 > 새 항목> 메뉴를 클릭한 다음 FrmMemoSearch.aspx라는 이름으로 웹 프로젝트에 웹 폼을 추가합니다. 템플릿 이름 이름 웹 폼 FrmMemoSearch.aspx

(3) FrmMemoSearch.aspx 페이지에 다음과 같이 입력합니다.

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="FrmMemoSearch.aspx.cs" Inherits="DevADONET.FrmMemoSearch" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>검색 패턴</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h3>데이터 검색</h3>
        <asp:DropDownList ID="lstSearchField" runat="server">
            <asp:ListItem Value="Name" Selected="True">이름</asp:ListItem>
            <asp:ListItem Value="Title" >메모</asp:ListItem>
        </asp:DropDownList>
        <asp:TextBox ID="txtSearchQuery" runat="server"></asp:TextBox>
        <asp:Button ID="btnSearch" runat="server" Text="검색"
            OnClick="btnSearch_Click" />
        <hr />
        <asp:GridView ID="ctlMemoSearchList" runat="server"></asp:GridView>
    </div>
    </form>
</body>
</html>

웹 폼에 등록된 컨트롤의 주요 속성은 다음과 같습니다. 컨트롤 속성 값 DropDownList ID lstSearchField Items 이름(Name) 메모(Title) TextBox ID txtSearchQuery Button ID btnSearch Text 검색 GridView ID ctlMemoSearchList

(4) FrmMemoSearch.aspx.cs 파일을 열고 다음과 같이 코드를 작성합니다.

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace DevADONET
{
    public partial class FrmMemoSearch : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnSearch_Click(object sender, EventArgs e)
        {
            // [1] 커넥션
            SqlConnection con = new SqlConnection(ConfigurationManager
                .ConnectionStrings["ConnectionString"].ConnectionString);
            con.Open();
            // [2] 커멘드
            SqlCommand cmd = new SqlCommand("SearchMemo", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            // [!] 파라미터 추가
            cmd.Parameters.AddWithValue("SearchField", 
                lstSearchField.SelectedValue);
            cmd.Parameters.AddWithValue("SearchQuery", 
                txtSearchQuery.Text.Replace("--", ""));
            // [3] 데이터어댑터
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            // [4] 데이터셋
            DataSet ds = new DataSet();
            da.Fill(ds, "Memos");
            // [5] 출력
            ctlMemoSearchList.DataSource = ds.Tables[0].DefaultView;
            ctlMemoSearchList.DataBind();
            // [6] 마무리
            con.Close();
        }
    }
}

(5) FrmMemoSearch.aspx에 마우스 오른쪽 버튼을 클릭하여 <시작 페이지로 설정> 메뉴를 선택하고 [Ctrl]+[F5]를 눌러 실행하면 웹 브라우저에 다음과 같이 출력됩니다.

그림 13 6 검색 패턴 웹브라우저 실행 결과

13.13.3 마무리 이로써 웹 응용 프로그램 제작의 핵심 로직인 입력, 출력, 상세, 수정, 삭제, 검색, 여섯 가지 패턴을 코드로 살펴보았습니다. 이 코드들은 앞으로 제작할 모든 데이터베이스 프로그래밍의 기본이 되는 코드이므로 유형을 이해하고 암기까지 하면 더욱 좋을 것입니다.

13.14 퀴즈

  1. 데이터베이스 프로그래밍은 일반적으로 CRUD로 구성됩니다. 이때 CRUD의 약자로 잘못된 것을 고르세요

a. Create b. Run c. Update d. Delete

정답: b

CRUD는 Create, Read/Retreve, Update, Delete의 약자입니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com