Android开发-之SQLite数据库
之前我们讲了如何将数据存储在文件中,那么除了这种方式呢,就是我们常见的大家都知道的将数据存储在数据库当中了。
将数据存储在数据库中的优势:
1)存储在数据库中的数据更加方便操作,比如增、删、改、查等
2)可以实现事务的回滚,比如银行转账等
3)方便维护,可读性高
4)资源占用少,性能高
5)……
SQLite数据库在我们日常生活中随处不见了,比如我们的手机~现在市场上的手机都是用SQLite数据库作为数据的存储的。
以及我们常看见的智能家居,也是用SQLite数据库去记录数据的。以及我们经常用到的桌面程序,比如QQ、迅雷等。
一、SQLite数据库概念及优缺点
SQLite数据库是一套开源的嵌入式数据库引擎,它的每个数据库都是以单个文件的形式存在
这些数据以B-Tree的数据结构的形式存储在磁盘上面。
SQLite数据库就是一个很小的、可以直接打开运行的文件,而其他的数据库都是一个大型的应用程序。
使用SQLite的优势:
1、SQLite支持大多数的sql标准语句
增、删、改、查、事务等等,所以这里就不详细的说这个了……
2、轻量级
可以说是袖珍型,然而小小的SQLite却可以支持高达2TB大小的数据库
3、检索速度快
4、动态数据模型(弱类型)
SQLite数据库支持
NULL:空值
INTEGER:整数型
REAL:浮点型
TEXT:字符串文本
BLOB:二进制对象
5个基本数据类型。
之所以称之为“弱类型”,是因为插入数据的时候不管是什么数据类型都会自动的转化。
注意:当INTEGER的约束为PRIMARY KEY时,就必须是整数不会自动转换,否则就会报错!
5、SQLite数据库在使用前不需要安装配置,也不需要启用进程来启动、关闭数据库
6、占用系统资源少
7、跨平台
它可以在多个操作系统下使用而不需要针对某一个操作系统独立编写代码,也就是说它在各各操作系统的数据层是相同的;
同时也是SQLite数据库内在机制决定的,SQL数据库是运行在SQLite虚拟机上面的,
在虚拟机上面会直接转编译成不同操作系统的数据模型。
SQLite的缺陷在于:
1、不支持大型项目
2、一部分SQL标准语句不支持,但是这些语句一般不会用到……
3、安全性相对于其他大型数据库差
就要比我们的Android手机,只要获取到root权限,那么也就是证明可以为所欲为了……
那么Android怎么来加强它的安全性呢?
a、提高程序的安全验证
b、加强代码的严谨性
c、权限管理
介于SQLite数据库的优势,很多的桌面应用程序都用它来存储该应用程序的数据;
当然,我们的Android以及iPhone的产品链也几乎都是运用SQLite数据库。
二、Android中的实现
1、使用原生的方法对数据库进行简单的操作
也就是直接写SQL代码
a、定义一个方法,继承SQLiteOpenHelper类。并实现onCreate和onUpgrade方法,重写自定义的方法。
重写自定义的方法:
1)参数有很多,那么这里简单的只需要context参数就好了。
2)super参数:
context:上下文
name:数据库名称
factory:目的创建cursor对象
version:数据库版本,一般从1开始
onCreate方法:
1)当数据库第一次创建时使用,如果是其次的就是打开
2)适合做表结构的初始化
onUpgrade方法:
1)当数据库的版本升级时使用
2)适合做表结构的更新
execSQL:
要执行的sql语句,这里适用于增、删、改
public class MyOpenHelper extends SQLiteOpenHelper { /**
*
* @param context 上下文
* name 数据库的名称
* factory 目的创建cursor对象
* version 数据库版本 从1开始
*/
public MyOpenHelper(Context context) {
super(context, "test_1.db", null, 3);
} /**
* 当数据库第一次创建是使用
* 这个方法特别适合做表结构的初始化 创建表就是写sql语句
*/
@Override
public void onCreate(SQLiteDatabase db) { db.execSQL("create table test_info(id integer primary key autoincrement,name varchar(20))");
} /**
* 当数据库版本升级时使用
* 这个方法适合做表结构的更新
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("alter table test_info add phone varchar(20)");
} }
b、必须要注意数据库的降级onDowngrade,降级的设计关键点
1)考虑云端要保存用户【自定义数据、行为习惯】。专业术语profile-->>提高用户黏度
2)考虑当前的最低版本要求-->>降低维护成本
3)尽可能本地的数据转移(所有新版本,都不删除字段)-->尽可能把未知变已知
4)降级很可能会失败,所以我们一般 try-catch;当降级成功就是try块的语句,失败之后就执行catch块的语句
5)SQLiteDatabase(执行语句)、oldVersion(老版本号)、newVersion(新版本号)
/* 模拟从3.0 降低会2.0 */
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//正常来讲大于2.0的,应该有test_info 这张表,且2.0有的字段,3.0都有
try {
//第一、先把test_info 未来的表,改名
String rename_sql = "alter table test_info rename to test_info_bak";
db.execSQL(rename_sql);
Log.i("down", "1.改名成功");
//第二、建立2.0的表结构
String sql_message = "create table test_info (id int primary key,tou1 varchar(50),userName varchar(50),
lastMessage varchar(50),datetime varchar(50))";
db.execSQL(sql_message);
Log.i("down", "2.建立2.0表结构成功");
//第三、把备份的数据,copy到 新建的2.0的表
String sql_copy = "insert into test_info select id,tou1,userName,lastMessage,datetime from test_info_bak";
db.execSQL(sql_copy);
Log.i("down", "3.copy到用户数据到 2.0的表");
//第四、把备份表drop掉
String drop_sql = "drop table if exists test_info_bak";
db.execSQL(drop_sql);
Log.i("down", "4.把备份表drop掉"); } catch (Exception e) {
//失败
Log.i("hi", "降级失败,重新建立");
String sql_drop_old_table = "drop table if exists test_info";
String sql_message = "create table test_info(id integer primary key autoincrement,name varchar(20),phone varchar(20))";
String sql_init_1 = "insert into test_info values (1,'abc','130000')";
String sql_init_2 = "insert into test_info values (2,'abc','134444')";
db.execSQL(sql_drop_old_table);
db.execSQL(sql_message);
db.execSQL(sql_init_1);
db.execSQL(sql_init_2);
}
}
c、创建MyOpenHelper对象
myOpenHelper = new MyOpenHelper(getApplicationContext()); //打开或是创建数据库 如果第一次就是创建,其次就是打开
//SQLiteDatabase sqliteDatabase = myOpenHelper.getWritableDatabase();
//打开或是创建数据库 如果第一次就是创建,其次就是打开 如果磁盘满了就返回只读
//SQLiteDatabase sqliteDatabase = myOpenHelper.getReadableDatabase();
d、增加数据
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//执行添加一条sql语句
db.execSQL("insert into test_info(name,phone) values(?,?)",new Object[]{"zhangsan","138888888"});
//数据库用完要关闭
db.close();
e、删除数据
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
db.execSQL("delete from test_info where name=?",new Object[]{"zhangsan"});
db.close();
f、修改数据
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
db.execSQL("updata test_info set phone=? where name=?",new Object[]{"13777777777","zhangsan"});
db.close();
g、查询数据
SQLiteDatabase db = myOpenHelper.getWritableDatabase(); Cursor cursor = db.rawQuery("select * from test_info", null); if(cursor!=null&&cursor.getCount()>0){
while(cursor.moveToNext()){
//columnIndex代表列的索引
String name = cursor.getString(1);
String phone = cursor.getString(2);
}
}
2、使用Google封装好的api对数据进行简单操作
Google工程师给我们封装好了的一些方法让我们直接调用,但是其实在底层也就是将这些字符串进行拼接成完整的sql语句。
a、增加数据
ContentValues 内部封装好的一个map集合,map集合是以<key,value>的形式存储数据的。
insert参数说明
table:表名
key:对应列的名字
value:对应的值
put参数说明
key:增加的列名字
value:对应的值
//获取数据库对象
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
/**
* table 表名
* ContentValues 内部封装了一个map
* key:对应列的名字
* value:对应值
*/
ContentValues values = new ContentValues();
values.put("name", "wangwu");
values.put("phone", "120");
//返回值代表插入新行的id
long insert = db.insert("test_info", null, values);//底层就是在拼接SQL语句
//数据库用完要关闭
db.close(); if(insert>0){
Toast.makeText(getApplicationContext(), "添加成功!", 3000).show();
}else{
Toast.makeText(getApplicationContext(), "添加失败!", 3000).show();
}
b、删除数据
delete参数说明
table:表名
whereClause:要删除的是哪一列,根据什么删除
whereArgs:这里返回的是一个数组对象,根据删除列的值
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//根据Google封装好的api删除
int delete = db.delete("test_info", "name=?", new String[]{"wangwu"});
db.close();
Toast.makeText(getApplicationContext(), "删除了"+delete+"行", 2000).show();
c、修改数据
update参数说明
table:表名
value:就是ContentValues中的value
whereClause:要修改的是哪一列,根据什么修改
whereArgs:这里返回的是一个数组对象,根据修改列的值
SQLiteDatabase db = myOpenHelper.getWritableDatabase(); //根据Google封装好的api修改
ContentValues value = new ContentValues();
value.put("phone", "110");
//代表更新了多少行
int updata = db.update("test_info", value, "name=?", new String[]{"wangwu"});
db.close();
Toast.makeText(getApplicationContext(), "更新了"+updata+"行", 2000).show();
d、查询数据
query参数说明
table:表名
columns:查询的列
selection:根据什么查询
selectionArgs:查询的条件的值
groupBy:分组
having:查询条件,这里要区分having与where的区别!
orderBy:排序
moveToNext():遍历数据表中的数据
cursor:Google工程师封装好的指针对象,用于遍历集合下标
SQLiteDatabase db = myOpenHelper.getWritableDatabase(); /**
* 根据Google封装好的api查询
* columns 代表你要查询的列
* selection 根据什么查询phone
*/
Cursor cursor = db.query("test_info", new String[]{"phone"}, "name=?", new String[]{"wangwu"}, null, null, null); if(cursor!=null&&cursor.getCount()>0){
while(cursor.moveToNext()){
String phone = cursor.getString(0);
System.out.println("phone:" + phone);
}
}
3、使用原生方法与封装好的api方法的优缺点
a、原生方法优点
1)可以更加灵活运用sql语句
2)代码量可以减少,效率更高
b、原生方法缺点
1)容易写错sql代码
2)不好维护
c、封装好的优点
1)不用直接写sql语句,减少了错误的概率
2)方便维护
d、封装好的缺点
1)使程序更加笨重,效率低
2)不方便数据的操作,不能灵活运用数据的操作语句
不管是使用哪一种方法,都有它的好处和坏处,所以在实际开发中视实际情况而定,想用什么方法也都是可行的。
建议:比较小型的程序推荐使用封装好的api,比较简单,可以提高开发效率
比较大型的程序推荐使用原生方法,比较灵活,也可以提高程序效率
三、总结
1、使用SQLite的优缺点
2、数据库的升级和降级(*****)
3、使用原生方法对数据库进行简单操作
4、使用Google封装好的api对数据库进行简单操作
5、各自的优缺点
6、Android和iPhone产品链的数据层是一样的
ps:感兴趣的同学可以想想微信:
在客户端的SQLite是怎么去实现的?
在后台服务器使用什么去实现的,又是如何实现的?
那么又要做到这些数据的交互呢?
又是怎样去优化的呢?
Android开发-之SQLite数据库的更多相关文章
- Android 开发中 SQLite 数据库的使用
SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP, ...
- Android开发学习——SQLite数据库与单元测试
SQLite数据库 轻量级关系型数据库 创建数据库需要使用的api:SQLiteOpenHelper public class Myopenhelper extends SQLiteOpenHelp ...
- Android开发--adb,SQLite数据库运用
一.玩转adb adb的全称为Android Debug Bridge,就是起到调试桥的作用. adb有什么用?:借助adb工具,我们可以管理设备或手机模拟器的状态.还可以进行很多手机操作,如安 ...
- Android 开发笔记 “Sqlite数据库删除”
1.代码方式 Context.deleteDatabase(String databaseName);//删除某一数据库 2.设置里面 进入应用程序 ,然后清除数据就ok了
- 从零开始学android开发-查看sqlite数据库
C:\Users\Administrator>cd E:\ProSoft\adt-bundle-windows-x86-20140321\sdk\platform-tools
- Android版本升级同时Sqlite数据库的升级及之前数据的保留
http://www.cnblogs.com/wang340/archive/2013/05/06/3063135.html http://www.eoeandroid.com/forum.php?m ...
- Android存储之SQLite数据库
Android存储之SQLite数据库数据库 创建数据库 package --; import android.content.Context; import android.database.sql ...
- Android基础总结+SQlite数据库【申明:来源于网络】
Android基础总结+SQlite数据库[申明:来源于网络] 基础总结篇之一:Activity生命周期:http://blog.csdn.net/liuhe688/article/details/6 ...
- Android 开发笔记 “Sqlite Cursor 使用”
使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生,如果你是搞.net 开发你大可以把Cursor理解成 Ado.net 中的数据集合相当于dataReader.今天特地将它单独拿出来谈, ...
随机推荐
- 技能收获与C语言学习
你有什么技能比大多人(超过90%以上)更好? 我会的东西很多,喜欢的东西太多,但是很遗憾广而不专,会而不精.学了很多东西我都是为了娱乐,因为以前我们那里过于强调学习,很多爱好也都被扼杀在摇篮里.我觉得 ...
- 记录同事的一个bug-ajax-413错误-fullhead
症状表现为在form下面的textarea里的字符数只有几十个的时候,请求可以成功,但是如果有几百字,则会出现413错误,提示fullhead,我第一反应是cookie体积太小,但是清了缓存还是一样的 ...
- BZOJ2498 : Xavier is Learning to Count
考虑容斥,通过$Bell(p)$的时间枚举所有等价情况. 对于一种情况,强制了一个等价类里面的数都要相同,其它的可以相同也可以不同. 这方案数显然可以通过多项式乘法求得,乘上容斥系数$(-1)^{p- ...
- 0_MVC+EF+Autofac(dbfirst)轻型项目框架_基本框架
前言 原来一直使用他人的开源项目框架,异常的定位会很麻烦,甚至不知道这个异常来自我的代码还是这个框架本身.他人的框架有一定的制约性,也有可能是我对那些框架并没深入了解,因为这些开源框架在网上也很难找到 ...
- 解决jquery新加入的元素没有绑定事件问题
在使用jquery操作时,往往需要动态的添加一些元素,但是这些新加入的元素并没有像css那样被赋予原本定义的样式,解决方法如下: 1.动态插入元素后,并用bind事件给新加入的元素绑定事件. 2.如果 ...
- 弱省互测#2 t2
题意 给两个树,大小分别为n和m,现在两棵树各选一些点(包括1),使得这棵树以1号点为根同构(同构就是每个点的孩子数目相同),求最大的同构树.(n, m<=500) 分析 我们从两棵树中各取出一 ...
- C语言与java 20155317 王新玮第二次
20155317 王新玮第二次写作感想 你有什么技能比大多数人(超过90%以上)更好? 刚刚看到这个题目,我的首先想到的是会一些中医,懂得中医的理论框架知识,懂得大部分的中医脉象,能够解决日常生活 ...
- 内存不足时,调用ajax报的错
在error中遍历出来的异常 很难见
- Oracle入门
一.Oracle数据库简介 Oracle数据库的主要特点 :支持多用户.大事务量的事务处理:数据安全性和完整性控制:支持分布式数据处理:可移植性. Oracle数据库基于客户端/服务器技术:数据库服务 ...
- Sage Crm 权限原理分析
文字是11年写的,贴出来共享一下,先来一张表结构图: 一.区域.表名:[territories] 1.我们先来看看区域表的结构. 从图中前面都是不能为空的字段,都是很重要的.来介绍一下这些字段: Te ...