通过项目实践,来熟悉利用SQLiteDatabase来操作SQLite的基本用法。
一、SQLite数据库
1、创建
(1)、SQLite通过SQLiteOpenHelper帮助类来更方便的管理数据库,SQLiteOpenHelper是一个抽象类,需要被继承后实现自己的帮助类。
(2)、SQLiteOpenHelper有两个抽象方法需要重写:onCreate()和onUpgrade(),即创建和升级方法。
(3)、SQLiteOpenHelper的两个实例方法(创建或打开一个现有的数据库,并返回一个可对数据库进行读写操作的对象):
①、getReadableDatabase():当数据库不可写入时(如磁盘空间已满),返回的对象将以只读的方式去打开数据库。
②、getWritableDatabase():当数据库不可写入时(如磁盘空间已满),出现异常。
(4)、SQLiteOpenHelper的构造方法:
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
参数一:上下文
参数二:数据库名
参数三:返回一个自定义的Cursor
参数四:版本号
(5)、SQLite数据库的数据类型:
integer:整型
real:浮点型
text:文本类型
blob:二进制类型
另外:primary代表将当前字段设置为主键,autoincrement代表主键自增。
若想创建一个名为BookStore的数据库,并包含一个名为Book数据表,步骤如下。
新建项目,DatabaseTest,新建MyDatabaseOpenHelper类并继承DatabaseOpenHelper类,代码如下:
package com.my.databasetest;
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; //上下文
//建表语句,表名:Book
public static final String CREATE_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text, "
+ "price real, "
+ "pages integer, "
+ "name text)";
//构造函数
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
mContext = context;
}
//创建方法
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
Toast.makeText(mContext, "创建成功!", Toast.LENGTH_SHORT).show();
}
//升级方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
修改activity_main.xml中的代码:
<?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:id="@+id/create_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="创建"
/>
</LinearLayout>
修改MainActivity中的代码:
package com.my.databasetest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper myDatabaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//利用帮助类创建数据库,数据库名BookStore,版本号 1
myDatabaseHelper = 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) {
myDatabaseHelper.getWritableDatabase();
}
});
}
}
运行程序:
再次点击不会出现Toast提示,因为数据库已经创建。
查看已创建的数据库中的数据:
Tools\Android\Android Device Monitor,在新出现的窗口中点击File Explorer,data\data\当前项目包名\databases目录下,可以看到数据库,但是无法查看其中具体的数据。
另一种方法:
将sdk的platform-tools配置到环境变量中(安装SDK时就应该将此目录配置到环境变量中,Android Studio自带的SDK会自动配置环境变量,但是不会配置该目录,仍需手动配置),里面是SDK自带的adb调试工具。
1、进入控制台,输入adb shell,进入设备控制台。
2、使用cd命令进入当前项目的databases目录,然后输入ls进行查看。
3、借助sqlite命令打开数据库:sqlite3 + 数据库名
4、输入 .table 查看数据表。
5、还可以通过 .schema 来查看建表语句。
2、升级
帮助类中,重写的onUpgrade()方法就是用来升级数据库的方法。
需求:在当前项目的数据库中新添加一个用于记录图书分类的Category表。
修改MyDatabaseHelper类代码:
(1)、在原来的Book建表语句下新增以下代码:
//建表语句,表名:Category
public static final String CREATE_CATEGORY = "create table Category ("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code integer)";
(2)、修改onCreate()代码:
//创建方法
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "创建成功!", Toast.LENGTH_SHORT).show();
}
(3)、在onUpgrade()方法中新增以下代码:
//升级方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
(4)、在MainActivity中,将创建数据库语句的参数,版本号改为2.
//利用帮助类创建数据库,数据库名BookStore,版本号 1,升级后版本号 2
myDatabaseHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
升级方法中使用DROP语句,若存在Book表,删除,若存在Category表,删除,然后调用onCreate()方法,重新建表。
运行程序后,点击创建按钮,会重新弹出Toast提示。使用adb工具查看。
3、添加数据
(1、)打开或创建数据库时,会使用到getReadableDatabase()方法或getWritableDatabase()方法。这两个方法都会返回一个SQLiteDatabase对象,通过该对象中专有的insert()方法可以实现向数据库中添加数据。
(2)、insert()方法:insert(String table, String nullColumnHack, ContentValues values)
参数一:表名。
参数二:用于在未指定添加数据的情况下给某些可为空的列自动赋值null,一般用不到,可以传入null。
参数三:ContentValues对象,数据载体,通过put()方法添加数据,利用这个对象将所有数据写入数据库。
修改activity_main.xml文件,新增一个按钮。
<Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加"
/>
修改MainActivity的createDatabase点击事件下添加一下代码:
Button addData = (Button)findViewById(R.id.add_data);
//点击事件,新增数据
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
//开始组装第一条数据
values.put("name","The Da Vinci Code");
values.put("author","Dan Brown");
values.put("pages",454);
values.put("price",16.96);
db.insert("Book",null,values);
values.clear();
//开始组装第二条数据
values.put("name","The Lost Symbol");
values.put("author","Dan Brown");
values.put("pages",510);
values.put("price",19.95);
db.insert("Book",null,values);
}
});
运行程序后,点击“添加”按钮,然后查看数据库中的数据。
4、更新数据
(1)、更新数据可以使用到SQLiteDatabase中的update()方法。
(2)、update()方法:update(String table, ContentValues values, String whereClause, String[] whereArgs)
参数一:表名。
参数二:ContentValues对象,用来存储需要更新的数据。
参数三、参数四:用于约束更新某一行或某几行中的数据,不指定,默认更新所有行。
修改activity_main.xml文件,新增一个按钮。
<Button
android:id="@+id/update_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更新"
/>
修改MainActivity中的代码,在addData的点击事件下,新增一下代码:
Button updateData = (Button)findViewById(R.id.update_data);
//点击事件,更新数据
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price",10.99);
//更新方法,将书名为The Da Vinci Code的价格更改为values中的数据
db.update("Book",values,"name = ?",new String[] {"The Da Vinci Code"});
}
});
运行程序,点击更新,查看数据库中的数据。
可以看到书的价格已经与上一次运行的结果不同了,16.96 -> 10.99
5、删除数据
(1)、删除数据可以用到SQLiteDatabase中的delete()方法。
(2)、delete()方法:
参数一:表名。
参数二、参数三:用于约束删除某一行还是删除某几行的数据,不指定,默认删除所有行。
修改activity_main.xml文件,新增一个按钮。
<Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除"
/>
修改MainActivity中的代码,在update点击事件的下面添加以下代码:
Button deleteData = (Button)findViewById(R.id.delete_data);
//点击事件,删除数据
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();
//删除方法,将Book表中pages大于500的数据整行删除。
db.delete("Book","pages > ?",new String[] {"500"});
}
});
运行程序,点击删除,查看数据库中的数据。
可以看到,对比与上一次运行结果,大于500页的书籍已经被删除了。
6、查询数据
(1)、查询数据可以用到SQLiteDatabase中的query()方法。
(2)、query()方法有三个:
①、query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
②、query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
③、query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
其中参数最少的也有7个之多,以这个方法为例,查看它的参数及含义。
三个方法都会返回Cursor对象,查询到的所有数据都从该对象中取出。
修改activity_main.xml文件,添加一个按钮。
<Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"
/>
修改MainActivity中的代码,在deleteData的点击事件下添加以下代码:
Button queryData = (Button)findViewById(R.id.query_data);
//点击事件,查询数据
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();
//查询Book表中的所有数据
Cursor cursor = db.query("Book",null,null,null,null,null,null);
if(cursor.moveToFirst()){
do{
//遍历Cursor对象,取出数据并打印
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
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();
}
});
运行程序:
点击查询,查看Logcat输出:
(1)、添加数据语句:
db.execSQL("insert into Book (name,author,pages,price) values(?,?,?,?)",new String[] {"The Da Vinci Code","Dan Brown","454",16.96});
(2)、更新数据语句:
db.execSQL("update Book set price = ? where name = ?",new String[] {"10.99","The Da Vinci Code"});
(3)、删除数据语句:
db.execSQL("delete from Book where pages > ?",new String[] {"500"});
(4)、查询数据语句:
db.rawQuery("select * from Book",null);
以上总结自郭神(郭霖)《第一行代码 第二版》并做了少量修改。