需求:写一个Person实体类,一个PersonDao类实现增删查改,一个mOpenHelper类的自定义帮助类,一个Test测试类来测试对应的功能,这里使用执行SQL语句方式。
基本步骤:
1.一般情况下,我们使用SQLiteOpenHelper这个帮助类来帮我们在SQLite中得到或者创建一个特定的数据库,但是这个类是一个abstract的抽象类,所以需要我们自己写一个实现类mOpenHelper继承SQLiteOpenHelper来实现它内部方法,同时这个类还要求我们至少实现它的某一个构造方法
(1)构造方法,这里一般要求实现父类的构造方法:super(context, name, factory, version); 其中,context是上下文,可以使用getContext()来得到;name是你需要的数据库名称,如果有同名的就直接得到,没有就建立一个新的,一般取做"xxx.db";factory是得到cursor对象的工厂类,这里设为null即可,表示使用默认的方法得到cursor;最后一个version代表数据库的版本,如果需要更新那么这个version应该比上一次的版本号要高,那么调用这个构造方法时就会通知数据库,需要更新,version的值最小为1,否则报异常。
(2)onCreate(SQLiteDatabase db)方法,这个什么好说的,是数据库创建的时候调用的方法,一般会在这里面完成一些初始化表或创建表的方法,使用db.execSQL(sql语句)来执行
(3)onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法,这个方法将在version号比之前的version号高的时候执行,一般里面实现一些更新数据库内容的操作,比如 删除、添加、修改表等等。
2.当帮助类mOpenHelper写好之后,可以完成Person实体类,其中包括三个成员变量以及对应getter和setter方法以及构造函数
3.要执行增删查改操作,还需要一个PersonDao的数据操作类,我们分别实现insert,delete,update和select功能,基本操作方法如下:
(1)使用new来得到一个mOpenHelper的实例mHelper
(2)使用mHelper得到一个SQLiteDatabase对象db,这个对象就是我们要执行具体操作的对象
对于insert,delete,update可以使用下面的操作来完成,因为不需要返回数据
(3)使用db.execSQL(sql语句,Object[] objects);来执行对应的操作即可,其中内部的sql语句是字符串形式,而objects是需要的参数,填补sql语句中的?号,没有的用null
对于select则使用下面的操作来完成,因为需要返回查询的结果数据
(4)这里会用到db.rawQuery(sql语句,Object[] objects);返回的是一个Curcor类型的游标对象cursor,而返回的数据都需要使用cursor来拿到
[1]cursor默认是从-1位置开始的,我们首先需要判断得到的cursor是否有效,使用if(cursor!=null&&cursor.getCount()>0)来判断
[2]使用循环方式while(cursor.moveTonext())作为判断条件来遍历cursor指向的对象,同时使用cursor.getXxx(int index)来获取对应的数据,这里由于是从序号来查询,那么就需要知道查询时的参数的顺序,所以一般我们在执行查询语句时,不会使用select * from的方式,而是将参数一个一个列出来,比如 select _id,name,agefrom...这种方法,这样能够让我们清楚的知道我们用cursor来取数据的时候第几个index对应的是什么类型的数据,比如这里,我们可以使用cursor.getInt(0);来取得int型的_id的值,使用cursor.getString(1);来取得String类型的name的值。
[3]取完一行数据之后,我们可以将数据封装到一个Person对象中,然后将这个对象的内容加入到一个List<Person>中(查询多个的情况)或者直接返回这个Person对象(查询单个的情况),以便最后函数将其返回调用者。
这里有几个需要注意的细节:
(1)首先是数据库对象SQLiteDatebase对象db,是占用资源的对象,所以在我们使用帮助类得到db之后,在使用之前,我们首先应当判断一下db是否真正拿到了,这里可以使用if(db.isOpen()){}方法来判断,其次在成功打开db之后,一定要执行db.close();方法,否则容易造成内存泄露
(2)cursor对象在使用完之后也应该关闭,执行cursor.close();方法
4.写一个Test类,继承AndroidTestCase类,在其中分别测试增、删、该、查单个、查多个
关于SQLite:
(1)可以使用一个小工具,SQLite Expert Personal 3来查看和执行SQL文件和操作。
(2)实际上在adb中也有使用命令行方式直接操作手机或模拟器中数据库的方式:在shell模式下,输入cd /data/data/包名/databases,进入对应目录,然后执行sqlite3 xx.db,就能打开对应的数据库,并使用SQL语句对其进行操作了。
部分代码:
SQLiteOpenHelper实现类:
package com.alexchen.sqlite.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
/**
* 数据库帮助类,用于创建和管理数据库
*
* @author Alex
*
*/
public class PersonSQLiteOpenHelper extends SQLiteOpenHelper {
/**
* 数据库的构造函数
*
* @param context 上下文
* @param name 数据库名称
* @param factory 游标cusor的工厂
* @param version 版本号,不可以小于1
*/
// 实现父类的构造方法
public PersonSQLiteOpenHelper(Context context) {
// super(context, name, factory, version);
// context是上下文,name是数据库名称,factory设为null则使用默认的cusor,version为数据库版本,至少从1开始
super(context, "alex.db", null, 1);
}
/**
* 数据库第一次创建时调用此方法 通常会做一些初始化表的操作
*/
@Override
public void onCreate(SQLiteDatabase db) {
// 创建表的SQL语句:
// create table person(
// _id integer primary key autoincrement,
// name varchar(20),
// age integer
// );
String sql="create table person(_id integer primary key,name varchar(20), age integer);";
// 操作数据库
db.execSQL(sql);//创建person表
}
/**
* 数据库的版本号更新时会自动回调此方法, 一般会做一些跟新数据库内容的操作(比如 删除表,添加表,修改版等等)
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
PersonDao数据库操作类:
package com.alexchen.sqlite.dao;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.alexchen.sqlite.db.PersonSQLiteOpenHelper;
import com.alexchen.sqlite.entity.Person;
public class PersonDao {
private PersonSQLiteOpenHelper mOpenHelper;// 数据库的帮助类
public PersonDao(Context context) {
mOpenHelper = new PersonSQLiteOpenHelper(context);
}
// 添加到person表一条数据
public void insert(Person person) {
SQLiteDatabase wDb = mOpenHelper.getWritableDatabase();
if (wDb.isOpen()) {
// insert into person(name,age) values('zhangsan',25);
String sql = "insert into person(name,age) values(?,?);";
// 执行添加操作
// 使用参数跟操作分开的模式
wDb.execSQL(sql, new Object[] { person.getName(), person.getAge() });
// 打开一次必须要关闭一次
wDb.close();
} else {
System.out.println("数据库打开失败");
return;
}
}
/*
* delete from person where _id=1;
*
* update person set name='李四' where _id=1;
*
* select * from person;
*/
/**
* 根据_id删除记录
* @param _id
*/
public void delete(int _id) {
String sql = "delete from person where _id=?;";
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL(sql, new Object[] { _id });
db.close();
}
}
/**
* 根据_id更新数据
* @param _id
*/
public void update(int _id) {
String sql = "update person set name=? where _id=?;";
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL(sql, new Object[] { "李四", _id });
db.close();
}
}
/**
* 查询所有
* @return
*/
public List<Person> queryAll() {
List<Person> personList;
int _id;
String name;
int age;
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
if (db.isOpen()) {
String sql = "select _id,name,age from person;";
// 由于查询需要返回对象,所以不能再使用execSQL了,只能使用rawQuery来返回一个Cursor对象
Cursor cursor = db.rawQuery(sql, null);
// cursor默认时是-1
if (cursor != null && cursor.getCount() > 0) {
// 移到下一位,只要不是最后一位
personList = new ArrayList<>();
while (cursor.moveToNext()) {
_id = cursor.getInt(0);
name = cursor.getString(1);
age = cursor.getInt(2);
personList.add(new Person(_id, name, age));
}
db.close();
cursor.close();
return personList;
}
db.close();
cursor.close();
}
return null;
}
/**
* 根据_id查询Item
* @param _id
* @return
*/
public Person queryItem(int _id) {
Person person = null;
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
if (db.isOpen()) {
String sql = "select name,age from person where _id=?";
Cursor cursor = db.rawQuery(sql,
new String[] { String.valueOf(_id) });
if (cursor != null && cursor.moveToFirst()) {
String name = cursor.getString(0);
int age = cursor.getInt(1);
person = new Person(_id, name, age);
cursor.close();
db.close();
}
cursor.close();
db.close();
}
return person;
}
}