安卓SQLite数据库笔记
好奇、学习、总结、分享
一、常用的数据库
1、SQL:结构化查询语言(Structured Query Language),常用数据库有:sql sever[微软]、mysql[开源]、Oracle[甲骨文]。
2、安卓用数据库:SQLite【轻量型结构化查询语言】
3、数据库的优点:存储大量结构相同的数据,查询速度快。数据库的一般操作:创建数据库、打开数据库、创建表、向表中添加数据、从表中删除数据、修改表中的数据、关闭数据库、删除指定表、删除数据库和查询表中的某条数据。
二、安卓数据库简介
Android使用开源的、与操作系统无关的SQL数据库—SQLite。SQLite第一个Alpha版本诞生于2000年5月,它是一款轻量级数据库,它的设计目标是嵌入式的,占用资源非常的低,只需要几百K的内存就够了。SQLite已经被多种软件和产品使用,Mozilla FireFox就是使用SQLite来存储配置数据的,Android和iPhone都是使用SQLite来存储数据的。
SQLite数据库是D.Richard Hipp用C语言编写的开源嵌入式数据库,支持的数据库大小为2TB。它具有如下特征:
1、轻量级
SQLite和C\S模式的数据库软件不同,它是进程内的数据库引擎,因此不存在数据库的客户端和服务器。使用SQLite一般只需要带上它的一个动态库,就可以享受它的全部功能。而且那个动态库的尺寸也相当小。
2、独立性
SQLite数据库的核心引擎本身不依赖第三方软件,使用它也不需要“安装”,所以在使用的时候能够省去不少麻烦。
3、隔离性
SQLite数据库中的所有信息(比如表、视图、触发器)都包含在一个文件内,方便管理和维护。
4、跨平台
SQLite数据库支持大部分操作系统,除了我们在电脑上使用的操作系统之外,很多手机操作系统同样可以运行,比如Android、Windows Mobile、Symbian、Palm等。
5、多语言接口
SQLite数据库支持很多语言编程接口,比如C\C++、Java、Python、dotNet、Ruby、Perl等,得到更多开发者的喜爱。
6、安全性
SQLite数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。在某个进程或线程向数据库执行写操作之前,必须获得独占锁定。在发出独占锁定后,其他的读或写操作将不会再发生。
三、安卓数据库常用类
1、SqliteOpenHelper是一个抽象类,来管理数据库的创建和版本的管理。要使用它必须实现它的onCreate(SQLiteDatabase),onUpgrade(SQLiteDatabase, int, int)方法。
常用方法:
onCreate( )//当数据库第一次被建立的时候被执行,例如创建表,初始化数据
onUpgrade()//当数据库需要被更新的时候执行,例如删除久表,创建新表
Close()//关闭任何打开的数据库
String getDatabaseName( )//获取数据库的名字
getWritableDatabase( ) //创建和/或打开一个数据库,将被用于读和写操作。
getReadableDatabase()//创建或打开一个数据库,该方法首先会调用
getWritableDatabase方法以读写方式打开数据,如果存放数据库的磁盘空间满了,
就会再以只读方式打开数据库。
2、SQLiteDatabase类它封装了一些操作数据库的API。使用它能实现基本的CRUD操作,通过getWritableDatabase()和getReadableDatabase()可以获取数据库实例。
常用方法:
deleteDatabase(File file)//删除数据库
getPageSize()//获取数据库页大小
getPath()//获取数据库文件路径
getVersion()//获取数据库版本
insert()//插入
delete()//删除
query()//查询
update()//更新
isOpen()//判断当前数据库是否
isReadOnly()//判断数据库是否只读
rawQuery()//查询,可以查询结果集通过结果集可以遍历获取表中的内容
execSQL(string s)//可以执行增加、删除、修改操作。【不推荐使用】。
四、用execSQL()方法实现数据库的曾加、删除、修改操作。
execSQL()方法的缺点:直接写sql语句容易写错,增删改没有返回值,无法确定是否执行成功。
示例:
public class CurdDao {
private MyOpenHelper myOpenHelper;
public CurdDao(Context context) {
myOpenHelper = new MyOpenHelper(context);
}
//构造方法可以初始化成员变量,也可以放置一些公共的方法,在创建对象时直接初始化
public void add(UserBean user){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//?是占位符,防止sql注入
String sql = "insert into info(name, phone) values(?, ?)";
//参数1:sql语句,参数2:sql语句中占位符的值
db.execSQL(sql, new Object[]{user.name, user.phone});
db.close();
}
//通过名字删除,也可以通过其他字段删除
public void del(String name){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//?是占位符,防止sql注入
String sql = "delete from info where name=?";
//参数1:sql语句,参数2:sql语句中占位符的值
db.execSQL(sql, new Object[]{name});
db.close();
}
//更新名字和电话号码
public void update(UserBean user){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//?是占位符,防止sql注入
String sql = "update info set phone=? where name=?";
//参数1:sql语句,参数2:sql语句中占位符的值
db.execSQL(sql, new Object[]{user.phone, user.name});
db.close();
}
//根据name查询
public void query( ){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//?是占位符,防止sql注入
String sql = "select name,phone from info";
//查询语句:参数1:sql语句,参数2:选择数组,返回游标对象
Cursor cursor = db.rawQuery(sql, null);
//判断表是否为空,是否有下一条数据
if (cursor!=null && cursor.getCount()>0) {
//循环遍历游标对象判断是否有下一行数据
while (cursor.moveToNext()) {
//获取索引为0的数据,name
String name = cursor.getString(0);
//获取索引为1的数据,phone
String phone = cursor.getString(1);
System.out.println(name+" : "+phone );
}
}
//关闭游标
cursor.close();
//关闭数据库
db.close();
}
}
五、使用Insert、delete、update、query方法实现数据库的插入、曾加、删除、修改操作。
优点:写sql语句不容易出错,增删改有返回值
缺点:查询不灵活,尤其是多表查询
示例:
public class CurdDao {
private MyOpenHelper myOpenHelper;
public CurdDao(Context context) {
myOpenHelper = new MyOpenHelper(context);
}
//构造方法可以初始化成员变量,也可以放置一些公共的方法,在创建对象时直接初始化
public boolean add(UserBean user){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//创建ContentValues对象,用来存放表数据<键,值>方式存储
//参数1:表名, 参数2:,参数3:要添加的值【ContentValues类型的对象】
ContentValues values = new ContentValues();
//底层实现了对HashMap的操作
values.put("name", user.name);
values.put("phone", user.phone);
//返回插入的行号,如果返回-1,表示插入失败
long result = db.insert("info", null, values);
//insert语句底层拼装sql语句
db.close();
if (result == -1) {
return false;
}else {
return true;
}
}
//通过名字删除,也可以通过其他字段删除
public int del(String name){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//参数1:表名 ,参数2:删除条件 ,参数3:删除条件占位符参数
int resurt = db.delete("info", "name = ?", new String[]{name});
db.close();
//返回删除成功的行数
return resurt;
}
//更新名字和电话号码
public int update(UserBean user){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//参数1:表名,参数2:要修改的键值对,参数3:更新条件,
参数4:更新占位符的参数数组
//参数2的类型:ContentValues,底层实现了对HashMap的操作
ContentValues values = new ContentValues();
//底层实现了对HashMap的操作
values.put("phone", user.phone);
int resurt = db.update("info", values, "name=?",
new String[]{user.name});
db.close();
//返回成功修改的行数
return resurt;
}
//根据name查询
public void query( ){
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
/**
* 参数1:要查询的表名
* 参数2:要查询的列数,如果传null表示默认查询所有列[String[] columns]
* 参数3:查询条件
* 参数4:查询条件占位符
* 参数5:按什么分组
* 参数6:分组条件
* 参数7:排序
*/
Cursor cursor = db.query("info", new String[]{"name", "phone"},
null, null, null, null, null);
if (cursor!=null && cursor.getCount()>0) {
//循环遍历游标对象判断是否有下一行数据
while (cursor.moveToNext()) {
//获取索引为0的数据,name
String name = cursor.getString(0);
//获取索引为1的数据,phone
String phone = cursor.getString(1);
System.out.println(name+" : "+phone );
}
}
//关闭游标
cursor.close();
//关闭数据库
db.close();
}
}
六、数据库的事务
事务:要么多条sql语句同时成功执行,要么同时失败
事物具有回滚机制
银行转账【同生共死】
示例代码:
//事物
public void transtation(View v){
//创建数据库打开帮助类对象
BankOpenHelper openHelper = new BankOpenHelper(mContext);
//通过帮助类对象获取数据库操作对象
SQLiteDatabase db = openHelper.getReadableDatabase();
//开启事物
db.beginTransaction();
try {
//转账【多条相关的SQL语句一起执行】
db.execSQL("update account set money= money-200 where name=?",new String[]{"李四"});//更新表操作
db.execSQL("update account set money= money+200 where name=?",new String[]{"张三"});//更新表操作
//执行到这行,表示事物已经成功执行
db.setTransactionSuccessful();
} finally {
//结束事物
db.endTransaction();
}
}