Tải bản đầy đủ (.pdf) (28 trang)

Three layer in android

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.5 MB, 28 trang )

Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

MỤC LỤC
I. Giới thiệu về mô hình 3 lớp. ................................................................................................ 2
1.1. Understanding Three-Layer Model: ............................................................................. 2
1.2. Các thành phần trong 3 – Layer.................................................................................... 2
1.3. Cách vận hành của mô hình. ......................................................................................... 3
II. Xây dựng ứng dụng.............................................................................................................. 4
2.1. Xây dựng Cơ sở dữ liệu: ............................................................................................... 4
2.2. Tạo một mới một cơ sở dữ liệu.. .................................................................................. 6
2.3. Xây dựng ứng dụng, sử dụng theo mô hình 3 lớp. ....................................................... 8
2.4. Khai báo quyền cho ứng dụng. ................................................................................... 26
2.5. Giao diện ứng dụng. ................................................................................................... 27

1


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

MÔ HÌNH LẬP TRÌNH 3 LỚP - SQLITE TRÊN ANDROID.
 Mục đích của tài liệu:
- Tài liệu này sẽ hướng dẫn các bạn cách lập trình thao tác cơ sở dữ liệu Sqlite trong lập trình
Android theo Mô hình 3 lớp, giống như lập trình 3 lớp thao tác với cơ sở dữ liệu Sql Server
trong CSharp.

I. Giới thiệu về mô hình 3 lớp.
1.1. Understanding Three-Layer Model:


Để dễ quản lý các thành phần của hệ thống, cũng như không bị ảnh hưởng bởi các thay đổi,
người ta hay nhóm các thành phần có cùng chức năng lại với nhau và phân chia trách nhiệm
cho từng nhóm để công việc không bị chồng chéo và ảnh hưởng lẫn nhau. Một trong những mô
hình lập trình như vậy đó là Mô hình 3 lớp (Three Layers).
1.2. Các thành phần trong 3 – Layer.
Mô hình 3 lớp được cấu thành từ: Presentation Layers, Business Logic Layers, và Data
Access Layers.

1. Presentation Layers. (Lớp 3)
- Lớp này làm nhiệm vụ giao tiếp với người dùng cuối để thu thập dữ liệu và hiển thị kết
quả/dữ liệu thông qua các thành phần trong giao diện người sử dụng. Trong .NET thì bạn có
thể dùng Windows Forms, ASP.NET hay Mobile Forms để hiện thực lớp này.
 Lưu ý: Lớp này không nên sử dụng trực tiếp các dịch vụ của lớp Data Access mà nên sử
dụng thông qua các service của lớp Business Logic vì khi bạn sử dụng trực tiếp như vậy,
bạn có thể bỏ qua các ràng buộc, các logic nghiệp vụ mà ứng dụng cần phải có.
2. Business Logic Layer. (Lớp 2)
2


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

- Đây là layer xử lý chính các dữ liệu trước khi được đưa lên hiển thị trên màn hình hoặc xử
lý các dữ liệu trước khi chuyển xuống Data Access Layer để lưu dữ liệu xuống cơ sở dữ liệu.
Đây là nơi đê kiểm tra ràng buộc, các yêu cầu nghiệp vụ, tính toán, xử lý các yêu cầu và lựa
chọn kết quả trả về cho Presentation Layers.
3. Data Access Layer. (Lớp 1)
- Lớp này thực hiện các nghiệp vụ liên quan đến lưu trữ và truy xuất dữ liệu của ứng dụng
như đọc, lưu, cập nhật cơ sở dữ liệu.

1.3. Cách vận hành của mô hình.
Đối với 3-Layer, yêu cầu được xử lý tuần tự qua các layer như hình.

