MFC - Lớp cơ sở dữ liệu
A databaselà một tập hợp thông tin được sắp xếp để có thể dễ dàng truy cập, quản lý và cập nhật. Các lớp cơ sở dữ liệu MFC dựa trên ODBC được thiết kế để cung cấp quyền truy cập vào bất kỳ cơ sở dữ liệu nào có sẵn trình điều khiển ODBC. Vì các lớp sử dụng ODBC nên ứng dụng của bạn có thể truy cập dữ liệu ở nhiều định dạng dữ liệu khác nhau và các cấu hình cục bộ / từ xa khác nhau.
Bạn không phải viết mã trường hợp đặc biệt để xử lý các hệ thống quản lý cơ sở dữ liệu (DBMS) khác nhau. Miễn là người dùng của bạn có trình điều khiển ODBC thích hợp cho dữ liệu họ muốn truy cập, họ có thể sử dụng chương trình của bạn để thao tác dữ liệu trong các bảng được lưu trữ ở đó. Nguồn dữ liệu là một ví dụ cụ thể của dữ liệu được lưu trữ bởi một số hệ thống quản lý cơ sở dữ liệu (DBMS). Ví dụ bao gồm Microsoft SQL Server, Microsoft Access, v.v.
CDatabase
MFC cung cấp một lớp CDatabasebiểu thị kết nối với nguồn dữ liệu, qua đó bạn có thể thao tác trên nguồn dữ liệu. Bạn có thể có một hoặc nhiều đối tượng CDatabase hoạt động tại một thời điểm trong ứng dụng của mình.
Sr.No. | Tên & Mô tả |
---|---|
1 | BeginTrans Bắt đầu một "giao dịch" - một loạt các lệnh gọi có thể đảo ngược đến các chức năng thành viên AddNew, Edit, Delete và Update của lớp CRecordset- trên nguồn dữ liệu được kết nối. Nguồn dữ liệu phải hỗ trợ các giao dịch choBeginTrans có bất kỳ tác dụng nào. |
2 | BindParameters Cho phép bạn ràng buộc các tham số trước khi gọi ExecuteSQL. |
3 | Cancel Hủy một hoạt động không đồng bộ hoặc một quá trình từ một luồng thứ hai. |
4 | CanTransact Trả về nonzero nếu nguồn dữ liệu hỗ trợ các giao dịch. |
5 | CanUpdate Trả về số khác không nếu CDatabase đối tượng có thể cập nhật (không phải chỉ đọc). |
6 | Close Đóng kết nối nguồn dữ liệu. |
7 | CommitTrans Hoàn tất giao dịch bắt đầu bởi BeginTrans. Các lệnh trong giao dịch làm thay đổi nguồn dữ liệu được thực hiện. |
số 8 | ExecuteSQL Thực thi một câu lệnh SQL. Không có bản ghi dữ liệu nào được trả lại. |
9 | GetBookmarkPersistence Xác định các hoạt động mà qua đó dấu trang vẫn tồn tại trên các đối tượng tập bản ghi. |
10 | GetConnect Trả về chuỗi kết nối ODBC được sử dụng để kết nối đối tượng CDatabase với nguồn dữ liệu. |
11 | GetCursorCommitBehavior Xác định ảnh hưởng của việc thực hiện một giao dịch trên một đối tượng tập bản ghi mở. |
12 | GetCursorRollbackBehavior Xác định ảnh hưởng của việc khôi phục giao dịch trên một đối tượng tập bản ghi đang mở. |
13 | GetDatabaseName Trả về tên của cơ sở dữ liệu hiện đang được sử dụng. |
14 | IsOpen Trả về số khác không nếu CDatabase đối tượng hiện được kết nối với nguồn dữ liệu. |
15 | OnSetOptions Được gọi bởi khuôn khổ để thiết lập các tùy chọn kết nối tiêu chuẩn. Việc triển khai mặc định đặt giá trị thời gian chờ truy vấn. Bạn có thể thiết lập các tùy chọn này trước bằng cách gọiSetQueryTimeout. |
16 | Open Thiết lập kết nối với nguồn dữ liệu (thông qua trình điều khiển ODBC). |
17 | OpenEx Thiết lập kết nối với nguồn dữ liệu (thông qua trình điều khiển ODBC). |
18 | Rollback Đảo ngược các thay đổi được thực hiện trong giao dịch hiện tại. Nguồn dữ liệu trở về trạng thái trước đó, như được định nghĩa trong cuộc gọi BeginTrans, không thay đổi. |
19 | SetLoginTimeout Đặt số giây sau đó nỗ lực kết nối nguồn dữ liệu sẽ hết thời gian. |
20 | SetQueryTimeout Đặt số giây sau đó các hoạt động truy vấn cơ sở dữ liệu sẽ hết thời gian. Ảnh hưởng đến tất cả các cuộc gọi Open, AddNew, Edit và Delete của tập bản ghi tiếp theo. |
Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.
Step 1 - Thay đổi chú thích của dòng TODO thành Retrieve Data from Database và kéo một nút và một điều khiển Danh sách như được hiển thị trong ảnh chụp nhanh sau.
Step 2 - Thêm trình xử lý sự kiện nhấp chuột cho nút và biến điều khiển m_ListControl cho Kiểm soát danh sách.
Step 3 - Chúng tôi có cơ sở dữ liệu đơn giản chứa một bảng Nhân viên với một số bản ghi như được hiển thị trong ảnh chụp nhanh sau đây.
Step 4 - Chúng ta cần đưa vào tệp tiêu đề sau để có thể sử dụng lớp CDatabase.
#include "odbcinst.h"
#include "afxdb.h"
Chèn truy vấn
Câu lệnh SQL INSERT INTO được sử dụng để thêm các hàng dữ liệu mới vào bảng trong cơ sở dữ liệu.
Step 1 - Để thêm các bản ghi mới, chúng ta sẽ sử dụng hàm ExecuteSQL () của lớp CDatabase như trong đoạn mã sau.
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile = L"D:\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
SqlString = "INSERT INTO Employees (ID,Name,age) VALUES (5,'Sanjay',69)";
database.ExecuteSQL(SqlString);
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;
Step 2 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy rằng một bản ghi mới được thêm vào cơ sở dữ liệu của bạn.
Truy xuất bản ghi
Để truy xuất bảng trên trong ứng dụng MFC, chúng tôi thực hiện các hoạt động liên quan đến cơ sở dữ liệu trong trình xử lý sự kiện nút như được hiển thị trong các bước sau.
Step 1- Để sử dụng CDatabase, hãy xây dựng một đối tượng CDatabase và gọi hàm Open () của nó. Điều này sẽ mở kết nối.
Step 2 - Xây dựng các đối tượng CRecordset để hoạt động trên nguồn dữ liệu được kết nối, chuyển phương thức khởi tạo tập ghi một con trỏ tới đối tượng CDatabase của bạn.
Step 3 - Sau khi sử dụng kết nối, gọi hàm Close và hủy đối tượng CDatabase.
void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
// TODO: Add your control notification handler code here
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";
CString sFile = L"D:\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset( &database );
// Build the SQL statement
SqlString = "SELECT ID, Name, Age " "FROM Employees";
// Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
// Reset List control if there is any data
ResetListControl();
// populate Grids
ListView_SetExtendedListViewStyle(m_ListControl,LVS_EX_GRIDLINES);
// Column width and heading
m_ListControl.InsertColumn(0,"Emp ID",LVCFMT_LEFT,-1,0);
m_ListControl.InsertColumn(1,"Name",LVCFMT_LEFT,-1,1);
m_ListControl.InsertColumn(2, "Age", LVCFMT_LEFT, -1, 1);
m_ListControl.SetColumnWidth(0, 120);
m_ListControl.SetColumnWidth(1, 200);
m_ListControl.SetColumnWidth(2, 200);
// Loop through each record
while( !recset.IsEOF() ) {
// Copy each column into a variable
recset.GetFieldValue("ID",strID);
recset.GetFieldValue("Name",strName);
recset.GetFieldValue("Age", strAge);
// Insert values into the list control
iRec = m_ListControl.InsertItem(0,strID,0);
m_ListControl.SetItemText(0,1,strName);
m_ListControl.SetItemText(0, 2, strAge);
// goto next record
recset.MoveNext();
}
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox("Database error: "+e→m_strError);
}
END_CATCH;
}
// Reset List control
void CMFCDatabaseDemoDlg::ResetListControl() {
m_ListControl.DeleteAllItems();
int iNbrOfColumns;
CHeaderCtrl* pHeader = (CHeaderCtrl*)m_ListControl.GetDlgItem(0);
if (pHeader) {
iNbrOfColumns = pHeader→GetItemCount();
}
for (int i = iNbrOfColumns; i >= 0; i--) {
m_ListControl.DeleteColumn(i);
}
}
Step 4 - Đây là tệp tiêu đề.
// MFCDatabaseDemoDlg.h : header file
//
#pragma once
#include "afxcmn.h"
// CMFCDatabaseDemoDlg dialog
class CMFCDatabaseDemoDlg : public CDialogEx {
// Construction
public:
CMFCDatabaseDemoDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFCDATABASEDEMO_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
void ResetListControl();
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_ListControl;
afx_msg void OnBnClickedButtonRead();
};
Step 5 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.
Step 6- Nhấn nút Đọc để thực hiện các thao tác với cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên.
Cập nhật bản ghi
Truy vấn CẬP NHẬT SQL được sử dụng để sửa đổi các bản ghi hiện có trong bảng. Bạn có thể sử dụng mệnh đề WHERE với truy vấn UPDATE để cập nhật các hàng đã chọn nếu không tất cả các hàng sẽ bị ảnh hưởng.
Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản bằng cách cập nhật Độ tuổi mà ID bằng 5.
SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";
database.ExecuteSQL(SqlString);
Step 2 - Đây là mã hoàn chỉnh của sự kiện bấm nút.
void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
// TODO: Add your control notification handler code here
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile =
L"C:\\Users\\Muhammad.Waqas\\Downloads\\Compressed\\ReadDB_demo\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset(&database);
SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";
database.ExecuteSQL(SqlString);
SqlString = "SELECT ID, Name, Age FROM Employees";
// Build the SQL statement
SqlString = "SELECT ID, Name, Age FROM Employees";
// Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
// Reset List control if there is any data
ResetListControl();
// populate Grids
ListView_SetExtendedListViewStyle(m_listCtrl,LVS_EX_GRIDLINES);
// Column width and heading
m_listCtrl.InsertColumn(0,L"Emp ID",LVCFMT_LEFT,-1,0);
m_listCtrl.InsertColumn(1,L"Name",LVCFMT_LEFT,-1,1);
m_listCtrl.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
m_listCtrl.SetColumnWidth(0, 120);
m_listCtrl.SetColumnWidth(1, 200);
m_listCtrl.SetColumnWidth(2, 200);
// Loop through each record
while (!recset.IsEOF()) {
// Copy each column into a variable
recset.GetFieldValue(L"ID",strID);
recset.GetFieldValue(L"Name",strName);
recset.GetFieldValue(L"Age", strAge);
// Insert values into the list control
iRec = m_listCtrl.InsertItem(0,strID,0);
m_listCtrl.SetItemText(0,1,strName);
m_listCtrl.SetItemText(0, 2, strAge);
// goto next record
recset.MoveNext();
}
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;
}
Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.
Step 4- Nhấn nút Đọc để thực hiện các thao tác với cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên sau.
Step 5 - Bây giờ bạn có thể thấy rằng độ tuổi được cập nhật từ 69 thành 59.
Xóa hồ sơ
Truy vấn SQL DELETE được sử dụng để xóa các bản ghi hiện có khỏi bảng. Bạn có thể sử dụng mệnh đề WHERE với truy vấn DELETE để xóa các hàng đã chọn, nếu không tất cả các bản ghi sẽ bị xóa.
Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản bằng cách xóa bản ghi có ID bằng 3.
SqlString = L"DELETE FROM Employees WHERE ID = 3;";
database.ExecuteSQL(SqlString);
Step 2 - Đây là mã hoàn chỉnh của sự kiện bấm nút.
void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
// TODO: Add your control notification handler code here
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile =
L"C:\\Users\\Muhammad.Waqas\\Downloads\\Compressed\\ReadDB_demo\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset(&database);
SqlString = L"DELETE FROM Employees WHERE ID = 3;";
database.ExecuteSQL(SqlString);
SqlString = "SELECT ID, Name, Age FROM Employees";
// Build the SQL statement
SqlString = "SELECT ID, Name, Age FROM Employees";
// Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
// Reset List control if there is any data
ResetListControl();
// populate Grids
ListView_SetExtendedListViewStyle(m_listCtrl,LVS_EX_GRIDLINES);
// Column width and heading
m_listCtrl.InsertColumn(0,L"Emp ID",LVCFMT_LEFT,-1,0);
m_listCtrl.InsertColumn(1,L"Name",LVCFMT_LEFT,-1,1);
m_listCtrl.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
m_listCtrl.SetColumnWidth(0, 120);
m_listCtrl.SetColumnWidth(1, 200);
m_listCtrl.SetColumnWidth(2, 200);
// Loop through each record
while (!recset.IsEOF()) {
// Copy each column into a variable
recset.GetFieldValue(L"ID",strID);
recset.GetFieldValue(L"Name",strName);
recset.GetFieldValue(L"Age", strAge);
// Insert values into the list control
iRec = m_listCtrl.InsertItem(0,strID,0);
m_listCtrl.SetItemText(0,1,strName);
m_listCtrl.SetItemText(0, 2, strAge);
// goto next record
recset.MoveNext();
}
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;
}
Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.
Step 4- Nhấn nút Đọc để thực hiện các thao tác với cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên.