1. 程式人生 > >Android-SQLiteOpenHelper裡增刪改查

Android-SQLiteOpenHelper裡增刪改查

為什麼要寫一篇,Android-SQLiteOpenHelper裡增刪改查,的文章呢;

  因為之前的方式是:MySQLiteOpenHelper(只負責 生成開啟據庫/生成開啟表/升級表),在其他端:完成此資料庫表的增刪改查邏輯處理,這樣程式碼有些分散

現在 MySQLiteOpenHelper(負責 生成開啟據庫 / 生成開啟表 / 升級表 / 完成此資料庫表的增刪改查邏輯處理 / 還有其他表處理功能增加等等),這一個類全包了

 


 

 

MySQLiteOpenHelperStudent

注意事項:繼承SQLiteOpenHelper抽象類 重寫的創表方法,此SQLiteDatabase db 不能關閉

package liudeli.datastorage.db;

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

import java.util.List;

import liudeli.datastorage.entity.Student;

/** * 資料庫表管理 * MySQLiteOpenHelperStudent * (負責 生成開啟據庫 / 生成開啟表 / 升級表 / * 完成此資料庫表的增刪改查邏輯處理 * / 還有其他表處理功能增加等等) */ public class MySQLiteOpenHelperStudent extends SQLiteOpenHelper { private final static String TAG = MySQLiteOpenHelperStudent.class.getSimpleName(); /** * 資料庫名稱
*/ private final static String DB_NAME = "student_info_manager.db"; /** * 表名 */ private static final String TABLE_NAME = "studentTable"; /** * 定義單例模式,可以被多次地方多次呼叫 */ private static MySQLiteOpenHelperStudent mySQLiteOpenHelperStudent; public static MySQLiteOpenHelperStudent getInstance(Context context) { if (null == mySQLiteOpenHelperStudent) { synchronized (MySQLiteOpenHelperStudent.class) { if (null == mySQLiteOpenHelperStudent) { mySQLiteOpenHelperStudent = new MySQLiteOpenHelperStudent(context, DB_NAME, null, 1); } } } return mySQLiteOpenHelperStudent; } private MySQLiteOpenHelperStudent(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } /** * 創表方法,注意:⚠️ 傳遞進來的 SQLiteDatabase database 不能關閉 * @param database */ private void createTable(SQLiteDatabase database) { String createTableSQL = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (ID INTEGER PRIMARY KEY, " + "name VARCHAR, " + "age INTEGER, " + "hobby VARCHAR);"; try { database.execSQL(createTableSQL); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, TAG + "創表異常:" + e.toString()); } /** * 注意:⚠️ * 這裡不能關閉database * 一旦關閉就會 Caused by: java.lang.IllegalStateException: * attempt to re-open an already-closed object: SQLiteDatabase: * 為什麼不能在這裡關閉呢? * 答:因為這個database,是在 public void onCreate ->傳遞過來的 */ /*finally { if (null != database) { database.close(); } }*/ } /** * 刪除表,會把表給刪除,慎用 * drop 表 */ public void dropTable() { SQLiteDatabase database = getWritableDatabase(); String dropSQL = "drop table if exists " + TABLE_NAME; try { database.execSQL(dropSQL); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "drop異常:" + e.toString()); } finally { if (null != database) { database.close(); } } } /** * 清除表的資料 */ public void cleanUpData() { // delete from TableName; //清空資料 SQLiteDatabase database = getWritableDatabase(); String dropSQL = "delete from " + TABLE_NAME; try { database.execSQL(dropSQL); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "drop異常:" + e.toString()); } finally { if (null != database) { database.close(); } } } /** * 插入多條資料 * @param students 傳遞Student集合 */ public void insertData(List<Student> students) { SQLiteDatabase database = getWritableDatabase(); try { for (Student student : students) { ContentValues contentValues = new ContentValues(); contentValues.clear(); contentValues.put("name", student.getName()); contentValues.put("age", student.getName()); contentValues.put("hobby", student.getHobby()); database.insert(TABLE_NAME, "_id", contentValues); } } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "insert多條異常:" + e.toString()); } finally { if (null != database) { database.close(); } } } /** * 插入單條 * @param contentValues 傳遞ContentValues */ public void insertData(ContentValues contentValues) { SQLiteDatabase database = getWritableDatabase(); try { database.insert(TABLE_NAME, "_id", contentValues); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "insert單條異常:" + e.toString()); } finally { if (null != database) { database.close(); } } } /** * 查詢需要的列名 */ private String[] columns = new String[]{"name", "age", "hobby"}; /** * 查詢第一條資料 * @return 返回Student實體 */ public Student selectData() { SQLiteDatabase database = getReadableDatabase(); Cursor cursor = null; Student student = null; try { cursor = database.query(TABLE_NAME, columns, null, null, null, null, null); if (cursor.moveToFirst()) { String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); String hobby = cursor.getString(cursor.getColumnIndex("hobby")); student = new Student(name, age, hobby); } } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "select異常:" + e.toString()); } finally { if (null != database) { database.close(); } if (null != cursor) cursor.close(); } return student; } /** * 判斷第一條資料是否存在 * @return 存在返回true,否則返回false */ public boolean isMoveToFirst() { boolean result; SQLiteDatabase database = getReadableDatabase(); Cursor cursor = database.query(TABLE_NAME, columns, null, null, null, null, null); result = cursor.moveToFirst(); database.close(); cursor.close(); return result; } /** * ......... 還可以增加很多操作表相關的行為 */ /** * 繼承SQLiteOpenHelper抽象類 重寫的創表方法,此SQLiteDatabase db 不能關閉 * @param db */ @Override public void onCreate(SQLiteDatabase db) { createTable(db); } /** * 繼承SQLiteOpenHelper抽象類 重寫的升級方法 * @param db * @param oldVersion * @param newVersion */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

 

繼承SQLiteOpenHelper抽象類 重寫的創表方法,此SQLiteDatabase db 不能關閉

/**
     * 創表方法,注意:⚠️ 傳遞進來的 SQLiteDatabase database 不能關閉
     * @param database
     */
    private void createTable(SQLiteDatabase database) {
        String createTableSQL =  "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (ID INTEGER PRIMARY KEY, "
                + "name VARCHAR, "
                + "age INTEGER, "
                + "hobby  VARCHAR);";
        try {
            database.execSQL(createTableSQL);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, TAG + "創表異常:" + e.toString());
        }

        /**
         * 注意:⚠️
         * 這裡不能關閉database
         * 一旦關閉就會 Caused by: java.lang.IllegalStateException:
         *             attempt to re-open an already-closed object: SQLiteDatabase:
         * 為什麼不能在這裡關閉呢?
         * 答:因為這個database,是在 public void onCreate ->傳遞過來的
         */
        /*finally {
            if (null != database) {
                database.close();
            }
        }*/
    }

一旦關閉,就會報以下錯誤:

Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

 

 

Student實體:

package liudeli.datastorage.entity;

public class Student {

    private String name;
    private int age;
    private String hobby;

    public Student() {
    }

    public Student(String name, int age, String hobby) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}

 

測試程式碼:

package liudeli.datastorage;

import android.app.Activity;
import android.content.ContentValues;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

import liudeli.datastorage.db.MySQLiteOpenHelperStudent;
import liudeli.datastorage.entity.Student;

public class MySQLiteActivity extends Activity {

    private MySQLiteOpenHelperStudent mySQLiteOpenHelperStudent;

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

        mySQLiteOpenHelperStudent = MySQLiteOpenHelperStudent.getInstance(this);

        /**
         * 初始化資料
         */
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", "劉劉" + System.currentTimeMillis());
        contentValues.put("age", 26);
        contentValues.put("hobby", "愛寫部落格" + System.currentTimeMillis());

        mySQLiteOpenHelperStudent.insertData(contentValues);
    }

    /**
     * 查詢
     * @param view
     */
    public void query(View view) {
        Student student = mySQLiteOpenHelperStudent.selectData();
        if (student != null) {
            Log.d("sql", "student.toString:" + student.toString());
        }
    }

    /**
     * 是否有第一條資料
     * @param view
     */
    public void query1(View view) {
        Toast.makeText(this, mySQLiteOpenHelperStudent.isMoveToFirst() + "", Toast.LENGTH_LONG).show();
    }

    /**
     * drop表 刪除表
     * @param view
     */
    public void  dropTable(View view) {
        mySQLiteOpenHelperStudent.dropTable();
    }

    /**
     * 插入很多資料
     * @param view
     */
    public void installMany(View view) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("李李", 11, "AAAAAAA"));
        students.add(new Student("李李22", 222, "BBBB"));
        students.add(new Student("李李33", 333, "CCC"));
        students.add(new Student("李李44", 444, "DDD"));
        mySQLiteOpenHelperStudent.insertData(students);
    }

    /**
     * 清除表資料
     * @param view
     */
    public void cleanUpData(View view) {
        mySQLiteOpenHelperStudent.cleanUpData();
    }
}

 

測試程式碼的佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="query"
        android:text="查詢"
        android:layout_weight="0"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="是否有第一條資料"
        android:onClick="query1"
        android:layout_weight="0"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="drop表 刪除表"
        android:onClick="dropTable"
        android:layout_weight="0"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="插入很多資料"
        android:onClick="installMany"
        android:layout_weight="0"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="cleanUpData"
        android:text="清除表資料"
        />

</LinearLayout>