- Đầu tiên User giao tiếp với Presentation Layers (GUI) (mục số 3) để gửi đi thông tin và
yêu cầu. Tại layer này, các thông tin sẽ được kiểm tra, nếu OK chúng sẽ được chuyển
xuống Business Logic Layer (BLL) (mục số 2).
- Tại BLL, các thông tin sẽ được nhào nặn, tính toán theo đúng yêu cầu đã gửi, nếu không
cần đến Database thì BLL sẽ gửi trả kết quả về GUI, ngược lại nó sẽ đẩy dữ liệu (thông
tin đã xử lý) xuống Data Access Layer (DAL) (mục số 1).
- DAL sẽ thao tác với Database và trả kết quả về cho BLL, BLL kiểm tra và gửi nó lên
GUI để hiển thị cho người dùng.
- Một khi gặp lỗi (các trường hợp không đúng dữ liệu) thì đang ở layer nào thì quăng lên
trên layer cao hơn nó 1 bậc cho tới GUI thì sẽ quăng ra cho người dùng biết
- Các dữ liệu được trung chuyển giữa các Layer thông qua một đối tượng gọi là Data
Transfer Object (DTO), đơn giản đây chỉ là các Class đại diện cho các đối tượng được
lưu trữ trong Database. (mục số 4).

3


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

II. Xây dựng ứng dụng.
2.1. Xây dựng Cơ sở dữ liệu:
Các bạn tạo cơ sở dữ liệu bằng một ứng dụng hỗ trợ. Lưu lại với định dạng .sqlite. Các bạn
có thể kết hợp các ứng dụng với nhau vì mỗi ứng dụng lại có một ưu nhược điểm khác nhau. Ở
trong bài này, mình sử dụng 2 ứng dụng.
1. SQLite Administrator.


2. SQLite manager. (Một tiện ích có sẵn trong Firefox)

Sau khi cài đặt:

4


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

Kéo thả tiện ích vào thanh công cụ như trong hình:

Khi chạy tiện ích sẽ được như trong hình:

5


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

2.2. Tạo một cơ sở dữ liệu mới, đặt tên là MyDatabase để thực hành ví dụ.

-

Bạn tạo một bảng dữ liệu mới đặt tên là SinhVien. Chọn phải chuột vào Tables => Create
Table. Đặt tên bảng là SinhVien. Chọn Add Field để thêm các trường.
6



Trương Khoan_KMT_TNUT

-

Sau khi thêm 3 trường, ta chọn Create:

-

Ta được như sau:

THÁI NGUYÊN UNIVERSITY

7


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

- Việc thêm, sửa, xóa, lấy dữ liệu ta sẽ thực hiện trong ứng dụng.
2.3. Xây dựng ứng dụng, sử dụng theo mô hình 3 lớp.
- Tạo ứng dụng android application, cấu trúc như sau:
(Bạn copy file MyDatabase.sqlite vừa tạo vào trong thư mục Access của Project)

Trong đó:
1. Packet com.kmt.Example: thuộc lớp thứ 3 là lớp Giao diện. Dùng để tương tác dữ liệu với
người dùng (hiển thị dữ liệu, nhận dữ liệu để thêm, sửa và xóa).
2. Packet dataaccesslayer: Thuộc lớp 1 trong mô hình 3 lớp. Gồm 2 Class.

8


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

- AssetDatabaseOpenHelper: Có nhiệm vụ Copy file Database từ thư mục Access vào
thư mục Database của ứng dụng. Vì ứng dụng chỉ tương tác với cơ sở dữ liệu trong thư
mục databases có cấu trúc đường dẫn:
///data/data/{package của bạn}/databases
VD: String path = "/data/data/com.kmt.databaseaccess/databases";

(Chú ý: Bạn chỉ có thể truy cập vào File Explorer khi chạy máy ảo)
Nếu bạn chỉ copy file CSDL vào thư mục Access của Projetc thì ứng dụng vẫn không
gọi được nó. Khi bạn dùng lớp này thì khi chạy ứng dụng, nó sẽ kiểm tra đã tồn tại CSDL
trong thư mục database hay chưa, nếu chưa thì nó sẽ copy file CSDL từ thư mục Access
của Project vào cho chúng ta một cách tự động.
9


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

Hoặc bạn có thể tự copy thủ công bằng cách sau: Chọn thư mục database trong Packet
của ứng dụng trong thư mục File Exploder => Chọn Push a file onto the device.

Chọn đến file CSDL mà bạn muốn import vào, chọn Open.


