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

Cách nối hai cột trong SQLite Android

Giới thiệu về SQLite trong Android

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, hỗ trợ đầy đủ tính năng cơ sở dữ liệu quan hệ. Không cần thiết lập kết nối như JDBC/ODBC để truy cập.

Ví dụ này minh họa cách nối (concatenate) hai cột name và salary thành một cột hiển thị 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"
        android:inputType="numberDecimal" />

    <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);

        // Xóa tất cả
        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();
            }
        });

        // Cập nhật
        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");
            }
        });

        // Làm mới
        refresh.setOnClickListener(v -> refreshList());

        // Lưu
        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) {
        String sql = "CREATE TABLE " + TABLE_NAME + " (" +
            "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "name TEXT, " +
            "salary TEXT, " +
            "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);
    }

    // Thêm bản ghi (dùng replace để upsert)
    boolean insert(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        cv.put("salary", salary);
        long result = db.replace(TABLE_NAME, null, cv);
        return result != -1;
    }

    // QUAN TRỌNG: Nối cột name và salary bằng toán tử ||
    ArrayList getAllContacts() {
        SQLiteDatabase db = getReadableDatabase();
        ArrayList list = new ArrayList<>();
        
        // Sử dụng || để nối chuỗi trong SQLite
        String query = "SELECT (name || ' - ' || salary) 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);
        cv.put("salary", salary);
        // Cập nhật bản ghi đầu tiên tìm thấy (nên dùng WHERE id=...)
        int rows = db.update(TABLE_NAME, cv, null, null);
        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 trong Android Studio. Nhập tên và lương, nhấn Lưu, sau đó nhấn Làm mới để xem danh sách.

Kết quả

Danh sách hiển thị dạng: "Nguyễn Văn A - 10000000" (tên và lương được nối bằng dấu " - ")

Giải thích quan trọng

  • Toán tử ||: Trong SQLite, dùng để nối chuỗi (concatenation). Cú pháp: cot1 || 'phan_cach' || cot2
  • AS fullname: Đặt bí danh cho cột kết quả để dễ lấy qua Cursor
  • db.replace(): Thực hiện INSERT hoặc REPLACE (nếu khóa chính trùng)
  • ContentValues: An toàn hơn nối chuỗi SQL trực tiếp (tránh SQL Injection)

Lưu ý: Code gốc dùng db.execSQL với nối chuỗi cho UPDATE - không an toàn. Đã sửa dùng ContentValues + db.update(). Cũng đã sửa tên phương thức getAllCotacts → getAllContacts.