본문 바로가기
대한상공회의소 스마트팩토리 교육/데이터베이스

[데이터베이스 운영] DBMS 기초 «수업-7» : 데이터베이스(DB) 연동 프로그래밍 기초 Using C# - ③ : GUI 환경 응용 (List View / Sub Form)

by 나는영하 2022. 4. 29.

※ 주의사항 

본 블로그는 수업 내용을 바탕으로 제가 이해한 부분을 정리한 블로그입니다.
본 내용을 참고로만 보시고, 틀린 부분이 있다면 지적 부탁드립니다!

감사합니다😁


DB 조회(List View 사용)

DB 수정(Sub Form 사용)

 


안녕하세요!!

저번에 GUI 환경으로 데이터베이스를 연동하는 기본 프로그램을 제작해보았습니다.

오늘은 지난 코드를 바탕으로 사용자 편의성을 한층 더 발전시켜볼려고 합니다.

List View 도구를 사용해서 DB에 있는 데이터를 더 정렬된 형태로 표시하고,

SubForm을 사용해서 DB에 있는 데이터를 더 편하게 수정해보겠습니다.

 

## Main Form 코드 ##

Form1.cs
0.01MB

 

 

## Sub Form 코드 ##

Update_Form.cs
0.01MB

 

 

1. 데이터베이스 조회 응용 (List View 사용)

(좌) RichTextBox 사용 / (우) ListView 사용

지난 글에서 데이터베이스를 조회하기 위해 RichTextBox를 사용하였었습니다.

가장 큰 단점은 문자열을 정렬하기 어렵고 번거롭다는 점입니다.

(사실 어제 이것때문에 엄청 고민을 하다 잠들었는데 ㅠ 이런 간편한 방법이 있을줄이야...)

 

그래서 이러한 단점을 개선하고 조금 더 편하게 데이터베이스를 조회(SELECT)하기 위해 List View를 사용해보겠습니다.

1-1. ListView 배치

우측 도구 상자에서 ListView를 드래그 & 드롭해서 적당한 크기로 배치해 주겠습니다.

저는 ListView에 데이터가 항시 조회될 수 있도록 별도의 조회 버튼은 만들지 않고 MainForm을 열거나 입력, 수정, 삭제가 처리 되었을때 데이터를 조회(SELECT)될 수 있도록 하겠습니다. 

 


1-2. SELECT 쿼리문 입력 및 전송 

별도로 조회 버튼을 사용하지않고 ListView에 DB를 조회하기 때문에 별도의 사용자 정의함수를 만들어 사용하겠습니다. 저는 view라는 함수를 만들어서 그안에 SELECT 문을 전송하고 DB 데이터를 전달받아 ListView에 출력을 하는 코드를 작성해보겠습니다. 

void view()
        {
            // 3단계. 쿼리문을 트럭에 실어서 교량을 건너 목적지에 붓기 --> SELECT SQL
            // 3-1. SQL문 준비하기
            sql = "SELECT emp_no, birth_date, first_name, last_name, gender, hire_date FROM employees";
            // 3-2. SQL문을 트럭에(C0MMAND) 싣기
            cmd.CommandText = sql;
            // 3-3. 트럭이 교량을 건너서 부어 넣고 끈만 가져오기
            MySqlDataReader reader;
            reader = cmd.ExecuteReader();
    	}

SELECT 쿼리문을 입력하고 전송하는 부분입니다. 기존과 동일하니 별도의 설명은 생략하겠습니다.

 


1-3. ListView의 속성 변경 및 열이름 추가, 사용 변수 선언

            listView1.Clear();             // 조회 될 때마다 기존 데이터 초기화    
            listView1.GridLines = true;    // 간격마다 눈금선 표시
            listView1.View = View.Details; // ListView를 엑셀모양으로 표시
                                           
            listView1.Columns.Add("직원번호"); //맨위에 DB의 열 제목 표시
            listView1.Columns.Add("생년월일");
            listView1.Columns.Add("성");
            listView1.Columns.Add("이름");
            listView1.Columns.Add("성별");
            listView1.Columns.Add("고용일");

            ListViewItem Item;                  // ListView 한 행의 값을 넣을 Item 생성
            // DB 데이터 저장 변수 선언 
            String emp_no, birth_date, first_name, last_name, gender, hire_date;
            int ab = 0; // DB 데이터 1,000개만 조회하기 위한 변수