CODE:
package databaseaccess;
/**
* Created by locnt_000 on 9/29/2015.
10


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class AssetDatabaseOpenHelper {
// tên file datebase trong thư mục assets
private static final String DB_NAME = "MyDatabase.sqlite";
private Context context;

public AssetDatabaseOpenHelper(Context context) {
this.context = context;
}


public void StoreDatabase() {
///data/data/{package của bạn}/databases
String path = "/data/data/com.kmt.databaseaccess/databases";
File pathDb = new File(path);
try {
// kiểm tra nếu có thư mục databases thì sẽ tạo
if (!pathDb.exists()){
pathDb.mkdir();
11


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

}
// kiểm tra file đó chưa tồn tại thì copy vào
// điều kiện này tránh trường hợp mỗi lần mở ứng dụng sẽ copy vào.
if (!new File(path + "/" + DB_NAME).exists()) {
copy(path);
}
} catch (IOException e) {
Log.d("IOException", e.getMessage());
}
Log.i("DB",context.getDatabasePath(DB_NAME).getPath());
}

/*
* Thực hiện đọc file và ghi file

*/
private void copy(String path) throws IOException {

// mở file trong thư mục assets
InputStream is = context.getAssets().open(DB_NAME);
FileOutputStream fos = new FileOutputStream(path + "/" + DB_NAME);
byte buffer[] = new byte[1024];
int length;

//đọc và ghi vào thư mục databases
while ((length = is.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
is.close();
12


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

fos.flush();
fos.close();
}
}
//-------------------------------------------------------------------------------------------------------------

DBAdapter: Lớp đầu tiên của mô hình. Thực hiện nhiệm vụ kết nối tới cơ sở dữ liệu. Đóng,
mở kết nối. Thực hiện các truy vấn, tác động tới cơ sở dữ liệu.
package databaseaccess;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;

public class DBAdapter {

private static final String TAG = "DBAdapter";
private static final String DB_NAME = "MyDatabase.sqlite";
private static final String DATABASE_NAME = "MyDatabase";
13


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

private static String DATABASE_TABLE = "";
private static String DATABASE_CREATE = "";
private static final int DATABASE_VERSION = 1;

private Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
private ContentValues contenValues;
private AssetDatabaseOpenHelper asset;

public DBAdapter(Context ctx, String DATABASE_TABLE, String
DATABASE_CREATE)
{
try {
asset = new AssetDatabaseOpenHelper(ctx);
asset.StoreDatabase();
// Kiểm tra, nếu chưa copy database từ thư
mục asset vào thư mục database của ứng dụng thì copy.
this.context = ctx;
DBHelper = new DatabaseHelper(ctx);
this.DATABASE_TABLE = DATABASE_TABLE;
this.DATABASE_CREATE = DATABASE_CREATE;

} catch (Exception e) {
Toast.makeText( ctx, "Lỗi khi tạo DBAdapter. Error: "+ e,
Toast.LENGTH_SHORT).show();
}

}
//------------------------------------------------------------------------------/**
14


Trương Khoan_KMT_TNUT


THÁI NGUYÊN UNIVERSITY

* Sử dụng để cập nhật, nâng cấp cơ sở dữ liệu.
* @author Jimmy
*
*/
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE); // Tạo bảng cụ thể.
} catch (SQLException e) {
e.printStackTrace();
}
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion
+ ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS '"+ DATABASE_TABLE +"'"); // xóa bảng

dữ liệu cũ.

15


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

onCreate(db);
lại bảng dữ liệu.

// Tạo

}
}
//------------------------------------------------------------------------------/**
* Tạo mới một cơ sở dữ liệu.
* @param DATABASE_CREATE
*/
public void CreateDatabase(String DATABASE_CREATE)
{
try {
db.execSQL(DATABASE_CREATE);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, "Error CreateDatabase: "+ e,
Toast.LENGTH_SHORT).show();
}
}

//------------------------------------------------------------------------------/**
* Xóa một cơ sở dữ liệu.
* @param DATABASE_NAME
*/
public void DeleteDatabase()
{
try {
open();

16


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

db.execSQL("DROP TABLE IF EXISTS '"+ DATABASE_NAME +"'"); // xóa
bảng dữ liệu cũ.
} catch (Exception e) {
Toast.makeText(context, "Error DeleteDatabase: "+ e,
Toast.LENGTH_SHORT).show();
}
finally
{
close();
}
}
//------------------------------------------------------------------------------/**
* Insert dữ liệu vào trong một bảng bất kỳ.
* @param DATABASE_TABLE : Tên bảng cần Insert dữ liệu.

