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

Cách sử dụng BIGINT trong SQLite Android

Giới thiệu về SQLite và kiểu dữ liệu

SQLite là cơ sở dữ liệu SQL mã nguồn mở, lưu trữ dữ liệu trong file văn bản trên thiết bị. Android tích hợp sẵn SQLite.

Lưu ý quan trọng: SQLite không có kiểu BIGINT như MySQL/PostgreSQL. SQLite sử dụng dynamic typing (kiểu động) và chỉ có 5 lớp lưu trữ: NULL, INTEGER, REAL, TEXT, BLOB. Khi bạn khai báo BIGINT(8), SQLite hiểu là INTEGER (8 byte, signed 64-bit).

Ví dụ này minh họa lưu trữ số lớn (lương) trong SQLite Android.

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

Mở Android Studio, chọn File → New Project và điền đầy đủ thông tin cần thiết.

Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity">

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

    <EditText
        android:id="@+id/salary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập lương (số lớn)"
        android:inputType="number" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Lưu" />

        <Button
            android:id="@+id/refresh"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Làm mới" />

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

        <Button
            android:id="@+id/delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Xóa tất cả" />

    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Bước 3: MainActivity.java

package com.example.andy.myapplication;

import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    Button save, refresh, update, delete;
    EditText name, salary;
    ListView listView;
    DatabaseHelper helper;
    ArrayAdapter arrayAdapter;
    ArrayList arrayList;

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

        helper = new DatabaseHelper(this);
        arrayList = new ArrayList<>(helper.getAllContacts());
        
        name = findViewById(R.id.name);
        salary = findViewById(R.id.salary);
        listView = findViewById(R.id.listView);
        save = findViewById(R.id.save);
        refresh = findViewById(R.id.refresh);
        update = findViewById(R.id.update);
        delete = findViewById(R.id.delete);

        arrayAdapter = new ArrayAdapter<>(this, 
            android.R.layout.simple_list_item_1, arrayList);
        listView.setAdapter(arrayAdapter);

        delete.setOnClickListener(v -> {
            if (helper.deleteAll()) {
                Toast.makeText(this, "Đã xóa", Toast.LENGTH_LONG).show();
                refreshList();
            } else {
                Toast.makeText(this, "Xóa thất bại", Toast.LENGTH_LONG).show();
            }
        });

        update.setOnClickListener(v -> {
            String n = name.getText().toString().trim();
            String s = salary.getText().toString().trim();
            if (!n.isEmpty() && !s.isEmpty()) {
                if (helper.update(n, s)) {
                    Toast.makeText(this, "Đã cập nhật", Toast.LENGTH_LONG).show();
                    refreshList();
                } else {
                    Toast.makeText(this, "Cập nhật thất bại", Toast.LENGTH_LONG).show();
                }
            } else {
                name.setError("Nhập tên");
                salary.setError("Nhập lương");
            }
        });

        refresh.setOnClickListener(v -> refreshList());

        save.setOnClickListener(v -> {
            String n = name.getText().toString().trim();
            String s = salary.getText().toString().trim();
            if (!n.isEmpty() && !s.isEmpty()) {
                if (helper.insert(n, s)) {
                    Toast.makeText(this, "Đã thêm", Toast.LENGTH_LONG).show();
                    refreshList();
                    name.setText("");
                    salary.setText("");
                } else {
                    Toast.makeText(this, "Thêm thất bại", Toast.LENGTH_LONG).show();
                }
            } else {
                name.setError("Nhập tên");
                salary.setError("Nhập lương");
            }
        });
    }

    private void refreshList() {
        arrayList.clear();
        arrayList.addAll(helper.getAllContacts());
        arrayAdapter.notifyDataSetChanged();
    }
}

Bước 4: DatabaseHelper.java

package com.example.andy.myapplication;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;

class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "salaryDatabase5";
    private static final String TABLE_NAME = "SalaryDetails";
    private static final int DATABASE_VERSION = 1;

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // SQLite KHÔNG có BIGINT - dùng INTEGER (8 byte, 64-bit signed)
        // BIGINT(8) được hiểu là INTEGER
        String sql = "CREATE TABLE " + TABLE_NAME + " (" +
            "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "name TEXT, " +
            "salary INTEGER, " +  -- INTEGER lưu số 64-bit (-2^63 đến 2^63-1)
            "datetime DEFAULT CURRENT_TIMESTAMP)";
        db.execSQL(sql);
    }

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

    boolean insert(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        // ContentValues.put(String, Long) cho số lớn
        try {
            cv.put("salary", Long.parseLong(salary));
        } catch (NumberFormatException e) {
            cv.put("salary", salary); // fallback lưu TEXT
        }
        long result = db.replace(TABLE_NAME, null, cv);
        return result != -1;
    }

    ArrayList getAllContacts() {
        SQLiteDatabase db = getReadableDatabase();
        ArrayList list = new ArrayList<>();
        
        // Hiển thị đầy đủ: id : name : salary : datetime
        String query = "SELECT (id || ' : ' || name || ' : ' || salary || ' : ' || datetime) AS fullname FROM " + TABLE_NAME;
        Cursor res = db.rawQuery(query, null);
        
        if (res.moveToFirst()) {
            do {
                list.add(res.getString(res.getColumnIndexOrThrow("fullname")));
            } while (res.moveToNext());
        }
        res.close();
        return list;
    }

    boolean update(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        try {
            cv.put("salary", Long.parseLong(salary));
        } catch (NumberFormatException e) {
            cv.put("salary", salary);
        }
        int rows = db.update(TABLE_NAME, cv, null, null); // CẢNH BÁO: không WHERE
        return rows > 0;
    }

    boolean deleteAll() {
        SQLiteDatabase db = getWritableDatabase();
        int rows = db.delete(TABLE_NAME, null, null);
        return rows > 0;
    }
}

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Nhập tên và lương số lớn (ví dụ: 9999999999), nhấn Lưu, sau đó Làm mới.

Kết quả

ListView hiển thị dạng: "1 : Nguyễn Văn A : 9999999999 : 2024-01-15 10:30:00"

Giải thích về INTEGER trong SQLite

  • Kích thước: 1, 2, 3, 4, 6, hoặc 8 byte tùy giá trị
  • Phạm vi: -9,223,372,036,854,775,808 đến +9,223,372,036,854,775,807 (64-bit signed)
  • BIGINT(8): Chỉ là alias (bí danh) cho INTEGER, số 8 không giới hạn kích thước
  • Lưu số rất lớn (>2^63): Phải lưu dưới dạng TEXT

Lưu ý: Code gốc khai báo "salary BIGINT(8)" - SQLite chấp nhận nhưng bỏ qua (8). Đã sửa thành INTEGER rõ ràng. Cũng sửa ContentValues.put Long để lưu số đúng kiểu. Cảnh báo UPDATE không WHERE.