SQLite是无类型数据库,可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么,也不用关心存放长度的问题。
但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误。
SQLite可以解析大部分标准SQL语句,如:
查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order by 排序子句
如:select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘传智’,3)
更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=‘传智‘ where id=10
删除语句:delete from 表名 where 条件子句。如:delete from person where id=10
为了对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2,并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。
getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
DBOpenHelper类继承SQLiteOpenHelper,实现onCreate和onUpgrade方法
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBOpenHelper extends SQLiteOpenHelper {
public DBOpenHelper(Context context) {
//类没有实例化,是不能用作父类构造器的参数,必须声明为静态
private static final String name = "wxxu"; //数据库名称,如果加后缀名可以为wxxu.db
private static final int version = 1; //数据库版本,不能为0
//第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
public DatabaseHelper(Context context) {
super(context, name, null, 1);//版本号从1开始,不能为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 oldVersion, int newVersion) {
db.execSQL("ALTER TABLE person ADD amount integer");
}
}
实现增删查改功能
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import cn.itcast.domain.Person;
public class PersonService {
private DBOpenHelper dbOpenHelper;
public PersonService(Context context) {
this.dbOpenHelper = new DBOpenHelper(context);
}
/**
* 添加记录
* @param person
*/
public void save(Person person){
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
db.execSQL("insert into person(name, phone, amount) values(?,?,?)",
new Object[]{person.getName(), person.getPhone(), person.getAmount()});
}
/**
* 删除记录
* @param id 记录ID
*/
public void delete(Integer id){
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
db.execSQL("delete from person where personid=?", new Object[]{id});
}
/**
* 更新记录
* @param person
*/
public void update(Person person){
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
db.execSQL("update person set name=?,phone=?,amount=? where personid=?",
new Object[]{person.getName(), person.getPhone(), person.getAmount(), person.getId()});
}
/**
* 查询记录
* @param id 记录ID
* @return
*/
public Person find(Integer id){
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from person where personid=?", new String[]{id.toString()});
if(cursor.moveToFirst()){
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
int amount = cursor.getInt(cursor.getColumnIndex("amount"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone = cursor.getString(cursor.getColumnIndex("phone"));
return new Person(personid, name, phone, amount);
}
cursor.close();
return null;
}
/**
* 分页获取记录
* @param offset 跳过前面多少条记录
* @param maxResult 每页获取多少条记录
* @return
*/
public List<Person> getScrollData(int offset, int maxResult){
List<Person> persons = new ArrayList<Person>();
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from person order by personid asc limit ?,?",
new String[]{String.valueOf(offset), String.valueOf(maxResult)});
while(cursor.moveToNext()){
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
int amount = cursor.getInt(cursor.getColumnIndex("amount"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone = cursor.getString(cursor.getColumnIndex("phone"));
persons.add(new Person(personid, name, phone, amount));
}
cursor.close();
return persons;
}
/**
* 分页获取记录
* @param offset 跳过前面多少条记录
* @param maxResult 每页获取多少条记录
* @return
*/
public Cursor getCursorScrollData(int offset, int maxResult){
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select personid as _id,name,phone,amount from person order by personid asc limit ?,?",
new String[]{String.valueOf(offset), String.valueOf(maxResult)});
return cursor;
}
/**
* 获取记录总数
* @return
*/
public long getCount(){
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select count(*) from person", null);
cursor.moveToFirst();
long result = cursor.getLong(0);
cursor.close();
return result;
}
}
测试增删查改
//创建数据库,通过调用getWritableDatabase方法
public void testCreateDB() throws Exception{
DBOpenHelper dbOpenHelper = new DBOpenHelper(getContext());
dbOpenHelper.getWritableDatabase();
}
public void testSave() throws Exception{
PersonService service = new PersonService(this.getContext());
for(int i = 0 ; i < 20 ; i++){
Person person = new Person("zhangxx"+ i, "136765765"+ i, 100);
service.save(person);
}
}
public void testDelete() throws Exception{
PersonService service = new PersonService(this.getContext());
service.delete(21);
}
public void testUpdate() throws Exception{
PersonService service = new PersonService(this.getContext());
Person person = service.find(1);
person.setName("zhangxiaoxiao");
service.update(person);
}
public void testFind() throws Exception{
PersonService service = new PersonService(this.getContext());
Person person = service.find(1);
Log.i(TAG, person.toString());
}
SQLite数据库的事务管理
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。使用例子如下:
SQLiteDatabase db = ....;
db.beginTransaction();//开始事务
try {
db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"哈哈哈哈", 4});
db.execSQL("update person set name=? where personid=?", new Object[]{"呵呵", 1});
db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务
} finally {
db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务
}
db.close();
上面两条SQL语句在同一个事务中执行。