Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách sử dụng SQLite Database trong ứng dụng Android

Giới thiệu

Bài viết này hướng dẫn toàn diện cách sử dụng SQLite - cơ sở dữ liệu nhúng sẵn có trên Android - để lưu trữ, truy xuất, cập nhật và xóa dữ liệu. Ví dụ minh họa quản lý danh sách cầu thủ bóng đá.

Kiến trúc ứng dụng

  • DatabaseHelper: Kế thừa SQLiteOpenHelper, quản lý tạo/cập nhật bảng
  • DataBaseManager: Lớp wrapper thao tác CRUD (Insert, Query, Update, Delete)
  • MainActivity: Hiển thị danh sách qua ListView + SimpleCursorAdapter
  • AddPlayerActivity / ModifyPlayerActivity: Màn hình thêm/sửa/xóa bản ghi

Các bước thực hiện

Bước 1: Tạo dự án mới

Android Studio → File → New Project → Chọn Empty Activity.

Bước 2: Layout chính (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="1dp"
        android:padding="10dp" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="" />
</RelativeLayout>

Bước 3: Lớp DatabaseHelper (DataBaseHelper.java)

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

class DatabaseHelper extends SQLiteOpenHelper {
    static final String TABLE_NAME = "FOOTBALLPLAYERS";
    static final String _ID = "_id";
    static final String SUBJECT = "subject";
    static final String DESCRIPTION = "description";

    private static final String DB_NAME = "PLAYER_COUNTRIES.DB";
    private static final int DB_VERSION = 1;

    private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "("
            + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + SUBJECT + " TEXT NOT NULL, "
            + DESCRIPTION + " TEXT);";

    DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}

Bước 4: Lớp DataBaseManager (DataBaseManager.java)

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

public class DataBaseManager {
    private DatabaseHelper databaseHelper;
    private Context context;
    private SQLiteDatabase database;

    DataBaseManager(Context c) {
        context = c;
    }

    DataBaseManager open() throws SQLException {
        databaseHelper = new DatabaseHelper(context);
        database = databaseHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        databaseHelper.close();
    }

    void insert(String name, String desc) {
        ContentValues contentValue = new ContentValues();
        contentValue.put(DatabaseHelper.SUBJECT, name);
        contentValue.put(DatabaseHelper.DESCRIPTION, desc);
        database.insert(DatabaseHelper.TABLE_NAME, null, contentValue);
    }

    Cursor fetch() {
        String[] columns = new String[]{DatabaseHelper._ID, DatabaseHelper.SUBJECT, DatabaseHelper.DESCRIPTION};
        Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, null, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
        }
        return cursor;
    }

    public int update(long _id, String name, String desc) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(DatabaseHelper.SUBJECT, name);
        contentValues.put(DatabaseHelper.DESCRIPTION, desc);
        return database.update(DatabaseHelper.TABLE_NAME, contentValues, DatabaseHelper._ID + " = " + _id, null);
    }

    public void delete(long _id) {
        database.delete(DatabaseHelper.TABLE_NAME, DatabaseHelper._ID + "=" + _id, null);
    }
}

Bước 5: Layout item dòng (res/layout/list_row.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp">

    <TextView
        android:id="@+id/id"
        android:layout_width="25dp"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginEnd="6dp"
        android:padding="3dp"
        android:visibility="visible" />

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_toEndOf="@id/id"
        android:maxLines="1"
        android:padding="3dp"
        android:textSize="17sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/desc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_marginStart="10dp"
        android:layout_toEndOf="@id/id"
        android:ellipsize="end"
        android:maxLines="2"
        android:padding="3dp"
        android:visibility="visible" />
</RelativeLayout>

Bước 6: MainActivity.java

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    DataBaseManager dataBaseManager;
    ListView listView;
    SimpleCursorAdapter adapter;
    final String[] from = new String[]{DatabaseHelper._ID, DatabaseHelper.SUBJECT, DatabaseHelper.DESCRIPTION};
    final int[] to = new int[]{R.id.id, R.id.title, R.id.desc};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dataBaseManager = new DataBaseManager(this);
        dataBaseManager.open();

        Cursor cursor = dataBaseManager.fetch();
        listView = findViewById(R.id.listView);
        listView.setEmptyView(findViewById(R.id.textView));

        adapter = new SimpleCursorAdapter(this, R.layout.list_row, cursor, from, to, 0);
        adapter.notifyDataSetChanged();
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long viewId) {
                TextView idTextView = view.findViewById(R.id.id);
                TextView titleTextView = view.findViewById(R.id.title);
                TextView descTextView = view.findViewById(R.id.desc);

                String id = idTextView.getText().toString();
                String title = titleTextView.getText().toString();
                String desc = descTextView.getText().toString();

                Intent modifyIntent = new Intent(getApplicationContext(), ModifyPlayerActivity.class);
                modifyIntent.putExtra("title", title);
                modifyIntent.putExtra("desc", desc);
                modifyIntent.putExtra("id", id);
                startActivity(modifyIntent);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.addRecord) {
            Intent addPlayer = new Intent(this, AddPlayerActivity.class);
            startActivity(addPlayer);
        }
        return super.onOptionsItemSelected(item);
    }
}

