在Android中使用的数据库是开源数据库Sqlite数据库,下面主要详细的介绍Sqlite的使用:
一 SQLite简介
我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版本进行管理来实现前面提出的需求。
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabasedb)和onUpgrade(SQLiteDatabasedb, intoldVersion, intnewVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。
getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
1先完成创建数据库操作:定义DBOpenHelper需要继承SQLiteOpenHelper类,重写onCreate方法创建数据库,当版本号变化时,执行onUpgrade更新数据表信息。
package com.andy.service;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBOpenHelper extends SQLiteOpenHelper{
public DBOpenHelper(Context context) {
super(context, "andy.db", null, 0);
}//数据库版本号从0开始 第一次为创建 没加一次就会执行数据库信息的更新操作
@Override
public void onCreate(SQLiteDatabase db) {//数据库每一次被创建的时间调用
db.execSQL("CREATE TABLE person(personid integer primary key autoincrement, name varchar(20), phone VARCHAR(12) NULL)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int orderVersion, int newVersion) {
db.execSQL("ALTER TABLE person ADD amount integer");
}
}
2 定义实现的PersonService数据库操作类
package com.andy.service;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.andy.domain.Person;
public class PersonService {
private DBOpenHelper dbOpenHelper;
public PersonService(Context context) {
dbOpenHelper = new DBOpenHelper(context);
}
// 打开数据库的方法有getWritableDatabase getReadableDatabase 如果数据库未满时 返回的是writable
public void save(Person person) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();
sqLiteDatabase.execSQL(
"insert into person(name, phone, amount) values(?, ?, ?) ",
new String[] { person.getName(), person.getPhone(),
String.valueOf(person.getAmount()) });
}
public void update(Person person) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();
sqLiteDatabase
.execSQL(
"update person set name=?, phone=?, amount=? where personid = ?",
new String[] { person.getName(), person.getPhone(),
person.getAmount().toString(),
person.getId().toString() });
}
public void delete(int id) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();
sqLiteDatabase.execSQL("delete from person where personid=?",
new Integer[] { id });
}
public Person find(Integer id) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();// 读取数据
Cursor cursor = sqLiteDatabase.rawQuery(
"SELECT * FROM person WHERE personid = ?",
new String[] { id.toString() });
if (cursor.moveToFirst()) {
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone = cursor.getString(cursor.getColumnIndex("phone"));
int amount = cursor.getInt(cursor.getColumnIndex("amount"));
return new Person(personid, name, phone, amount);
}
cursor.close();// 游标 需要关闭
return null;
}
public List<Person> getScrollData(int offset, int maxResult) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();
List<Person> persons = new ArrayList<Person>();
Cursor cursor = sqLiteDatabase.rawQuery(
"select * from person order by personid limit ?,? ",
new String[] { String.valueOf(offset),
String.valueOf(maxResult) });
while (cursor.moveToNext()) {
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone = cursor.getString(cursor.getColumnIndex("phone"));
int amount = cursor.getInt(cursor.getColumnIndex("amount"));
persons.add(new Person(personid, name, phone, amount));
}
cursor.close();
return persons;
}
public long getCount() {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("select count(*) from person",
null);
cursor.moveToFirst();
long result = cursor.getLong(0);
cursor.close();
return result;
}
public Cursor getCursorScrollData(int offset, int maxResult){
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery(
"select personid _id, name, phone, amount from person order by personid limit ?,? ",
new String[] { String.valueOf(offset),
String.valueOf(maxResult) });
return cursor;
}
//测试事务 transaction
public void payment(){
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();
sqLiteDatabase.beginTransaction();
try{
sqLiteDatabase.execSQL("update person set amount = amount -10 where personid = 1");
sqLiteDatabase.execSQL("update person set amount = amount + 10 where personid = 2");
sqLiteDatabase.setTransactionSuccessful();
}finally{
sqLiteDatabase.endTransaction();//结束事务有两种情况 commit rollback
//事物的提交是由事务的标志决定的,如果事务的标志为true,事务就会提交,否则就会回滚,默认情况下事务的状态的状态是FALSE
//无论回滚或者是提交 必须要执行事务的结束 放在try finally中执行
}
}
}
3 使用到的Person类
package com.andy.domain;
public class Person {
private Integer id;
private String name;
private String phone;
private Integer amount;
public Person(){
}
public Person(String name, String phone, Integer amount) {
super();
this.name = name;
this.phone = phone;
this.amount = amount;
}
public Person(Integer id, String name, String phone, Integer amount) {
super();
this.id = id;
this.name = name;
this.phone = phone;
this.amount = amount;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", phone=" + phone
+ ", amount=" + amount + "]";
}
}