一、SQLite特点
Android平台中嵌入了一个关系型数据库SQLite,和其他数据库不同的是SQLite存储数据时不区分类型,例如一个字段声明为Integer类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数。除非是主键被定义为Integer,这时只能存储64位整数。
创建数据库的表时可以不指定数据类型,例如:
CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))
CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name)
上面两句SQL语句是一样的。
SQLite支持大部分标准SQL语句,增删改查语句都是通用的,分页查询语句和MySQL相同
SELECT * FROM person LIMIT 20 OFFSET 10
SELECT * FROM person LIMIT 10,20
二、创建数据库
定义类继承SQLiteOpenHelper
声明构造函数,4个参数
重写onCreate()方法
重写upGrade()方法
注意:SQLite数据库中列一旦创建不能修改,如果一定要修改,需要重新创建表,拷贝数据
三. CRUD操作
和JDBC访问数据库不同,操作SQLite数据库无需加载驱动,不用获取连接,直接可以使用
获取SQLiteDatabase对象之后通过该对象直接可以执行SQL语句
SQLiteDatabase.execSQL()
SQLiteDatabase.rawQuery()
getReadableDatabase()和getWritableDatabase()的区别
查看源代码后我们发现getReadableDatabase()在通常情况下返回的就是getWritableDatabase()拿到的数据库,只有在抛出异常的时候才会以只读方式打开
数据库对象缓存。getWritableDatabase()方法最后会使用一个成员变量记住这个数据库对象,下次打开时判断是否重用。
SQLiteDatabase封装了insert()、delete()、update()、query()四个方法也可以对数据库进行操作,这些方法封装了部分SQL语句,通过参数进行拼接。
四、事务管理
在使用SQLite数据库时可以用SQLiteDatabase类中定义的相关方法控制事务
beginTransaction() 开启事务
setTransactionSuccessful() 设置事务成功标记
endTransaction() 结束事务
endTransaction()需要放在finally中执行,否则事务只有到超时的时候才自动结束,会降低数据库并发效率
例子:
public class MyDBOpenHelper extends SQLiteOpenHelper { /** * * @param context 应用程序上下文 * @param name 数据库的名字 * @param factory 查询数据库的游标工厂 一般情况下 用sdk默认的 * @param version 数据库的版本 版本号必须不小1 * */ public MyDBOpenHelper(Context context) { super(context, "itheima.db", null, 5); } // 在mydbOpenHelper 在数据库第一次被创建的时候 会执行onCreate(); @Override public void onCreate(SQLiteDatabase db) { System.out.println("我被调用了 oncreate"); db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { System.out.println("on update "); db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL "); } }
MyDBOpenHelper helper = new MyDBOpenHelper(this);
SQLiteDatabase ddatabase = helper.getReadableDatabase();
获取数据库后进行CRUD
常用DAO代码参考:
/** * 数据库常用Dao */ public class BlackNumberDao { private BlackNumberDBOpenHelper helper; public BlackNumberDao(Context context) { helper = new BlackNumberDBOpenHelper(context); } /** * 查找一条黑名单号码 */ public boolean find(String number) { boolean result = false; SQLiteDatabase db = helper.getReadableDatabase(); if (db.isOpen()) { Cursor cursor = db.rawQuery( "select * from blacknumber where number =?", new String[] { number }); if (cursor.moveToFirst()) { result = true; } cursor.close(); db.close(); } return result; } /** * 查找一条黑名单号码的拦截模式 */ public int findNumberMode(String number) { int result = -1; SQLiteDatabase db = helper.getReadableDatabase(); if (db.isOpen()) { Cursor cursor = db.rawQuery( "select mode from blacknumber where number =?", new String[] { number }); if (cursor.moveToFirst()) { result = cursor.getInt(0); } cursor.close(); db.close(); } return result; } /** * 添加一条黑名单号码 */ public boolean add(String number, String mode) { if (find(number))// 防止添加重复的数据 return false; SQLiteDatabase db = helper.getWritableDatabase(); if (db.isOpen()) { db.execSQL("insert into blacknumber (number,mode) values (?,?)", new Object[] { number, mode }); db.close(); } return find(number); } /** * 删除一条黑名单号码 */ public void delete(String number) { SQLiteDatabase db = helper.getWritableDatabase(); if (db.isOpen()) { db.execSQL("delete from blacknumber where number=?", new Object[] { number }); db.close(); } } /** * 更改黑名单号码 * * @param oldnumber 旧的的电话号码 * @param newnumber 新的号码 可以留空 * @param mode 新的模式 */ public void update(String oldnumber, String newnumber, String mode) { SQLiteDatabase db = helper.getWritableDatabase(); if (db.isOpen()) { if (TextUtils.isEmpty(newnumber)) { newnumber = oldnumber; } db.execSQL( "update blacknumber set number=?, mode=? where number=?", new Object[] { newnumber, mode, oldnumber }); db.close(); } } /** * 查找全部的黑名单号码 * @return */ public List<BlackNumber> findAll() { List<BlackNumber> numbers = new ArrayList<BlackNumber>(); SQLiteDatabase db = helper.getReadableDatabase(); if (db.isOpen()) { Cursor cursor = db.rawQuery("select number,mode from blacknumber", null); while (cursor.moveToNext()) { BlackNumber blackNumber = new BlackNumber(); blackNumber.setNumber(cursor.getString(0)); blackNumber.setMode(cursor.getInt(1)); numbers.add(blackNumber); blackNumber = null; } cursor.close(); db.close(); } return numbers; } /** * 分页的加载数据 * @param startindex * @param maxresult * @return */ public List<BlackNumber> findAllByPage(int startindex ,int maxresult) { List<BlackNumber> numbers = new ArrayList<BlackNumber>(); SQLiteDatabase db = helper.getReadableDatabase(); if (db.isOpen()) { Cursor cursor = db.rawQuery("select number,mode from blacknumber limit ?,? ", new String[]{startindex+"",maxresult+""}); while (cursor.moveToNext()) { BlackNumber blackNumber = new BlackNumber(); blackNumber.setNumber(cursor.getString(0)); blackNumber.setMode(cursor.getInt(1)); numbers.add(blackNumber); blackNumber = null; } cursor.close(); db.close(); } return numbers; } }