listView1.Clear를 하지 않으면 기존 데이터 밑으로 데이터가 추가로 생성됩니다. 따라서 지난 데이터는 삭제(Clear)하고 새로운 데이터를 조회하기 위해 Clear를 진행해주었습니다.

 

View.Details은 ListView에 항목을 표시할 수 있는 5개의 보기중에 한가지 입니다. 그외 LargeI0con, SmallIcon, List, Tile이 있는데 다양한 열을 자세하게 보기 위해서는 'Details' 설정이 제일 좋습니다. 흔히 우리들이 보는 엑셀모양의 표모양으로 항목이 표시 됩니다. 

 

listView1.Columns.Add를 통해 열 제목을 추가해주었으며,

그아래 행 마다 데이터 값을 표시하기 위한 변수들을 선언해주었습니다. 

 

마지막으로는 DB의 데이터가 너무 많으면 조회하는데 오랜시간이 소요되기 때문에 1,000개만 보기 위한 카운터용 변수를 선언해두었습니다. 

 


1-4. ListView에 데이터베이스(DB)의 데이터 표시

 while (reader.Read()) // DB에 데이터가 안읽힐떄까지 반복
            {
                if (ab>1000) break;
                emp_no = reader["emp_no"].ToString();
                birth_date = reader["birth_date"].ToString();
                DateTime dt1 = Convert.ToDateTime(birth_date); // string 타입 날짜데이터 --> date 타입변환
                birth_date = dt1.ToString("yyyy-MM-dd");// date 타입을 string 타입으로 변환
                first_name = reader["first_name"].ToString();
                last_name = reader["last_name"].ToString();
                gender = reader["gender"].ToString();
                hire_date = reader["hire_date"].ToString();
                DateTime dt2 = Convert.ToDateTime(hire_date);
                hire_date = dt2.ToString("yyyy-MM-dd");

                Item = new ListViewItem(emp_no);
                Item.SubItems.Add(birth_date);
                Item.SubItems.Add(first_name);
                Item.SubItems.Add(last_name);
                Item.SubItems.Add(gender);
                Item.SubItems.Add(hire_date);

                listView1.Items.Add(Item);
                ab++;
            }
            reader.Close();

reader["열이름"].ToString()을 통해 받은 각 행의 데이터 값은 미리 선언해둔 변수에 저장을 해두었습니다. 

그리고 이 변수를 Item.SubItems.Add(변수명)을 통해 ListView에 표시를 하였습니다.  

 

이렇게 만든 view() 함수는 btn_Insert_Click / btn_Delete_Click / btn_Update_Click 이벤트가 처리될때 마지막에 호출하여서 해당 작업들이 끝나고 ViewList가 리셋되도록 하겠습니다! 

 

ListView의 사용법 자체는 크게 어렵지 않습니다. 다만 이것을 어디에 어떻게 적재적소에 사용하느냐에 따라 보여지는 퀄리티가 천차만별일 것이라 생각합니다. 


2. 데이터베이스 수정 (SubForm 사용)

2-1. Update_Form 생성 및 MainForm UPDATE 버튼 이벤트 함수부

Update Form

먼저 Update_Form을 새로 만들고 MainForm에서 수정을 눌렀을때 SubForm (Update)으로 이동할 수 있도록 코드를 작성하겠습니다. 여기서 유의해야할 점은 메인폼에서 입력하는 5가지의 데이터를 모두 매개변수 형태로 모두 서브폼안으로 가져가야합니다. 5개의 데이터가 어떤식으로 매개변수로 들어가고 사용되는지가 중요한 포인트가 될 것 같습니다. 

