SQLite数据库存储

SQLite数据库存储

  • 应用运行需要保存一系列有一定结构的数据, 比如说公司员工信息
  • 文件类型: .db
  • 数据保存的路径: /data/data/projectPackage/databases/xxx.db
  • 默认情况下其它应用不能访问, 当前应用可以通过ContentProvider提供其它应用操作
  • 应用卸载时会删除此数据

 

SQLite (http://www.sqlite.org/),是一款轻型的关系型数据库服务器, 移动设备的数据库存储都使用SQLite, 它的特点:

  • 安装文件小: 最小只有几百K, Android系统已经安装
  • 支持多操作系统: Android, WP, IOS, Windows, Linux等
  • 支持多语言: 比如 Java 、 PHP、C#等.
  • 处理速度快:  处理速度比Mysql, Oracle, SqlServer都要快(数据量不是特别大)
  • Sqlite中的一个数据库就是一个.db文件(本质上.db的后缀都可以不指定)

Sqlite数据库客户端

 

 

 

 

 

 

 

 

Sqlite数据库命令行

 

  • adb shell  进入系统根目录
  • cd data/data/…/databases : 进入包含数据库文件的文件夹下
  • sqlite3 contacts2.db : 使用sqlite3命令连接指定的数据库文件, 进入连接模式
  •  .help : 查看命令列表
  • .tables : 查看所有表的列表
  • 执行insert/delete/update/select语句
  • .exit : 退出数据库连接模式
  • Ctrl + C : 直接退出sell模式

 

 

数据类型

  • Sqlite支持的数据类型与Mysql相似, 常用的数据类型
    • INT/INTEGER : 整数
    • FLOAT/DOUBLE : 小数
    • CHAR/VARCHAR/TEXT : 字符串文本
    • BLOB : 文件
    • DATE/ DATETIME : 日期/日期时间



Sqlite
建表

  • Sqlite操作数据库的sql语句基本与mysql一样,  但需要注意下面2个点:
    • 最大的不同在于创建表时可以不用指定字段类型, Sqlite可以适时的自动转换, 但除varchar类型外最好指定类型
    • Sqlite中的主键最名称建议使用_id


  • create table employee (
  •        _id integer primary key autoincrement, /*主键,自增长*/
  •        name varchar,                /*字符串*/
  •        salary double,                                /*小数*/
  •        birthday date                                /*日期, 可直接插入日期格式字符串*/
  • )

 

 

Sqlite的CRUD语句

/*插入*/

INSERT INTO employee (name,salary,birthday) VALUES('Tom', 8000, '1988-09-21');

/*删除*/

DELETE FROM employee WHERE _id=2

/*更新*/

UPDATE employee SET name='Jack',salary=salary+1000 WHERE _id=1

/*查找*/

SELECT * FROM employee where _id=3

 

 

 

 

 

相关API

  • SQLiteOpenHelper: 数据库操作的抽象帮助类

   

      SQLiteOpenHelper(Context context, String name,

           CursorFactory factory, int version) : 构造方法, 指定数据库文件名和版本号

      abstract void onCreate(SQLiteDatabase db) : 用于创建表

      abstract void onUpgrade() : 用于版本更新

      SqliteDatabase getReadableDatabase() : 得到数据库连接

 

 

 

 

  • SqliteDatabase: 代表与数据库的连接的类

  

      long insert(): 用于执行insert SQL, 返回id值

       int update(): 用于执行update SQL

       int delete(): 用于执行delete SQL

       Cursor query(): 用于执行select SQL, 返回包含查询结果数据的Cursor

       void execSql(sql) : 执行sql语句

    

       beginTransaction(): 开启事务

       setTransactionSuccessful(): 设置事务是成功的

       endTransaction(): 结束事务, 可能提交事务或回滚事务

       openDatabase(String path, CursorFactory factory, int flags):  得到数据库连接

 

 

  • Cursor : 包含所有查询结果记录的结果集对象(光标,游标)

      

                int getCount() : 匹配的总记录数

       boolean moveToNext() : 将游标移动到下一条记录的前面

       Xxx getXxx(columnIndex) : 根据字段下标得到对应值

       int getColumnIndex(columnname): 根据字段名得到对应的下标

 

 

测试用例

  1. 数据库的创建
  2. 数据库的版本更新
  3. 表数据的CRUD
  4. 数据库事务

 

 

1. 界面布局

       ListView

2. DBHelper

       数据库

       表

3. 实体类

4. DAO并单元测试

5. 显示列表

6. 添加

       1. 显示添加的dialog(带输入框)

       2. 在确定的回调方法实现:

              1). 保存数据表中

              2). 保存数据到List

              3). 通知更新列表

       问题1: 新添加的没有显示在第一行

              add到集合中的第一位

       问题2: 初始显示的列表顺序不对

              查询根据_id倒序

