之前我们讲了如何将数据存储在文件中,那么除了这种方式呢,就是我们常见的大家都知道的将数据存储在数据库当中了。

  将数据存储在数据库中的优势:

    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数据库的更多相关文章

  1. Android 开发中 SQLite 数据库的使用

    SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP, ...

  2. Android开发学习——SQLite数据库与单元测试

    SQLite数据库 轻量级关系型数据库 创建数据库需要使用的api:SQLiteOpenHelper  public class Myopenhelper extends SQLiteOpenHelp ...

  3. Android开发--adb,SQLite数据库运用

    一.玩转adb  adb的全称为Android Debug Bridge,就是起到调试桥的作用.   adb有什么用?:借助adb工具,我们可以管理设备或手机模拟器的状态.还可以进行很多手机操作,如安 ...

  4. Android 开发笔记 “Sqlite数据库删除”

    1.代码方式 Context.deleteDatabase(String databaseName);//删除某一数据库 2.设置里面 进入应用程序 ,然后清除数据就ok了

  5. 从零开始学android开发-查看sqlite数据库

    C:\Users\Administrator>cd E:\ProSoft\adt-bundle-windows-x86-20140321\sdk\platform-tools

  6. Android版本升级同时Sqlite数据库的升级及之前数据的保留

    http://www.cnblogs.com/wang340/archive/2013/05/06/3063135.html http://www.eoeandroid.com/forum.php?m ...

  7. Android存储之SQLite数据库

    Android存储之SQLite数据库数据库 创建数据库 package --; import android.content.Context; import android.database.sql ...

  8. Android基础总结+SQlite数据库【申明:来源于网络】

    Android基础总结+SQlite数据库[申明:来源于网络] 基础总结篇之一:Activity生命周期:http://blog.csdn.net/liuhe688/article/details/6 ...

  9. Android 开发笔记 “Sqlite Cursor 使用”

    使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生,如果你是搞.net 开发你大可以把Cursor理解成 Ado.net 中的数据集合相当于dataReader.今天特地将它单独拿出来谈, ...

随机推荐

  1. java 随机获取国内IP

    /* * 随机生成国内IP地址 */ public static String getRandomIp(){ //ip范围 int[][] range = {{607649792,608174079} ...

  2. JSTL标签库

    JSP页面作为内嵌java的Html简化了Servlet在控制页面显示的语法,但JSP脚本中的表达式功能不够强大,语法也稍显繁杂,EL(Expression Language)表达式语言的出现能够大大 ...

  3. HTML5 学习笔记(二)——HTML5新增属性与表单元素

    目录 一.HTML5新增属性 1.1.contextmenu 1.2.contentEditable 1.3.hidden 1.4.draggable 1.5.data-* 1.6.placehold ...

  4. XCode6.3上使用opencv教程(MacOSX 10.10)

    OpenCV 是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS操作系统上.它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Pyth ...

  5. mac osx 上面部署Django项目 apache+mysql+mod_wsgi

    1.安装Xcode command line tools 首先,编译mysql和Homebrew需要用到Xcode command line tools,所以首先安装command line tool ...

  6. eclipse下创建maven项目

    1.创建一个Java项目 1)File--->New--->Other--->Maven--->Maven Projet 2)选择maven-archetype-quickst ...

  7. overflow:hidden清除浮动原理

    overflow:hidden的意思是超出部分去掉,如果父元素height为auto,内部元素浮动,势必会将内部元素全部隐藏,故计算出内部浮动高度顺便清除浮动.

  8. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  9. @dynamic 模拟NSManagedObject类的内部实现,AFN的非常规用法

    @property和@synthesize复习 @property生成setter和getter的声明,同时生成属性对应的成员变量,并且前面加一个下划线_.如果将getter和setter的实现同时重 ...

  10. linux shell中不显示路径了,显示为-bash-4.1#的两种解决办法

    出现这个问题的原因是因为没有配置.bash_profile的问题,或者是我们不小心清空或删除了.bash_profile文件. 办法一:修改 ~/.bash_profile文件 步骤如下: vim ~ ...