前面一章学习到了SharedPreferences,它可以存储不同类型的键值对。比如,存储一个用户的账号和密码。但是,如果这个应用被要求可以记住多个用户的密码怎么办?这个时候SharedPreferences就很难做到了,而使用安卓内置的SQLite轻量级数据库就可以很轻松做到。
1、创建数据库
// DatabaseTest.java MainActivity.java
private Button mButton;
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.create_db_button);
dbHelper = new MyDatabaseHelper(getApplicationContext(), "student.db", null, 1);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
dbHelper.getReadableDatabase(); // 第一次执行的时候,onCreate方法会执行
}
});
}
// MyDatabaseHelper.java
public class MyDatabaseHelper extends SQLiteOpenHelper{
private Context mContext;
private static final String CREATE_DB = "create table student(id integer primary key autoincrement, "
+ "no text, name text, number text)";
public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB);
Toast.makeText(mContext, "创建数据库成功!", Toast.LENGTH_LONG).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
}
}
这里说明几点需要注意的地方:
(1)SQLiteOpenHelper是一个抽象类,所以我们需要实现它的方法才可以使用
(2)onCreate函数是在getWritableDatabase或者getReadableDatabase之后实现的,还有一个前提是数据库还没有被创建。
(3)SQLite的数据类型没有那么多,只有integer、real、text和blob(二进制)
实现效果:
2、更新数据库
为什么需要更新数据库:仍然是上面的例子,如果再次点击按钮,onCreate函数不会再执行。(所以更准确点说,onCreate函数只会执行一次)那么如果我还想创建新的数据库怎么办?这个方法就必须写在onUpgrade函数内。但是这个函数要执行也要一定的条件:那就是构造函数的版本数要大于第一次创建数据库时的版本数(比如上面的例子,要大于1)
3、添加数据
CRUD操作:C:Create,即创建数据库;R:Retrieve,即查询;U:Update,即更新;D:Delete,即删除。学过数据库就知道这几种操作的数据库语言,但是不是所有人都知道具体的语句怎么写。所以Android提供了一系列操作,可以使用函数来实现CRUD。
下面是插入数据的例子:首先通过getWritableDatabase获取可以插入数据的SQLiteDatabase,然后再创建ContentValues,也就是键值对,最后使用insert插入这个contentvalues就可以了。
mBInsert = (Button) findViewById(R.id.insert_button);
mBInsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
SQLiteDatabase database = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "kuli");
values.put("no", "30");
values.put("number", "12345");
database.insert(MyDatabaseHelper.TABLE_NAME, null, values);
Toast.makeText(getApplicationContext(), "插入数据成功!", Toast.LENGTH_LONG).show();
}
});
实现效果:
4、更新数据
mBUpdate = (Button) findViewById(R.id.update_button);
mBUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("number", "6789");
db.update(MyDatabaseHelper.TABLE_NAME, values, "name = ?", new String[]{"kuli"});
Toast.makeText(getApplicationContext(), "更新数据成功!", Toast.LENGTH_LONG).show();
}
});
关键在最后两个参数:第一个表示需要查询的属性名称,第二个表示属性的取值。
5、删除数据
和更新的思路类似。
mBDelete = (Button) findViewById(R.id.delete_button);
mBDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(MyDatabaseHelper.TABLE_NAME, "name = ?", new String[] {"kuli"});
Toast.makeText(getApplicationContext(), "删除数据成功!", Toast.LENGTH_LONG).show();
}
});
6、查询数据
查询数据是四种操作中最难的,首先是参数复杂,其次是返回的数据类型是Cursor,它的使用也是要注意的。下面先介绍查询操作的参数:
query()方法参数 | 对应SQL | 部分描述 |
table | from table_name | 指定查询的表名 |
columns | select column1, column2 | 指定查询的列名 |
selection | where column = value | 指定where 的约束条件 |
selectionArgs | - | 为where 中的占位符提供具体的值 |
groupBy | group by column | 指定需要group by 的列 |
having | having column = value | 对group by 后的结果进一步约束 |
orderBy | order by column1, column2 | 指定查询结果的排序方式 |
当然这些参数也不是什么时候都要用上的,如果你要获取数据库的所有记录,除了第一个表名,其他传入null就行了。
// MyDatabaseHelper.java
public Cursor getQuery() {
SQLiteDatabase db = getReadableDatabase();
return db.query(TABLE_NAME, null, null, null, null, null, null);
}
// MainActivity.java
mBQuery = (Button) findViewById(R.id.query_button);
mBQuery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Cursor cursor = dbHelper.getQuery();
while (cursor.moveToNext()) {
Log.d("sysu", cursor.getString(cursor.getColumnIndex("no")));
Log.d("sysu", cursor.getString(cursor.getColumnIndex("name")));
Log.d("sysu", cursor.getString(cursor.getColumnIndex("number")));
}
cursor.close();
Toast.makeText(getApplicationContext(), "遍历数据成功!", Toast.LENGTH_LONG).show();
}
});
实现效果:
7、使用SQL操作数据库
其实前面实现的CRUD操作通过execSQL和rawQuery这两个函数也可以实现,如下:
// 其他方法
database.execSQL("insert into student(no, name, number) values(?, ?, ?, ?)", new String[] {"30", "kuli", "12345"}); // 插入数据
db.execSQL("update table student set number = ? where name = ?", new String[] {"6789", "kuli"}); // 更新数据
db.execSQL("delete from student where name = ?", new String[] {"kuli"}); // 删除数据
cursor = db.rawQuery("select * from student", null); // 查询数据
这两种方法都各有好处,前者使用方便,后者加深对SQL语句的记忆。各有所长。