private void btn_update_Click(object sender, EventArgs e)
        {
            String emp_no, birth_date, first_name, last_name, gender, hire_date;
            emp_no = tb_emp_no.Text;
            birth_date = tb_birth_date.Text;
            first_name = tb_first_name.Text;
            last_name = tb_last_name.Text;
            gender = tb_gender.Text;
            hire_date = DateTime.Today.ToString("yyyy-MM-dd");

            Update_Form ufrm = new Update_Form(emp_no, birth_date, first_name, last_name, gender, hire_date);
            ufrm.ShowDialog();
            if (ufrm.DialogResult == DialogResult.OK) MessageBox.Show(emp_no +"번의 데이터가 정상적으로 수정되었습니다.");     

            view();
        }

2-2. Update_Form 전역변수부 및 초기설정

SubForm과 MainForm은 완전히 별개로 생각해야합니다. 따라서 MySqlConnector using문도 새로 추가해주어야 하며 데이터베이스 연결부터 연결해제까지 서브폼안에도 그대로 구현해주어야 합니다.

데이터베이스 연결을 위한 전역변수 선언과 초기 연결 과정(교량 건설 --> 트럭 준비 등)은 지난번에 설명을 하였으니 생략하고 코드만 구성하겠습니다. 

 

메인 폼에서 입력한 5개의 매개변수

메인폼에서 입력한 5개의 데이터들이 다음과 같이 서브폼의 매개변수가 되어서 서브폼안으로 들어왔습니다.

(나머지 한개는 hire_date로써 시스템 시간을 실시간으로 입력 받는 형태) 

매개변수를 저장할 변수들은 전역변수로 선언하여서 다른 이벤트 함수부에서 사용할 예정입니다! 


2-3. Update_Form 폼 Load 이벤트 함수부

폼 Load 이벤트 함수부는 폼이 실행될때 자동으로 수행될 함수입니다.

따라서 저는 서브폼이 켜지면 아래와 같은 동작을 하도록 코딩하였습니다. 

 

(1) 서브폼 TextBox 비활성화 --> 사용자가 편집 버튼을 누르기 전까진 MainForm에서 불러온 데이터들이 TextBox에 들어간 데이터를 변경시킬 수 없도록 하였습니다

(2) 데이터베이스 연결 및 쿼리문 전송 --> SubForm도 MainForm처럼 데이터베이스를 연결해주어야 합니다.(메인폼과 서브폼은 별개로 생각해야합니다!!) 따라서 메인폼에서 했던 과정들을 동일하게 반복하도록 합니다. 보낼 쿼리문은 서브폼 아래의 ListView에 데이터를 표시하기위해 SELECT문을 전송하도록 하겠습니다.  

(3) 서브폼의 TextBox에 메인폼에서 입력한 값 저장 --> 한번더 확인하는 용도로 메인폼에서 입력한 값들을 그대로 서브폼의 TextBox에 저장하였습니다. 만약 수정해야할 사항이 있다면 사용자가 편집 버튼을 눌러서 서브폼에서 바로 수정할 수 있도록 구성하였습니다.

(4) 서브폼의 ListView에 기존 DB의 데이터 표시 --> 기존 DB의 데이터값과 사용자가 수정하기 위해 입력한 데이터 값을 비교하기 위해 ListView에 SELECT를 통해 가져온 값들을 표시하겠습니다. 

 

각각의 구성은 아래의 코드에서 주석으로 구분지어두었으니 참고 바랍니다.