7. 删除

       1. 显示ContextMenu

       2. 响应对item的选择

              1). 删除数据表对应的数据

              2). 删除List对应的数据

              3). 通知更新列表

       问题: 如何得到长按的position?     

8. 更新

       1. 显示更新的Dialog

       2. 点击确定的响应

              1). 更新数据表对应的数据

              2). 更新List对应的数据

              3). 通知更新列表

 

9. 使用ListActivity优化功能

       1. extends ListActivity

       2. 布局文件中的<ListView>的id必须是系统定义的id: list

       3. 如果想在没有数据时显示一个提示文本, 可以在布局中定义 一个<TextView>(id必须为empty)

 

/*

一个功能的主要工作

*/

       1. 内存的操作(集合)

       2. 存储的操作(sp/数据库/文件)

       3. 界面的操作(列表)

 

 

package com.atguigu.l04_datastorage;

 

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

import android.util.Log;

 

/**

 * 数据库操作的帮助类

 * @author 侯志强

 *

 */

public class DBHelper extends SQLiteOpenHelper {

 

       public DBHelper(Context context,int version) {

              super(context, "atguigu.db", null, version);

       }

 

       /**

        * 什么时候才会创建数据库文件?

        *   1). 数据库文件不存在

        *  2). 连接数据库

        *

        * 什么时候调用?

        *   当数据库文件创建时调用(1次)

        * 在此方法中做什么?

        *   建表

        *   插入一些初始化数据

        */

       @Override

       public void onCreate(SQLiteDatabase db) {

              Log.e("TAG", "DBHelper onCreate()");

              //建表

              String sql = "create table person(_id integer primary key autoincrement, name varchar,age int)";

              db.execSQL(sql);//执行SQL语句

              //插入一些初始化数据

              db.execSQL("insert into person (name, age) values ('Tom1', 11)");

              db.execSQL("insert into person (name, age) values ('Tom2', 12)");

              db.execSQL("insert into person (name, age) values ('Tom3', 13)");

       }

 

       //当传入的版本号大于数据库的版本号时调用

       @Override

       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

              Log.e("TAG", "DBHelper onUpgrade()");

       }

 

}

 

 

 

package com.atguigu.l04_datastorage;

 

import android.app.Activity;

import android.content.ContentValues;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Toast;

 

/**

 * 测试Sqlite数据库存储

 *

 * @author 侯志强

 *

 */

public class DBActivity extends Activity {

 

       @Override

       protected void onCreate(Bundle savedInstanceState) {

              super.onCreate(savedInstanceState);

              setContentView(R.layout.activity_db);

       }

 

       /*

        * 创建库

        */

       public void testCreateDB(View v) {

              DBHelper dbHelper = new DBHelper(this, 1);

              //获取连接

              SQLiteDatabase database = dbHelper.getReadableDatabase();

             

              Toast.makeText(this, "创建数据库", 0).show();

       }

 

       /*

        * 更新库

        */

       public void testUpdateDB(View v) {

              DBHelper dbHelper = new DBHelper(this, 2);

              //获取连接

              SQLiteDatabase database = dbHelper.getReadableDatabase();

             

              Toast.makeText(this, "更新数据库", 0).show();

       }

 

       /*

        * 添加记录

        */

