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 {
}
请注意,虽然提到了最佳实践,但还没有使用一些最佳实践来轻松生成此答案(即我有点懒惰)。
我正在开发一个应用程序。我想知道如何将用户的联系信息(姓名、图片、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 {
}
请注意,虽然提到了最佳实践,但还没有使用一些最佳实践来轻松生成此答案(即我有点懒惰)。