创建数据库
1.SQLiteHelper简介
Android 为了让我们能够更加方便地管理数据库,专门提供了一个 SQLiteOpenHelper 帮助类,借助这个类就可以非常简单地对数据库进行创建和升级 SQLiteOpenHelper 是一个抽象类,这意味着如果我们想要使用它的话,就需要创建一个自己的帮助类去继承它。 SQLiteOpenHelper 中有两个抽象方法,分别是onCreate()和 onUpgrade(),我们必须在自己的帮助类里面重写这两个方法,然后分别在这两个方法中去实现创建、升级数据库的逻辑。
SQLiteOpenHelper中还有两个非常重要的实例方法 , getReadableDatabase() 和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入的时候(如磁盘空间已满) getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而 getWritableDatabase()方法则将出现异常。
SQLiteOpenHelper 中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法中接收四个参数,第一个参数是 Context,这个没什么好说的,必须要有它才能对数据库进行操作。第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般都是传入null。第四个参数表示当前数据库的版本号 ,可用于对数据库进行升级操作。
先写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, 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) {
}
}
创建好自己的MyDatabaseHelper 后,可以再往后的代码中创建Helper实例,调用getReadabledatabase()或者getWriterabledatabase即可创建数据库,示例如下:
private MyDatabaseHelper dbHelper;
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);//调用了CREATE()函数
dbHelper.getWritableDatabase();
升级数据库
当指定的数据库版本号大于当前数据库版本号的时候,就会进入到 onUpgrade()方法中去执行更新操作。这里需要为每一个版本号赋予它各自改变的内容,然后在onUpgrade()方法中对当前数据库的版本号进行判断,再执行相应的改变就可以了
onUpgrade()方法是用于对数据库进行升级的,例如我们在一个数据库中已经有一个BOOK表,想要再创建一个CATEGORY表,我们不能通过修改onCREATE()方法去新增加一个表,下面是错误示例:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);//已经创建过BOOK表
db.execSQL(CREATE_CATEGORY);//此表将无法创建,因为已经拥有BOOK表
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).
show();
}
正确的步骤是
1.修改onCreate()方法
2.在onUPGRADE()方法中编写case语句,对应相应的版本号
3.修改创建数据库语句,把传入的版本号改为大于之前的版本号即可
代码:
//1.修改onCreate(SQLiteDatabase db)
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREAT_BOOK);
db.execSQL(CREATE_CATEGORY);
}
//2.修改onUpgrade()
public class MyDatabaseHelper extends SQLiteOpenHelper {
……
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
db.execSQL(CREATE_CATEGORY);
case 2:
//第二版程序要更新的内容
case 3:
//第三版程序要更新的内容
default:
break;
}
}
//将原先的版本号1改为大于1的版本号,这里改为了2
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
switch 中每一个 case 的最后都是没有使用 break 的,这是为了保证在跨版本升级的时候,每一次的数据库修改都能被全部执行到。比如用户当前是从第二版程序升级到第三版程序的,那么 case 2 中的逻辑就会执行。而如果用户是直接从第一版程序升级到第三版程序的,那么 case 1 和 case 2 中的逻辑都会执行。使用这种方式来维护数据库的升级,不管版本怎样更新,都可以保证数据库的表结构是最新的,而且表中的数据也完全不会丢失了
添加数据
调用 SQLiteOpenHelper 的 getReadableDatabase()或 getWritableDatabase()方法是可以用于创建和升级数据库的,不仅如此,这两个方法还都会返回一个 SQLiteDatabase对象,借助这个对象就可以对数据进行插入、修改、查询等操作了。
1.插入数据
SQLiteDatabase 中提供了一个 insert()方法,这个方法就是专门用于添加数据的。它接收三个参数,第一个参数是表名,我们希望向哪张表里添加数据,这里就传入该表的名字。第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值 NULL,一般我们用不到这个功能,直接传入 null 即可。第三个参数是一个 ContentValues 对象,它提供了一系列的 put()方法重载,用于向 ContentValues 中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。
插入数据步骤总结:
1.通过getWrite获取数据库对象db
2.通过ContentValues 先组装好每一行的数据values;
3.最后用db.insert(“表名”, null, values);插入各个组装好的数据
代码示例:
SQLiteDatabase db = dbHelper.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); // 插入第二条数据
2.更新数据
SQLiteDatabase 中也是提供了一个非常好用的 update()方法用于对数据进行更新,这个方法接收四个参数,第一个参数和 insert()方法一样,也是表名,在这里指定去更新哪张表里的数据。第二个参数是 ContentValues 对象,要把更新数据在这里组装进去。第三、第四个参数用于去约束更新某一行或某几行中的数据,不指定的话默认就是更新所有行。
更新数据步骤总结:
1.通过getWrite获取数据库对象db
2.通过ContentValues 写好要更新的列和数值,例如price变为10.99
values.put("price", 10.99);
3.调用db.update(),传入相应数值
db.update("Book", values, "name = ?", new String[]{"The DaVinci Code"});
其中第三个就是SQL语句中的Where,“Where name = ?”,那这个?问好是什么呢,就是第四个String数组里的值,结合起来,就是”Where name = The DaVinci code”
具体代码:
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values, "name = ?", new String[] { "The Da
Vinci Code" });
3.删除数据
删除数据提供了delete()方法,该方法接收三个参数,第一个参数是表名,第二、第三个参数是用于去约束删除某一行或某几行的数据,不指定的话默认就是删除所有行。
步骤:
1.通过getWrite获取数据库对象db
2.调用db.update(),传入相应数值
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages > ?", new String[]{"500"});
3.查询数据
SQLiteDatabase 中提供了一个 query()方法用于对数据进行查询。这个方法的参数非常复杂,最短的一个方法重载也需要传入七个参数。下面我们只介绍最简单的七个参数的方法。
db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
第一个参数,表名,表示我们希望从哪张表中查询数据。
第二个参数用于指定去查询哪几列,如果不指定则默认查询所有列。
第三、第四个参数用于去约束查询某一行或某几行的数据,不指定则默认是查询所有行的数据。
第五个参数用于指定需要去 group by 的列,不指定则表示不对查询结果进行 group by 操作。
第六个参数用于对 group by 之后的数据进行进一步的过滤,不指定则表示不进行过滤。
第七个参数用于指定查询结果的排序方式,不指定则表示使用默认的排序方式。更多详细的内容可以参考下表。