文章目录
- 创建数据库
- 更新数据库
- 增加数据
- 修改数据
- 删除数据
- 查询数据
安卓专门提供了一个SQLiteOpenHelper帮助类,借助这个类可以非常简单地对数据库进行创建和升级。SQLiteOpenHelper是一个抽象类,使用它需要创建一个自己的帮助类去继承它。SQLiteOpenHelper中有两个抽象方法:onCreate()和onUpgrade()。我们需要在帮助类里重写这两个方法,然后分别在这两个方法中实现创建和升级数据库的逻辑。
SQLiteOpenHelper中还有两个非常重要的实例方法:getReadableDatabase()和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则要创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入的时候(如磁盘空间已满),getReadableDatabase()方法返回的对象将以只读的方式打开数据库,而getWritableDatabase()方法则将出现异常。
创建数据库
SQLiteOpenHelper中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法中接收4个参数:第一个参数是Context,这个没什么好说的,必须有它才能对数据库进行操作;第二个参数是数据库名,创建数据库时使用的就是这里指定的名称;第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般传入null即可;第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。构建出SQLiteOpenHelper的实例之后,再调用它的getReadableDatabase()或getWritableDatabase()方法就能够创建数据库了,数据库文件会存放在/data/data//databases/目录下。此时,重写的onCreate()方法也会得到执行,所以通常会在这里处理一些创建表的逻辑。
新建MyDatabaseHelper类继承自SQLiteOpenHelper。
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text, "
+ "price real, "
+ "pages integer, "
+ "name text)";
private Context mContext;
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, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
修改activity_main.xml中的代码。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/createDatabase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Database" />
</LinearLayout>
最后修改MainActivity中的代码.
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.createDatabase);
createDatabase.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
dbHelper.getWritableDatabase();
}
});
}
}
运行程序之后并不能查看数据库,需要先下载一个插件Database Navigator。
安装好插件后需要重启Android studio,重启之后打开Device File Explorer,然后进入/data/data/com.example.databasetest/databases/目录下,可以看到已经存在了一个BookStore.db文件。对着BookStore.db文件右击→Save As,将它从模拟器导出到计算机的任意位置。
安装好插件之后可以使用快捷键Ctrl + Shift + A(Mac系统是command + shift + A)打开搜索功能,在搜索框中输入“DB Browser”即可找到这个工具。
找到保存文件的路径,应用之后就可以在左侧看到数据库的内容了。
更新数据库
当数据库BookStore.db已经存在时,MyDatabaseHelper中的onCreate()方法不会再次执行。这里就可以巧妙的利用数据库更新,从而达到新建表的效果。
修改MyDatabaseHelper.java文件。
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text, "
+ "price real, "
+ "pages integer, "
+ "name text)";
// 新建表的SQL语句
public static final String CREATE_CATEGORY = "create table Category ("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code inteher)";
private Context mContext;
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);
// 在执行onCreate时创建表
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
// 更新数据库
@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);
}
}
使用db.execSQL将已经存在的表先删除,否则创建已经存在的表会报错。
SQLiteOpenHelper的构造方法里接收的第四个参数代表的就是版本号,第一次输入的是1,要更新数据库,输入的值就要比上一次大。
修改MainActivity.java文件,其实就只是修改一下数据库版本号。
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, 2);
Button createDatabase = (Button) findViewById(R.id.createDatabase);
createDatabase.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
dbHelper.getWritableDatabase();
}
});
}
}
增加数据
SQLiteDatabase中提供了一个insert()方法,专门用于添加数据。它接收3个参数:第一个参数是表名;第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般我们用不到这个功能,直接传入null即可;第三个参数是一个ContentValues对象,它提供了一系列的put()方法重载,用于向ContentValues中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。
修改activity_main.xml中的代码。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/createDatabase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Database" />
<Button
android:id="@+id/addData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add data" />
</LinearLayout>
修改MainActivity中的代码。
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, 2);
Button createDatabase = (Button) findViewById(R.id.createDatabase);
createDatabase.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
dbHelper.getWritableDatabase();
}
});
Button addData = (Button) findViewById(R.id.addData);
addData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// 开始组装第一条数据
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 497);
values.put("price", 17.9);
db.insert("Book", null, values);
values.clear();
// 开始组装第二条数据
values.put("name", "The Lost Symbol");
values.put("author", "Dan Brown");
values.put("pages", 597);
values.put("price", 27.9);
db.insert("Book", null, values);
}
});
}
}
运行程序点击按钮之后,重新保存BookStore.db文件,然后打开DB Browser执行SQL语句select * from Book,就可以看见增加的数据了。
修改数据
SQLiteDatabase中提供了一个非常好用的update()方法,用于对数据进行修改。这个方法接收4个参数:第一个参数和insert()方法一样,也是表名,指定更新哪张表里的数据;第二个参数是ContentValues对象,要把更新数据在这里组装进去;第三、第四个参数用于约束更新某一行或某几行中的数据,不指定的话默认会更新所有行。
修改activity_main.xml中的代码,新加一个按钮用于修改数据。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/createDatabase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Database" />
<Button
android:id="@+id/addData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add data" />
<Button
android:id="@+id/updateData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Upadate data" />
</LinearLayout>
修改MainActivity中的代码,实现修改数据的逻辑。
Button updateData = (Button) findViewById(R.id.updateData);
updateData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 19.99);
db.update("Book", values, "name = ?", new String[]{"The Da Vinci Code"});
}
});
还是和之前操作一样,重新保存一下db文件,然后就可以看到数据更新了。
删除数据
SQLiteDatabase中提供了一个delete()方法,专门用于删除数据。这个方法接收3个参数:第一个参数仍然是表名;第二、第三个参数用于约束删除某一行或某几行的数据,不指定的话默认会删除所有行。
修改activity_main.xml中的代码,新加一个按钮,用于删除数据。
<Button
android:id="@+id/deleteData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete Data"
/>
修改MainActivity中的代码,实现删除功能。
Button deleteData =(Button) findViewById(R.id.deleteData);
deleteData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages > ?", new String[] {"500"});
}
});
操作同上,查询之后就可以看见pages大于500的被删除了。
查询数据
SQLiteDatabase中提供了一个query()方法用于对数据进行查询。这个方法的参数非常复杂,最短的一个方法重载也需要传入7个参数。第一个参数是表名,表示希望从哪张表中查询数据。第二个参数用于指定去查询哪几列,如果不指定则默认查询所有列。第三、第四个参数用于约束查询某一行或某几行的数据,不指定则默认查询所有行的数据。第五个参数用于指定需要去group by的列,不指定则表示不对查询结果进行group by操作。第六个参数用于对group by之后的数据进行进一步的过滤,不指定则表示不进行过滤。第七个参数用于指定查询结果的排序方式,不指定则表示使用默认的排序方式。
修改activity_main.xml中的代码,新加一个按钮。
<Button
android:id="@+id/queryData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query Data" />
修改MainActivity中的代码。
Button queryData = (Button) findViewById(R.id.queryData);
queryData.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);
if(cursor.moveToFirst()){
do{
// 遍历Cursor对象,取出数据并打印
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
String author = cursor.getString(cursor.getColumnIndexOrThrow("author"));
int pages = cursor.getInt(cursor.getColumnIndexOrThrow("pages"));
double price = cursor.getDouble(cursor.getColumnIndexOrThrow("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就可以看见查询到的内容了。