Mô hình 3 lớp trong Lập trình CSDL
Đối với lập trình hiện đại, mọi thā đều đi nhiều lớp, tương tự như C#, cũng có cả mÙ
hÏnh 3 lớp C# để chúng ta thực thi áp dụng. à C# chúng ta gọi là mô hình 3 lớp 3
Layers.
I. Mô hình 3 lớp đơn giản
GUI Layer: Lớp này là lớp hiển thị giao diện và các chāc năng để ngưßi dùng cuối sử
dụng.
Business (BUS) Layer: Đây là lớp nhận các yêu cầu từ lớp GUI và truy xuất lên lớp Data
để lấy thông tin và trả về GUI.
Data Access Layer: Lớp này là lớp để truy xuất với CSDL, chỉ duy nhất lớp này được làm
việc với database.
(Ko cần thiết) DTO Layer: Lớp này chỉ là phụ, đây là lớp định nghĩa các table trong
database cÿa bạn, định nghĩa cột cÿa nó cũng như để ta gán data khi query lấy dữ liệu.
Các bạn có thể hiểu nôm na là 1 dạng cơ bản ORM (Object Relation Mapping).
Đây là cách hoạt động cÿa mô hình 3 lớp:
Nhìn sơ qua thì nó khá là giống MVC bên web. Business như là Controller, GUI l‡ View v‡
Data Access l‡ Model.
Lợi thế của mô hình 3 lớp:
Phân loại rõ ràng các lớp có các nhiệm vụ khác nhau. Từ đó ta có thể quản lý và bảo trì
project tốt hơn.
Dễ dàng phân loại các hành động tại Business.
Dễ dàng phân loại các hàm truy xuất tại Database, phân loại hàm theo table,...
Āng dụng được cho các project lớn á bên ngoài.
...
Lưu ý khi xây dựng mô hình 3 lớp:
Cần một solution riêng cho project.
Cần 4 project khác nhau để làm nên 3 lớp, tên Project đặt như sau:
GUI : GUI_* (VD: GUI_QuanLy): Project làm giao diện ngưßi dùng
Lớp Business : BUS_* (VD: BUS_QuanLy)
Lớp Data Access : DAO_* (VD: DAO_QuanLy)
Lớp DTO : DTO_* (VD: DTO_QuanLy)
Bên trong 3 lớp như trên các file đặt cần có các tiền tố như sau:
Ví dụ ta có một table tên là ThanhVien
Lớp GUI : GUI_* (VD: GUI _ThanhVien )
Lớp Business : BUS_* (VD: BUS _ThanhVien )
Lớp Data Access : DAO_* (VD: DAO _ThanhVien )
Lớp DTO : DTO_* (VD: DTO _ThanhVien )
Như các bạn đã thấy tên Table liên quan mật thiết tới cách đặt tên file để thống nhất và
dễ nhớ.
II. Liên kết 3 lớp
Như các bạn đã nhìn tại sơ đồ á trên thì Mô hình 3 lớp hoạt động như sau:
GUI liên kết tới Business Layer v‡ DTO.
Business Layer liên kết tới được Data Access v‡ DTO.
Data Access chỉ liên kết tới DTO.
Cả 3 Project DTO, Business và Data Access chúng ta tạo theo Class Library
Bước 1:
Tạo một Project mới, đặt tÍn Project l‡ GUI_Quanly, tÍn Solution l‡ QuanLyThanhVien.
Đổi tÍn Form1 th‡nh GUI_Thanhvien.
Bước 3: Xóa các File class1
Kết quả sau bước 3
Bước 4: Tạo tham chiếu giữa các Project:
- DAO tham chiếu đến DTO
- BUS tham chiếu đến DAO, DTO
- GUI tham chiếu đến BUS, DTO
DAO: Chuột phải v‡o References => Add Reference
Xuất hiện:
Chọn Project, sau đó chọn DTO_Quanly
Tương tự cho BUS và GUI
Một bảng hiện ra, tại mục Project ta sẽ chọn 2 lớp mà lớp GUI có thể liên kết tới
l‡ BUS v‡ DTO :
Bấm OK l‡ Reference sẽ được thÍm v‡o c·c lớp, ch ̇ng ta cÛ thể kiểm tra bằng c·ch
má References ra:
DTO_ThanhVien .cs
using
System ;
using
System .
Collections .
Generic ;
using
System .
Linq ;
using
System .
Text ;
namespace
DTO_QuanLy
{public class DTO_ThanhVien //Tạo lớp trung gian để thao t·c với bảng Thanhvien
{private int
_THANHVIEN_ID ;private string
_THANHVIEN_NAME ;private string
_THANHVIEN_PHONE ;private string
_THANHVIEN_EMAIL ;/* C·c h‡m get v‡ set đặt á đây */
public int
THANHVIEN_ID {get
{ return
_THANHVIEN_ID ; }set
{ _THANHVIEN_ID\= value; }
}public string
THANHVIEN_NAME {get
{ return
_THANHVIEN_NAME; e}
set
{ _THANHVIEN_NAME\= value; }
}public string
THANHVIEN_PHONE {get
{ return
_THANHVIEN_PHONE ;}set
{ _THANHVIEN_PHONE\= value;}
}public string
THANHVIEN_EMAIL {get
{ return
_THANHVIEN_EMAIL ; }set
{ _THANHVIEN_EMAIL = value; }
}/* === Constructor === */
public DTO_ThanhVien()
{ }public DTO_ThanhVien(int id, string name, string phone, string email)
{this.
THANHVIEN_ID \=id ;
this.
THANHVIEN_EMAIL \=email ;
this.
THANHVIEN_NAME \=name ;
this.
THANHVIEN_PHONE \=phone ;
} } }return
dtThanhvien ;
}/// ThÍm th‡nh viÍn
public bool themThanhVien(DTO_ThanhVien
tv )
{try
{// Ket noi
_conn .Open();
// Query string – ch ̇ ̋ TV_ID l‡ gi· trị tự tăng dần nÍn ko cần phải thÍm ID
string
SQL\= string("INSERT INTO THANHVIEN(TV_NAME,
TV_PHONE, TV_EMAIL) VALUES ('{0}', '{1}', '{2}')",tv .
THANHVIEN_NAME ,tv .
THANHVIEN_PHONE ,tv .
THANHVIEN_EMAIL );SqlCommand
cmd = new SqlCommand(
SQL ,_conn );
// Query v‡ kiểm tra
if (
cmd .ExecuteNonQuery() > 0 )
return true;
}catch (Exception
e )
{ }finally
{_conn .Close(); // Đóng kết nối
}return false;
}// Sửa th‡nh viÍn
public bool suaThanhVien(DTO_ThanhVien
tv )
{try
{// Ket noi
_conn .Open();
// Query string
string
SQL\= string("UPDATE THANHVIEN SET TV_NAME = '{0}',
TV_PHONE = '{1}', TV_EMAIL = '{2}' WHERE TV_ID = {3}",tv .
THANHVIEN_NAME ,tv .
THANHVIEN_PHONE ,tv .
THANHVIEN_EMAIL ,tv .
THANHVIEN_ID );SqlCommand
cmd = new SqlCommand(
SQL ,_conn );
// Query v‡ kiểm tra
if (
cmd .ExecuteNonQuery() > 0 )
return true;
}catch (Exception
e )
{ }finally
{// Dong ket noi
_conn .Close();
}return false;
}// XÛa th‡nh viÍn
public bool xoaThanhVien(int
TV_ID ) {try
{// Ket noi
_conn .Open();
// Query string - vÏ xÛa chỉ cần ID nÍn ch ̇ng ta ko cần 1 DTO-ID l‡ đÿ
string
SQL\= string("DELETE FROM THANHVIEN WHERE TV_ID =
{0})", TV_ID );SqlCommand
cmd = new SqlCommand(
SQL ,_conn );
// Query v‡ kiểm tra
if (cmd() > 0 )
return true;
}catch (Exception
e )
{public bool suaThanhVien(DTO_ThanhVien
tv )
{return
daoThanhVien .suaThanhVien(
tv );
}public bool xoaThanhVien(int
TV_ID ) {return
daoThanhVien .xoaThanhVien(
TV_ID ); } } }à đây chỉ đơn giản l‡ gọi h‡m v‡ trả về, coi như một lớp trung gian. (Ch ̇ng ta sẽ gặp
BUS phāc tạp hơn á phần sau)
Xây dựng GUI
GUI ta sẽ design như sau:
Control Name Text Describe Note
Form GUI_ThanhVien Text: Quản l ̋
th‡nh viÍn
Groupbox - Text: ThÙng tin
th‡nh viÍn
DataGridView dgvTV
TextBox txtName
TextBox txtPhone
TextBox txtEmail
Button btnAdd ThÍm
Button btnEdit Sửa
Button btnDelete XÛa
Button btnExit Tho·t
Ta sẽ g·n c·c chāc năng v‡o c·c đối tượng trÍn Form:
using
System ;
using
System .
Collections .
Generic ;
using
System .
ComponentModel ;
using
System .
Data ;
using
System .
Drawing ;
using
System .
Linq ;
using
System .
Text ;
using
System .
Windows .
Forms ;
using
DTO_QuanLy ;
using
BUS_QuanLy ;
namespace
GUI_QuanLy
{public partial class GUI_ThanhVien : Form
{BUS_ThanhVien
busTV = new BUS_ThanhVien();
public GUI_ThanhVien()
{InitializeComponent();
}private void btnExit_Click(object
sender , EventArgs
e )
{Application .Exit();
}private void btnAdd_Click(object
sender , EventArgs
e )
{ {MessageBox .Show("Sửa th‡nh cÙng");
dgvTV .
DataSource =
busTV .getThanhVien(); // refresh datagridview
}else
{MessageBox .Show("Sửa ko th‡nh cÙng");
} }else
{MessageBox .Show("Xin h„y nhập đầy đÿ");
} }else
{MessageBox .Show("H„y chọn th‡nh viÍn muốn sửa");
} }private void dgvTV_Click(object
sender , EventArgs
e )
{// Lấy row hiện tại
DataGridViewRow
row =
dgvTV .
SelectedRows [ 0 ];
// Chuyển gi· trị lÍn form
txtName .
Text =
row .
Cells [ 1 ].
Value .ToString();
txtPhone .
Text =
row .
Cells [ 2 ].
Value .ToString();
txtEmail .
Text =
row .
Cells [ 3 ].
Value .ToString();
}private void btnDelete_Click(object
sender , EventArgs
e )
{// Kiểm tra nếu cÛ chọn table rồi
if (
dgvTV .
SelectedRows .
Count > 0 )
{// Lấy row hiện tại
DataGridViewRow
row =
dgvTV .
SelectedRows [ 0 ];
int
ID \=Convert .ToInt16(
row .
Cells [ 0 ].
Value .ToString());
// XÛa
if (
busTV .xoaThanhVien(
ID )) {MessageBox .Show("XÛa th‡nh cÙng");
dgvTV .
DataSource =
busTV .getThanhVien(); // refresh datagridview
}else
{MessageBox .Show("XÛa ko th‡nh cÙng");
} }else
{MessageBox .Show("H„y chọn th‡nh viÍn muốn xÛa");
} } } }Chạy thử chương trình