Bước 7: AddPlayerActivity.java & activity_addplayer.xml

// AddPlayerActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;

public class AddPlayerActivity extends AppCompatActivity implements View.OnClickListener {
    Button btnAdd;
    private EditText editSubject, editDescription;
    private DataBaseManager dataBaseManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle("Thêm bản ghi");
        setContentView(R.layout.activity_addplayer);

        editSubject = findViewById(R.id.editTextSubject);
        editDescription = findViewById(R.id.editTextDescription);
        btnAdd = findViewById(R.id.add_record);
        dataBaseManager = new DataBaseManager(this);
        dataBaseManager.open();
        btnAdd.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.add_record) {
            final String name = editSubject.getText().toString();
            final String desc = editDescription.getText().toString();
            dataBaseManager.insert(name, desc);
            Intent main = new Intent(AddPlayerActivity.this, MainActivity.class)
                    .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(main);
        }
    }
}
<!-- activity_addplayer.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp">

    <EditText
        android:id="@+id/editTextSubject"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Nhập tên">
        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/editTextDescription"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập quốc gia"
        android:inputType="textMultiLine" />

    <Button
        android:id="@+id/add_record"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Thêm bản ghi" />
</LinearLayout>

Bước 8: ModifyPlayerActivity.java & activity_modify_player.xml

// ModifyPlayerActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class ModifyPlayerActivity extends AppCompatActivity implements View.OnClickListener {
    EditText editTextSub, editTextDesc;
    Button updateBtn, deleteBtn;
    private long _id;
    DataBaseManager dataBaseManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle("Sửa bản ghi");
        setContentView(R.layout.activity_modify_player);

        dataBaseManager = new DataBaseManager(this);
        dataBaseManager.open();

        editTextSub = findViewById(R.id.editTextSub);
        editTextDesc = findViewById(R.id.editTextDesc);
        updateBtn = findViewById(R.id.btnUpdate);
        deleteBtn = findViewById(R.id.btnDelete);

        Intent intent = getIntent();
        String id = intent.getStringExtra("id");
        String name = intent.getStringExtra("title");
        String desc = intent.getStringExtra("desc");

        _id = Long.parseLong(id);
        editTextSub.setText(name);
        editTextDesc.setText(desc);

        updateBtn.setOnClickListener(this);
        deleteBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnUpdate:
                String title = editTextSub.getText().toString();
                String desc = editTextDesc.getText().toString();
                dataBaseManager.update(_id, title, desc);
                this.returnHome();
                break;
            case R.id.btnDelete:
                dataBaseManager.delete(_id);
                this.returnHome();
                break;
        }
    }

    public void returnHome() {
        Intent home_intent = new Intent(getApplicationContext(), MainActivity.class)
                .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(home_intent);
    }
}
<!-- activity_modify_player.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <EditText
        android:id="@+id/editTextSub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:ems="10"
        android:hint="Nhập tên" />

    <EditText
        android:id="@+id/editTextDesc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập quốc gia" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="2"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnUpdate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Cập nhật" />

        <Button
            android:id="@+id/btnDelete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Xóa" />
    </LinearLayout>
</LinearLayout>

Bước 9: Menu (res/menu/main.xml)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="https://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/addRecord"
        android:title="Thêm cầu thủ"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

Bước 10: Cấu hình Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".ModifyPlayerActivity"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".AddPlayerActivity" />
    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Ứng dụng cho phép xem danh sách, thêm, sửa, xóa cầu thủ.

Cách sử dụng SQLite Database trong ứng dụng Android Cách sử dụng SQLite Database trong ứng dụng Android

Các phương pháp hiện đại hơn

Hiện nay Google khuyến nghị sử dụng Room Database (thư viện Jetpack) thay vì SQLite trực tiếp vì:

  • Kiểm tra lỗi tại compile-time cho câu truy vấn SQL
  • Hỗ trợ LiveData/Flow để quan sát dữ liệu tự động
  • Tích hợp tốt với ViewModel, Repository pattern
  • Giảm boilerplate code đáng kể