       public void testInsert(View v) {

              //1. 得到连接

              DBHelper dbHelper = new DBHelper(this, 2);

              SQLiteDatabase database = dbHelper.getReadableDatabase();

              //2. 执行insert  insert into person(name, age) values('Tom', 12)

              ContentValues values = new ContentValues();

              values.put("name", "Tom");

              values.put("age", 12);

              long id = database.insert("person", null, values);

              //3. 关闭

              database.close();

              //4. 提示

              Toast.makeText(this, "id="+id, 1).show();

       }

 

       /*

        * 更新

        */

       public void testUpdate(View v) {

              DBHelper dbHelper = new DBHelper(this, 2);

              SQLiteDatabase database = dbHelper.getReadableDatabase();

              //执行update  update person set name=Jack, age=13 where _id=4

              ContentValues values = new ContentValues();

              values.put("name", "jack");

              values.put("age", 13);

              int updateCount = database.update("person", values , "_id=?", new String[]{"4"});

              database.close();

              Toast.makeText(this, "updateCount="+updateCount, 1).show();

       }

 

       /*

        * 删除

        */

       public void testDelete(View v) {

              // 1. 得到连接

              DBHelper dbHelper = new DBHelper(this, 2);

              SQLiteDatabase database = dbHelper.getReadableDatabase();

              // 2. 执行delete delete from person where _id=2

              int deleteCount = database.delete("person", "_id=2", null);

              // 3. 关闭

              database.close();

              // 4. 提示

              Toast.makeText(this, "deleteCount=" + deleteCount, 1).show();

       }

 

       /*

        * 查询

        */

       public void testQuery(View v) {

              // 1. 得到连接

              DBHelper dbHelper = new DBHelper(this, 2);

              SQLiteDatabase database = dbHelper.getReadableDatabase();

              // 2. 执行query select * from person

              Cursor cursor = database.query("person", null, null, null, null, null, null);

              //cursor = database.query("person", null, "_id=?", new String[]{"3"}, null, null, null);

              //得到匹配的总记录数

              int count = cursor.getCount();

             

              //取出cursor中所有的数据

              while(cursor.moveToNext()) {

                     //_id

                     int id = cursor.getInt(0);

                     //name

                     String name = cursor.getString(1);

                     //age

                     int age = cursor.getInt(cursor.getColumnIndex("age"));

                     Log.e("TAG", id+"-"+name+"-"+age);

              }

              // 3. 关闭

              cursor.close();

              database.close();

              // 4. 提示

              Toast.makeText(this, "count=" + count, 1).show();

       }

 

       /*

        * 测试事务处理

        * update person set age=16 where _id=1

        * update person set age=17 where _id=3

        *

        * 一个功能中对数据库进行的多个操作: 要就是都成功要就都失败

        * 事务处理的3步:

        * 1. 开启事务(获取连接后)

        * 2. 设置事务成功(在全部正常执行完后)

        * 3. 结束事务(finally中)

        */

       public void testTransaction(View v) {

             

              SQLiteDatabase database = null;

              try{

                     DBHelper dbHelper = new DBHelper(this, 2);

                     database = dbHelper.getReadableDatabase();

                    

                     //1. 开启事务(获取连接后)

                     database.beginTransaction();

                    

                     //执行update  update person set age=16 where _id=1

                     ContentValues values = new ContentValues();

                     values.put("age", 16);

                     int updateCount = database.update("person", values , "_id=?", new String[]{"1"});

                     Log.e("TAG", "updateCount="+updateCount);

                    

                     //出了异常

                     boolean flag = true;

                     if(flag) {

                            throw new RuntimeException("出异常啦!!!");

                     }

                    

                     //执行update  update person set age=17 where _id=3

                     values = new ContentValues();

                     values.put("age", 17);

                     int updateCount2 = database.update("person", values , "_id=?", new String[]{"3"});

                     Log.e("TAG", "updateCount2="+updateCount2);

                    

                     //2. 设置事务成功(在全部正常执行完后)

                     database.setTransactionSuccessful();

                    

              } catch(Exception e) {

                     e.printStackTrace();

                     Toast.makeText(this, "出异常啦!!!", 1).show();

              } finally {

                     //3. 结束事务(finally中)

                     if(database!=null) {

                            database.endTransaction();

                            database.close();

                     }

              }

            

       }

 }

posted @ 2016-10-08 23:23  RazorH  阅读(401)  评论(0编辑  收藏  举报