* @param fields : Mảnh chứa tên các trường cần thê dữ liệu.
* @param values : Mảng chứa giá trị cần thêm vào các trường theo thứ tự tương ứng.
*/
public void InsertIntoTable(String[] fields, String[] values)
{
try {
open();
contenValues = new ContentValues();
int i = 0;
long result;
for (String field : fields) {
contenValues.put(field, values[i]);
i++;
}
17


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

result = db.insert(DATABASE_TABLE, null, contenValues);
if (result == -1) {

// lỗi

Toast.makeText(context, "Can't Insert. \n Error: ",
Toast.LENGTH_SHORT).show();
}
else {


// Ok.
Toast.makeText(context, "Inserted!", Toast.LENGTH_SHORT).show();
}

} catch (Exception e) {
Toast.makeText(context, "Error InsertIntoTable: "+ e,
Toast.LENGTH_SHORT).show();
}
finally
{
close();
}
}
//------------------------------------------------------------------------------/**
* Update dữ liệu vào 1 bảng.
* @param DATABASE_TABLE : Tên bảng.
* @param fields : Danh sách các trường cần cập nhật dữ liệu.
* @param values : Danh sách các giá trị mới.
* @param whereClause : Mệnh đề điều kiện. Form: tentruong1 = ? and tentruong2 = ? or
tentruong3 = ? ....
* @param whereArgs : Danh sách các tham số truyền vào mệnh đề điều kiện.
*/
public void UpdateTable(String[] fields, String[] values, String whereClause, String[]
whereArgs)
{
18


Trương Khoan_KMT_TNUT


THÁI NGUYÊN UNIVERSITY

try {
open();
contenValues = new ContentValues();
int i = 0;
long result;
for (String field : fields) {
contenValues.put(field, values[i]);
i++;
}
result = db.update(DATABASE_TABLE, contenValues, whereClause, whereArgs);
if (result == 0) {

// lỗi. Không có bản ghi nào được tác động.

Toast.makeText(context, "Can't Update.",
Toast.LENGTH_SHORT).show();
}
else {

// Ok.
Toast.makeText(context, "Updated!", Toast.LENGTH_SHORT).show();
}

} catch (Exception e) {
Toast.makeText(context, "Error UpdateTable: "+ e,
Toast.LENGTH_SHORT).show();
}

finally
{
close();
}
}
//------------------------------------------------------------------------------/**
* Xóa các bản ghi.
19


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

* @param DATABASE_TABLE : Tên bảng cần xóa dữ liệu.
* @param whereClause : Điều kiện.
* @param whereArgs : Giá trị tham số của điều kiện.
* Nếu xóa hết cả bảng: 2 tham số cuối để: NULL.
*/