private void Update_Form_Load(object sender, EventArgs e)
        {
// ------------------------ (1) 서브 폼 텍스트 박스 비활성화 ------------------------
            // 수정용 Form이기 때문에 처음 TextBox는 비활성화 상태 
            tb_upd_birth_date.Enabled = false;
            tb_upd_emp_no.Enabled = false;
            tb_upd_first_name.Enabled = false;
            tb_upd_gender.Enabled = false;
            tb_upd_last_name.Enabled = false;

// ---------------------- (2) 데이터베이스 연결 및 쿼리문 전송 ----------------------
            // 1단계 : 데이터베이스 연결
            conn = new MySqlConnection(connStr);
            conn.Open();

            // 2단계 : 트럭준비
            cmd = new MySqlCommand("", conn);

            // 서브폼이 열리는 순간 메인폼에서 가져와서 사용자에게 보여주어야 한다.
            // <3> 트럭에 짐 탑재하고, 다리건너 부어넣기.
            sql = "SELECT emp_no, birth_date, first_name, last_name, gender, hire_date";
            sql +=" FROM employees Where emp_no = '" + emp_no + "'";
            // <3-2> 짐을 탑재하기.
            cmd.CommandText = sql;
            // <3-3> 트럭이 다리건너서 부어넣고, 끈만 가져오기
            MySqlDataReader reader;
            reader = cmd.ExecuteReader();
            
// ------------------------ (3) 서브폼의 텍스트박스 값 저장 ------------------------
            tb_upd_emp_no.Text = emp_no;
            tb_upd_birth_date.Text = birth_date;
            tb_upd_first_name.Text = first_name;
            tb_upd_last_name.Text = last_name;
            tb_upd_gender.Text = gender;

// ----------------- (4) 서브폼의 ListView에 기존 DB의 데이터 표시 -----------------
            listView1.View = View.Details;
            listView1.Columns.Add("직원번호");
            listView1.Columns.Add("생년월일");
            listView1.Columns.Add("성");
            listView1.Columns.Add("이름");
            listView1.Columns.Add("성별");
            listView1.Columns.Add("입사날짜");

            ListViewItem Item;

            String emp_no_view, birth_date_view, first_name_view, last_name_view,
               gender_view, hire_date_view;
            while (reader.Read()) // 톡! 땡기기
            {
                emp_no_view = reader["emp_no"].ToString();
                birth_date_view = reader["birth_date"].ToString();
                DateTime dt2 = Convert.ToDateTime(birth_date_view);
                birth_date_view = dt2.ToString("yyyy-MM-dd");
                first_name_view = reader["first_name"].ToString();
                last_name_view = reader["last_name"].ToString();
                gender_view = reader["gender"].ToString();
                hire_date_view = reader["hire_date"].ToString();
                DateTime dt1 = Convert.ToDateTime(hire_date_view);
                hire_date_view = dt1.ToString("yyyy-MM-dd");

                Item = new ListViewItem(emp_no_view);
                Item.SubItems.Add(birth_date_view);
                Item.SubItems.Add(first_name_view);
                Item.SubItems.Add(last_name_view);
                Item.SubItems.Add(gender_view);
                Item.SubItems.Add(hire_date_view);
                listView1.Items.Add(Item);
            }
            reader.Close();
        }

2-4. Update_Form 버튼 ok 클릭 이벤트 함수부

  private void btn_ok_Click(object sender, EventArgs e)
        {
            if (btn_edit.Created)
            {
                birth_date = tb_upd_birth_date.Text;
                first_name = tb_upd_first_name.Text;
                last_name = tb_upd_last_name.Text;
                gender = tb_upd_gender.Text;
            }

            sql = "UPDATE employees SET birth_date = '" + birth_date + "', first_name = '" + first_name + "', last_name = '" + last_name;
            sql += "', gender = '" + gender + "', hire_date = '" + hire_date + "' WHERE emp_no = '" + emp_no + "'";
          
            cmd.CommandText = sql;
            try { 
            cmd.ExecuteNonQuery();
            this.DialogResult = DialogResult.OK;
            }
            catch {
                MessageBox.Show("잘못입력하셨습니다.");

            }
        }

서브폼에 들어와서 쿼리문을 보내는 경우는 두가지가 있습니다.

 

(1) 사용자가 편집버튼을 누르지 않고 바로 확인을 누르는 경우 

--> 이경우는 메인폼에서 사용자가 입력한 값 그대로 쿼리문에 들어가서 데이터 수정이 이루어지게 됩니다.

 

(2) 사용자가 편집버튼을 눌러서 서브폼에서 값을 수정하는 경우 

--> 해당 경우는 if문을 통해 편집버튼이 눌러졌는지(btn_edit.Created)를 확인하고 눌러졌으면 서브폼의 TextBox의 Text를 변수에 저장해서 쿼리문에 보내게 됩니다.

댓글