SQLite 的单个条目信息

Single Entry Information for SQLite

我正在开发一个应用程序。我想知道如何将用户的联系信息(姓名、图片、phone 号码、地址)存储在 SQLite 中,但不能添加到该数据库?
更多具有编辑功能的单一条目信息。

你能给我提供好的例子吗?

假设您只需要修改一个用户,您可以执行以下操作。

  • 使用 GSON.

  • 将用户对象设为 JSON 字符串
  • 存储这个用户 class JSON 字符串在 SharedPreference.

  • 必要时从 SharedPreference 获取用户 JSON 字符串,并将其从 JSON 字符串转换为用户 class。

这是一个使用 SQLite 创建具有单个 table 和单个行的数据库的基本示例。

主要有两个组成部分。您的应用 activity 和 DBHelper Class.

中的代码

首先是 DBHelper class :-

package your.package;

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

/**
 * Created by Mike092015 on 13/08/2016.
 */
public class MyDBHelper extends SQLiteOpenHelper {

    // A few variables
    public static final String DATABASE_NAME = "MYDB";
    public static final int DATABASE_VERSION = 1;

    // The Database Constructor
    public MyDBHelper(Context ctxt, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(ctxt, DATABASE_NAME, factory, DATABASE_VERSION); }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String sqlstr = "CREATE TABLE IF NOT EXISTS MYUSERTABLE (_id INTEGER PRIMARY KEY, " +
                "NAME TEXT NOT NULL, " +
                "PICTURE TEXT, " +
                "PHONE_NUMBER TEXT, " +
                "ADDRESS TEXT);";
        db.execSQL(sqlstr);
        sqlstr = "INSERT INTO MYUSERTABLE (_id, NAME, PICTURE, PHONE_NUMBER, ADDRESS) " +
                "VALUES('0','MYNAME','MYPICTURE_LINK','00 0000 0000','NONE');";
        db.execSQL(sqlstr);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        //DO NOTHING

    }

    public Cursor getUserAsCursor() {
        String sqlstr = "SELECT * FROM MYUSERTABLE;";
        SQLiteDatabase db = this.getReadableDatabase();
        return db.rawQuery(sqlstr,null);
    }
}

创建 MyDBHelper 实例将创建不存在的数据库(当尝试通过 getReadableDatabase()getWritableDatabase() 打开数据库时)并导致 onCreate要调用的方法,其中创建 table 并填充一行。如果数据库已经存在,那么 onCreate 将不会被调用,因此 table 不会被触及。请注意,该实例将在另一个 activity 中创建(见下文)。

如果版本号增加,那么将调用 onUpgrade 方法(我已经这样做了,所以它什么都不做(我个人不使用它,而是使用创建伪模式的方法根据值,然后将其与实际模式进行比较,然后相应地添加额外的 tables/rows))。但是,目前不要担心 onUpgrade。只需删除应用程序的数据即可重新开始。

引入了一种方法,即getUserAsCursor,它将return一个SQLite游标(以列为元素的行数组)。这用于调用 activity.

第二个代码是调用 activity 并且是 :-

package your.package;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class Main extends AppCompatActivity {

    public MyDBHelper myDBHelper = new MyDBHelper(this,null,null,1);

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

        Cursor csr = myDBHelper.getUserAsCursor();
        Toast.makeText(this,"Cursor Count returns " + csr.getCount() +
                "\nNumber of Columns is " + csr.getColumnCount(),
                Toast.LENGTH_LONG).show();
        csr.moveToFirst();

        if(csr.getCount() > 0) {
            Toast.makeText(this,"Name==> " + csr.getString(1) + "\n" +
                    "Picture==> " + csr.getString(2)  + "\n" +
                    "Phone Number==> " + csr.getString(3) + "\n" +
                    "Address===> " + csr.getString(4),Toast.LENGTH_LONG).show();
        }
        else {
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        myDBHelper.close();
    }
}

相关代码的方面是:-

public MyDBHelper myDBHelper = new MyDBHelper(this,null,null,1);

创建数据库实例。如前所述,这将创建数据库和 table,仅当数据库不存在时才会填充它。

Cursor csr = myDBHelper.getUserAsCursor();

这会调用 getUserAsCursor 方法 return 创建一个包含 table 中所有行的所有列的游标。根据 SQL 查询 SELECT * FROM MYUSERTABLE;(Select 来自 table 的所有列称为 MYUSERTABLE)。

Toast.makeText(this,"Cursor Count returns " + csr.getCount() +
                "\nNumber of Columns is " + csr.getColumnCount(),
                Toast.LENGTH_LONG).show();

是调试信息。它会生成一个 toast,说明 return 游标中包含多少行和多少列。

csr.moveToFirst();

这会移动到第一个 data/row(我不确定这个词是什么,但游标最初位于 header,如果它是一行,则尝试访问它导致 'OutofBounds' 错误)。

if(csr.getCount() > 0) {
            Toast.makeText(this,"Name==> " + csr.getString(1) + "\n" +
                    "Picture==> " + csr.getString(2)  + "\n" +
                    "Phone Number==> " + csr.getString(3) + "\n" +
                    "Address===> " + csr.getString(4),Toast.LENGTH_LONG).show();
        }

这会从行中的列访问数据并发出显示数据的 toast。如您所见,它使用游标“getString”方法获取行的索引(从 0 开始)。

您可能想知道为什么我将 _id 作为列包含在 table 中。这是因为有些东西,比如cursorAdapters(被ListViews使用)期望有这样一个列。



关于更新用户。下面是如何实现这一目标的示例。这个基本示例根据 :-

向 DBHelper 添加了另一种方法 upDateUser
    public void upDateUser(String newname, String newpicture, String newphonenumber, String newaddress) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("NAME",newname);
        cv.put("PICTURE",newpicture);
        String where = "_id = ? ";
        String[] whereargs = new String[] {String.valueOf(0)};
        db.update("MYUSERTABLE", cv, where, whereargs);
        db.close();
    }

请注意,您可以通过 db.execSQL 使用查询来执行相同的操作。但是,使用 contentValues 和更新方法被认为是更好的做法(我相信)

然后通过(在上述代码之后)从 activity 中调用:-

    myDBHelper.upDateUser("Fred", "A NEW PICTURE", "11 1111 1111","0 NOWHERE TOWN");

然后复制以下代码(如前所述),将显示 changed/updated 记录(请注意,在这种情况下,只会显示第一个 运行 之后的变化database/table/row 已创建,后续 运行 将显示相同的数据):-

csr = myDBHelper.getUserAsCursor(); // get DB cursor via getUserAsCursor method
Toast.makeText(this,"Cursor Count returns " + csr.getCount() +
                "\nNumber of Columns is " + csr.getColumnCount(),
        Toast.LENGTH_LONG).show(); // Show, via toast, # of rows and # of columns
csr.moveToFirst();

if(csr.getCount() > 0) {
    Toast.makeText(this,"Name==> " + csr.getString(1) + "\n" +
            "Picture==> " + csr.getString(2)  + "\n" +
            "Phone Number==> " + csr.getString(3) + "\n" +
            "Address===> " + csr.getString(4),Toast.LENGTH_LONG).show();
}
else {
}

请注意,虽然提到了最佳实践,但还没有使用一些最佳实践来轻松生成此答案(即我有点懒惰)。