public void DeleteTable(String whereClause, String[] whereArgs)
{
try {
open();
int result;
result = (int) db.delete(DATABASE_TABLE, whereClause, whereArgs);
if (result != 0) {

// Ok.


Toast.makeText(context, "Inserted!", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(context, "Error DeleteTable: "+ e,
Toast.LENGTH_SHORT).show();
}
finally
{
close();
}
}

//------------------------------------------------------------------------------/**
* Truy vấn lấy về dữ liệu trong bảng.
* @param DATABASE_TABLE : Bảng cần lấy dữ liệu.
20


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

* @param columns : Các trường cần lấy.
* @param selection : Mệnh đề điều kiện.
* @param selectionArgs : Danh sách giá trị các tham số.
* @return
*/
public Cursor SqlQuery(String[] columns, String selection, String[] selectionArgs)
{
try {

open();
Cursor c = db.query(DATABASE_TABLE, columns, selection,
selectionArgs, null, null, null);
// 3 giá trị null cuối mặc định là: GroupBy, Having, OrderBy.
return c;
} catch (Exception e) {
Toast.makeText(context, "Error SqlQuery: "+ e,
Toast.LENGTH_SHORT).show();
return null;
}
finally
{
close();
}
}
//------------------------------------------------------------------------------/**
* Truy vấn lấy giá trị dựa vào câu truy vấn bất kỳ.
* @param sql : Câu truy vấn.
* @param selectionArgs : Danh sách các giá trị của tham số trong mệnh đề điều kiện
(nếu có).
21


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

* @return
*/
public Cursor SqlRawQuery(String sql, String[] selectionArgs)

{
try {
open();
Cursor c = db.rawQuery(sql, selectionArgs);
return c;
} catch (Exception e) {
Toast.makeText(context, "Error SqlRawQuery: "+ e,
Toast.LENGTH_SHORT).show();
return null;
}
finally
{
close();
}
}
//------------------------------------------------------------------------------/**
* --- opens the database--* @return
* @throws SQLException
*/
public DBAdapter open() throws SQLException
{
try {

22


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY


db =
SQLiteDatabase.openDatabase(context.getDatabasePath(DB_NAME).getPath(), null,
SQLiteDatabase.OPEN_READWRITE);
} catch (Exception e) {
Toast.makeText(context, "Error When Open Db: "+ e,
Toast.LENGTH_SHORT).show();
}
return this;
}
//------------------------------------------------------------------------------/**
* ---closes the database--*/
public void close()
{
try {
DBHelper.close();
} catch (Exception e) {
Toast.makeText(context, "Error: "+ e, Toast.LENGTH_SHORT).show();
}
}
public static String getDatabaseCreate() {
return DATABASE_CREATE;
}
public static void SetDatabaseCreate(String DATABASE_CREATE) {
DBAdapter.DATABASE_CREATE = DATABASE_CREATE;
}
}

23



Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

3. Packet object. Sử dụng để lưu trữ các giá trị của các đối tượng thuộc lớp SinhViên - Data
Transfer Object (DTO)
package object;

public class SinhVien {
// Các biến sử dụng cho lớp đối tượng Sinh Viên.
private String Name = "", ClassName = "";
private int ID = 0;

// Thiết lập và lấy các giá trị của một đối tượng thuộc lớp Sinh Viên.
public int getID() {
return ID;
}

public void setID(int iD) {
ID = iD;
}

public String getName() {
return Name;
}

public void setName(String name) {
Name = name;
}


public String getClassName() {
return ClassName;
24


Trương Khoan_KMT_TNUT

THÁI NGUYÊN UNIVERSITY

}

public void setClass(String ClassName) {
ClassName = ClassName;
}
}
4. Packet businesslogiclayer: Chứa các Class thuộc lớp thứ 2 trong mô hình 3 lớp.
package businesslogiclayer;
import com.kmt.Example.MainActivity;
import
import
import
import
import
import

android.content.ContentValues;
android.content.Context;
android.database.Cursor;
android.database.SQLException;
android.database.sqlite.SQLiteDatabase;

android.widget.Toast;

import dataaccesslayer.DBAdapter;
public class DtSinhVien {
private DBAdapter dbAdapter;
//private DatabaseHelper DBHelper;
private final Context context;
private SQLiteDatabase db;
private static final int DATABASE_VERSION = 1;
static final String DATABASE_CREATE =
"CREATE TABLE [SinhVien] ( [ID] INTEGER DEFAULT '0' NOT NULL
PRIMARY KEY AUTOINCREMENT, [Name] TEXT NULL, [Class] TEXT NULL)";
// Các biến sử
liệu.
private static
private static
private static
private static
private static

dụng cho một bảng cụ thể. Dùng để truy xuất, tác động dữ
final
final
final
final
final

String DATABASE_TABLE = "SinhVien";
String KEY_ROWID = "id";
String KEY_NAME = "Name";

String KEY_CLASS = "Class";
String[] COLUMNS = {KEY_ROWID,KEY_NAME,KEY_CLASS };

public DtSinhVien(Context context)
{
this.context = context;
try {
dbAdapter = new DBAdapter(context, DATABASE_TABLE,
DATABASE_CREATE);
} catch (Exception e) {
Toast.makeText(context, "Lỗi khi tạo đối tượng DBAdapter.
"+ e, Toast.LENGTH_SHORT).show();
}

25


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×