Android数据持久化存储(二)
Android持久化存储(一)
在Android数据持久化存储(一)中介绍了Android数据持久化存储前两种方法,这一篇博客主要介绍第三种方法数据库使用,
SQLite是一款轻量级的关系型数据库,它的运行速度很快,占用资源少,通常只需要几百K的内存就足够了,因而现在的主流移动设备都使用SQLite作为复杂数据的存储引擎。对于Android来说,系统内置了丰富的API来提供开发人员操作SQLite,从而轻松的实现数据的操作。
首先给出全部代码:
main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:weightSum="1">
<Button
android:id="@+id/create_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="创建数据库"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/add_data"
android:text="Add Data"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/update_data"
android:text="update Data"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/query_data"
android:text="query Data"/>
</LinearLayout>
自己创建一个MyDatabaseHelper.java
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
//固定套路;
public class MyDatabaseHelper extends SQLiteOpenHelper {
private Context mContext;
//我们希望创建一个名为BookStore.db的数据库, 然后在数据库中新建一张Book表, 其中有id(主键), 作者, 价格,页数和书名. SQL建表语句如下:
/****
* integer: 表示整型;
* real: 表示浮点型;
* text: 表示文本型;
* blob:表示二进制类型
* primary key: 表示主键;
* autoincrement: 表示自增长
*/
public static final String CREATE_BOOK = "create table Book (" +
"id integer primary key autoincrement, " +
"author text, " +
"price real, " +
"page integer, " +
"name text)";
public static final String CREATE_CATEGORY = "create table Category (" +
"id integer primary key autoincrement," +
"category_name text," +
"category_code integer)";
////构造方法:第一个参数Context,第二个参数数据库名,第三个参数cursor允许我//
// 们在查询数据的时候返回一个自定义的光标位置,一般传入的都是null,
// 第四个参数表示目前库的版本号(用于对库进行升级)
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//调用SQLiteDatabase中的execSQL()执行建表语句。
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//如果Book、Category表已存在则删除表
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
}
activity.xml
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.apache.http.util.EncodingUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
Button createDatabase = (Button) findViewById(R.id.create_database);
//创建,设置监听事件;
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//QLiteOpenHelper中的两个非常重要的实例方法。
// getReadableDatabase()和getWriteableDatabase(),
// 这两个方法都可以创建和打开一个现有的数据库,
// 区别在于当数据库不可写入的时候getReadableDatabase()方法返回的对象将以只读
// 的方式去打开数据库,而getWriteDatabase()将出现异常
SQLiteDatabase db =
dbHelper.getWritableDatabase();
}
});
//添加
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//getWritableDatabase()会返回一个SQLiteDatabase对象
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name","The Da Vinci Code");
values.put("price",20);
values.put("page",600);
values.put("author","Scott");
//insert()方法中第一个参数是表名,第二个参数是表示给表中未指定数据的自动赋值为NULL。第三个参数是一个ContentValues对象
db.insert("Book",null,values);
values.clear();
values.put("name","The Lost Symbol");
values.put("author","Scott");
values.put("page",500);
values.put("price",30);
db.insert("Book",null,values);
}
});
//更新
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price",19.99);
//仔细update中提示的参数(String table,ContentValues,String whereClause,String[] whereArgs)
//第三滴四行指定具体更新那几行。注意第三个参数中的?是一个占位符,通过第四个参数为第三个参数中占位符指定相应的内容。
db.update("Book", values, "name=?", new String[]{"The Da Vinci Code"});
}
});
//查找;
Button queryButton = (Button) findViewById(R.id.query_data);
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
//指明去查询Book表。
Cursor cursor = db.query("Book",null,null,null,null,null,null);
//调用moveToFirst()将数据指针移动到第一行的位置。
if (cursor.moveToFirst()){
do {
//然后通过Cursor的getColumnIndex()获取某一列中所对应的位置的索引
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("page"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("MainActivity", "book name is " + name);
Log.d("MainActivity","book author is "+author);
Log.d("MainActivity","book pages is "+pages);
Log.d("MainActivity","book price is "+price);
}while(cursor.moveToNext());
}
cursor.close();
}
});
}
}
1SQLiteOpenHelper中的两个非常重要的实例方法。getReadableDatabase()和getWriteableDatabase(),这两个方法都可以创建和打开一个现有的数据库,区别在于当数据库不可写入的时候getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWriteDatabase()将出现异常
2删除数据很简单,SQLiteDatabase 提供了delete() 方法用于删除数据。这里就不写代码了具体讲一下什么意思
delete(String table, String whereClause, String [] whereArgs)
举个例子 delete(“Book”,”name=?”,new String[] {“The Da Vinci Code”});
就是把名字为The Da Vinci Code 这本书的数据都删除。
再比如:delete(“Book”,”price > ?”,new String[] {“20”});
意思就是把价格大于20 的所有的书都删掉。
哈哈还是很好玩的,想删什么删什么,但是要注意了 如果你第二,第三个参数不指定的话,就会删除所有行。
3
query()的参数讲解
SQLiteDatabase包含有四个参数不同的query函数,分别包含有7,8,9,10个参数。这么多的参数很难记,所以在这里以10个参数的query函数为例,梳理一下各个参数的意义。
Cursor query (
boolean distinct, //1设置为true,每一行的数据必须唯一。反之亦然。
String table, // 2表名
String[] columns, // 3要返回的列的名字的数组。如果设置为null,返回所有列,
String selection, //4个决定返回哪一行的过滤器,相当于SQL语句中的 WHERE
// 关键字。传递null则会返回给定表 的所有行
String[] selectionArgs, //5用于替换上一个参数中的 ? ,顺序对应selection中?的
// 顺序。格式限制为String格式
String groupBy, //6相当于SQL语句中的GROUP BY 关键字。
//传递null表示返回的行不会被分组。
String having, //7决定哪一行被放到Cursor中的过滤器。如果使用了行分组,
//相当于SQL语句中的HAVING关键字。传递null会导致所有
//的行都包含在内,前提
//是groupBy属性也设置为null。
String orderBy, //8行的排列方式,相当于SQL语句中的“ORDER BY”关键字,传递null表示使用默认的排序方式,可能是无序排列。
String limit, //9设置query语句返回行的数量,相当于SQL语句中的“LIMIT”关键字,传递null表示没有设置limit语句。注意格式为String,传递的时候需要传递数字字符串,例如“12
CancellationSignal cancellationSignal // 10取消程序操作的信号,如果没有则设置为null。如果操作取消了,query语句运行时会抛出OperationCanceledException异常。
含有7个参数的query函数不包含1,9,10,也就是distinct,limit,cancellationSignal。
含有8个参数的query函数不包含1,10,也就是distinct,cancellationSignal。
含有9个参数的query函数不包含10,也就是cancellationSignal。
4
insert()
方法中第一个参数是表名,第二个参数是表示给表中未指定数据的自动赋值为NULL。第三个参数是一个ContentValues对象
5
update
仔细update中提示的参数(String table,ContentValues,String whereClause,String[] whereArgs)
//第三滴四行指定具体更新那几行。注意第三个参数中的?是一个占位符,通过第四个参数为第三个参数中占位符指定相应的内容。