Giới thiệu
Tiếp nối bài viết mảng kiến thức lưu trữ dữ liệu trong Android. Bài trước chúng ta đã được tiếp xúc với Lưu trữ dữ liệu với Shared Preferences. Và trong bài viết này tôi sẽ giới thiệu cho các bạn cách lưu trữ dữ liệu sử dụng SQLite.
SQLite là một hệ quản trị cơ sở dữ liệu có quy mô nhỏ, đơn giản, không cần cài đặt, không cần cấu hình. Và được tích hợp sẵn trong Android từ API 1 và rất dễ sử dụng (chúng ta không cần cài driver cho SQLite và kết nối thông qua JDBC).
Trang chủ SQLite: https://www.sqlite.org/
Để tiếp thu bài viết một cách tốt nhất yêu cần bạn phải có kiến thức cơ bản về SQL (các câu lệnh tạo bảng, thêm xoá, sửa, và các câu query để lấy dữ liệu).
Source demo sử dụng trong bài viết các bạn có thể download tại đây.
Thao tác với SQLite trong Android
Trong bài viết này tôi sẽ hướng dẫn các bạn các thao tác cơ bản với SQLite trong Android gồm
- Create Database
- Create Table
- Select Data
- Insert Data
- Update Data
- Delete Data
Với ví dụ là Database có tên là DICTIONARY_DB có 1 table là WORD có các trường như dưới đây:
Column | Kiểu dữ liệu | Ghi chú |
id | INTEGER | Id của word, Khoá chính, trường tự tăng |
word | TEXT | từ |
mean | TEXT | Nghĩa của từ |
Trước tiên tôi tạo model có tên Word.java ứng với table Word như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
public class Word { private int mId; private String mWord; private String mMean; public Word() { } public Word(int id, String word, String mean) { this.mId = id; this.mWord = word; this.mMean = mean; } public Word(String word, String mean) { this.mWord = word; this.mMean = mean; } public void setMean(String mean) { this.mMean = mean; } public void setWord(String word) { this.mWord = word; } public int getId() { return mId; } public String getWord() { return mWord; } public String getMean() { return mMean; } } |
Để sử dụng SQLite trong Android các bạn phải tạo class kế thừa từ class SQLiteDatabaseHelper và implement hai phương thức onCreate và phương thức onUpgrade
1 |
public class DatabaseHelper extends SQLiteOpenHelper { |
Phương thức onCreate
1 2 3 4 5 |
@Override public void onCreate(SQLiteDatabase db) { //Thực thi các câu lệnh tạo bảng //Sử dụng db.execSQL(sql); chạy câu lênh sql tạo bảng } |
Phương thức onUpgrade
1 2 3 4 5 |
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //Gọi khi bạn thay đổi DATABASE_VERSION //Thường sử dụng để thay đổi cấu trúc bảng (ALTER, DROP, ADD CONSTRAIN...) } |
Constructor
1 2 3 4 |
private DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); Log.e(TAG, "DatabaseHelper: "); } |
Chúng ta thấy rằng phạm vi của contructor tôi để là private bởi vì Database của chúng ta có thể truy cập được bất cứ đâu trong ứng dụng (Activity, Fragment, Service…). Vì vậy tôi sử dụng Design Parttern Singleton để đảm bảo trong ứng dụng có duy nhất một đối tượng DatabaseHelper quản lý việc thao tác trên SQLite.
1 2 3 4 5 6 |
public static DatabaseHelper getInstance(Context context) { if (sInstance == null) { sInstance = new DatabaseHelper(context.getApplicationContext()); } return sInstance; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "DatabaseHelper"; private static final String DATABASE_NAME = "DICTIONARY_DB"; private static final int DATABASE_VERSION = 1; private static final String TABLE_WORD = "WORD"; private static final String ID_COLUMN = "id"; private static final String WORD_COLUMN = "word"; private static final String MEAN_COLUMN = "mean"; private static final String CREATE_WORD_TABLE_SQL = "CREATE TABLE " + TABLE_WORD + " (" + ID_COLUMN + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + WORD_COLUMN + " TEXT NOT NULL," + MEAN_COLUMN + " TEXT NOT NULL" + ")"; private static DatabaseHelper sInstance; public static DatabaseHelper getInstance(Context context) { if (sInstance == null) { sInstance = new DatabaseHelper(context.getApplicationContext()); } return sInstance; } private DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); Log.e(TAG, "DatabaseHelper: "); } @Override public void onCreate(SQLiteDatabase db) { Log.e(TAG, "onCreate: "); db.execSQL(CREATE_WORD_TABLE_SQL); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.e(TAG, "onUpgrade: "); db.execSQL("DROP TABLE IF EXISTS " + TABLE_WORD); onCreate(db); } } |
Insert Data
1 2 3 4 5 6 7 8 9 10 11 |
public boolean insertWord(Word word) { SQLiteDatabase db = getWritableDatabase(); ContentValues values = new ContentValues(); values.put(WORD_COLUMN, word.getWord()); values.put(MEAN_COLUMN, word.getMean()); long rowId = db.insert(TABLE_WORD, null, values); db.close(); if (rowId != -1) return true; return false; } |
Sử dụng đối tượng ContentValues để put các giá trị ứng với tên colum và sử dụng phương thức insert của SQLiteDatabase để tiến hành ghi xuống database. Phương thức trả về true nếu insert thành công, ngược lại thất bại.
Select Data
Đối với việc lấy data từ SQLite các bạn có hai phương thức là query() và rawQuery()
Hai phương thức này trả về đối tương cursor, từ đối tượng này các bạn có thể lấy ra data của từng row.
Lấy từ theo id:
1 2 3 4 5 6 7 8 9 10 11 12 |
public Word getWord(int id) { SQLiteDatabase db = getReadableDatabase(); Word word = null; Cursor cursor = db.query(TABLE_WORD, new String[]{ID_COLUMN, WORD_COLUMN, MEAN_COLUMN}, ID_COLUMN + " = ?", new String[]{String.valueOf(id)}, null, null, null); if (cursor != null && cursor.moveToFirst()) { word = new Word(cursor.getInt(0), cursor.getString(1), cursor.getString(2)); cursor.close(); } db.close(); return word; } |
Lấy tất cả các từ có trong databse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public List<Word> getAllWord() { SQLiteDatabase db = getReadableDatabase(); List<Word> words = new ArrayList<>(); String sql = "SELECT * FROM " + TABLE_WORD; Cursor cursor = db.rawQuery(sql, null); if (cursor != null && cursor.moveToFirst()) { do { words.add(new Word(cursor.getInt(0), cursor.getString(1), cursor.getString(2))); } while (cursor.moveToNext()); cursor.close(); } db.close(); return words; } |
Tổng số row có trong database:
1 2 3 4 5 6 7 8 |
public int getTotalWord() { SQLiteDatabase db = getReadableDatabase(); String sql = "SELECT * FROM " + TABLE_WORD; Cursor cursor = db.rawQuery(sql, null); int totalRows = cursor.getCount(); cursor.close(); return totalRows; } |
Update Data
Đối việc với update data hay delete chúng ta làm giống như với việc insert. SQLiteDatabaseHelper có cung cấp cho chúng ta các phương thức insert, update và delete.
1 2 3 4 5 6 7 8 9 |
public int updateWord(Word word) { SQLiteDatabase db = getWritableDatabase(); ContentValues values = new ContentValues(); values.put(WORD_COLUMN, word.getWord()); values.put(MEAN_COLUMN, word.getMean()); int rowEffect = db.update(TABLE_WORD, values, ID_COLUMN + " = ?", new String[]{String.valueOf(word.getId())}); db.close(); return rowEffect; } |
Phương thức trả về số dòng ảnh hưởng.
Delete Data
1 2 3 4 5 6 |
public int deleteWord(Word word) { SQLiteDatabase db = getReadableDatabase(); int rowEffect = db.delete(TABLE_WORD, ID_COLUMN + " = ?", new String[]{String.valueOf(word.getId())}); db.close(); return rowEffect; } |
Giống với Update thì phương thức này cũng return về số dòng ảnh hưởng.
Sử dụng
Tiếp theo tôi sẽ demo các phương thức đã viết ở trên trong file MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package com.example.nguyennghia.databasedemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import java.util.List; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //get Instance. DatabaseHelper db = DatabaseHelper.getInstance(this); //insert data db.insertWord(new Word("book", "Sách(n), đặt chổ(v)")); db.insertWord(new Word("table", "Bàn(n)")); db.insertWord(new Word("action movie", "Phim hành động")); //loge all word in database for(Word w: db.getAllWord()){ Log.e(TAG, "onCreate: " + w.getId() + ", " + w.getWord() + ", " + w.getMean()); } //upate word Word word = db.getAllWord().get(0); word.setMean("Sách(n), đặt chổ(v), đặt vé(v)"); db.updateWord(word); //loge all word in database for(Word w: db.getAllWord()){ Log.e(TAG, "onCreate: " + w.getId() + ", " + w.getWord() + ", " + w.getMean()); } //delete word db.deleteWord(db.getAllWord().get(0)); //loge total rows in database Log.e(TAG, "onCreate: " + db.getTotalWord()); } } |
Các bạn có thể tìm thấy database tại đường dẫn
1 |
database/data/[application package name]/databases/database_name |
Database DICTIONARY_DB tôi đã tạo
Kết luận
Ở ví dụ trên tôi chỉ tạo một Table để demo, tuy nhiên các bạn có thể tạo nhiều table khác nhau tuỳ thuộc vào project, ứng dụng của các bạn. Hy vọng bài viết giúp ích cho các bạn. Nếu có bất cứ thắc mắc có thể để lại bình luận bên dưới hoặc liên hệ qua fanpage Eitguide Android để được giải đáp.
bạn có thể giải thích từng dòng code dc ko bạn, bạn quăng nguyên cục code ra đó mình mới học chả hiểu gi hết @@
Mình có giải thích ở bên dưới các đoạn mã mà bạn. Tuy nhiên phải thực sự phải làm lại mới thực sự hiểu được nó. Nếu có thắc mắc nào bạn có thể liên hệ với mình qua facebook: https://www.facebook.com/nguyennghia.uit
bạn nên chụp cái ảnh để chạy ứng dụng nữa như thế sẽ dễ hiểu hơn
Cảm ơn bạn đã góp ý. Mình sẽ update lại bài viết trong thời gian tới.
Cai DB nó lưu ở đâu thế bác, t tìm k thấy
Máy bạn đã được root chưa?