首页 > 代码库 > SQLite数据库存储
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 INTOemployee (name,salary,birthday) VALUES(‘Tom‘, 8000, ‘1988-09-21‘);
/*删除*/
DELETE FROMemployee WHERE _id=2
/*更新*/
UPDATEemployee 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() : 匹配的总记录数
booleanmoveToNext() : 将游标移动到下一条记录的前面
XxxgetXxx(columnIndex) : 根据字段下标得到对应值
intgetColumnIndex(columnname): 根据字段名得到对应的下标
测试用例
- 数据库的创建
- 数据库的版本更新
- 表数据的CRUD
- 数据库事务
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;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* 数据库操作的帮助类
*@author 侯志强
*
*/
public class DBHelper extendsSQLiteOpenHelper {
publicDBHelper(Context context,int version) {
super(context,"atguigu.db", null, version);
}
/**
* 什么时候才会创建数据库文件?
* 1). 数据库文件不存在
* 2). 连接数据库
*
* 什么时候调用?
* 当数据库文件创建时调用(1次)
* 在此方法中做什么?
* 建表
* 插入一些初始化数据
*/
@Override
publicvoid onCreate(SQLiteDatabase db) {
Log.e("TAG","DBHelper onCreate()");
//建表
Stringsql = "create table person(_id integer primary key autoincrement, namevarchar,age int)";
db.execSQL(sql);//执行SQL语句
//插入一些初始化数据
db.execSQL("insertinto person (name, age) values (‘Tom1‘, 11)");
db.execSQL("insertinto person (name, age) values (‘Tom2‘, 12)");
db.execSQL("insertinto person (name, age) values (‘Tom3‘, 13)");
}
//当传入的版本号大于数据库的版本号时调用
@Override
publicvoid 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;
importandroid.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
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_db);
}
/*
* 创建库
*/
publicvoid testCreateDB(View v) {
DBHelperdbHelper = new DBHelper(this, 1);
//获取连接
SQLiteDatabasedatabase = dbHelper.getReadableDatabase();
Toast.makeText(this,"创建数据库",0).show();
}
/*
* 更新库
*/
publicvoid testUpdateDB(View v) {
DBHelperdbHelper = new DBHelper(this, 2);
//获取连接
SQLiteDatabasedatabase = dbHelper.getReadableDatabase();
Toast.makeText(this,"更新数据库",0).show();
}
/*
* 添加记录
*/
publicvoid testInsert(View v) {
//1.得到连接
DBHelperdbHelper = new DBHelper(this, 2);
SQLiteDatabasedatabase = dbHelper.getReadableDatabase();
//2.执行insert insert into person(name, age) values(‘Tom‘,12)
ContentValuesvalues = new ContentValues();
values.put("name","Tom");
values.put("age",12);
longid = database.insert("person", null, values);
//3.关闭
database.close();
//4.提示
Toast.makeText(this,"id="+id, 1).show();
}
/*
* 更新
*/
publicvoid testUpdate(View v) {
DBHelperdbHelper = new DBHelper(this, 2);
SQLiteDatabasedatabase = dbHelper.getReadableDatabase();
//执行update update person set name=Jack, age=13 where_id=4
ContentValuesvalues = new ContentValues();
values.put("name","jack");
values.put("age",13);
intupdateCount = database.update("person", values , "_id=?",new String[]{"4"});
database.close();
Toast.makeText(this,"updateCount="+updateCount, 1).show();
}
/*
* 删除
*/
publicvoid testDelete(View v) {
//1. 得到连接
DBHelperdbHelper = new DBHelper(this, 2);
SQLiteDatabasedatabase = dbHelper.getReadableDatabase();
//2. 执行deletedelete from person where _id=2
intdeleteCount = database.delete("person", "_id=2", null);
//3. 关闭
database.close();
//4. 提示
Toast.makeText(this,"deleteCount=" + deleteCount, 1).show();
}
/*
* 查询
*/
publicvoid testQuery(View v) {
//1. 得到连接
DBHelperdbHelper = new DBHelper(this, 2);
SQLiteDatabasedatabase = dbHelper.getReadableDatabase();
//2. 执行query select* from person
Cursorcursor = database.query("person", null, null, null, null, null,null);
//cursor= database.query("person", null, "_id=?", newString[]{"3"}, null, null, null);
//得到匹配的总记录数
intcount = cursor.getCount();
//取出cursor中所有的数据
while(cursor.moveToNext()){
//_id
intid = cursor.getInt(0);
//name
Stringname = cursor.getString(1);
//age
intage = 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中)
*/
publicvoid testTransaction(View v) {
SQLiteDatabasedatabase = null;
try{
DBHelperdbHelper = new DBHelper(this, 2);
database= dbHelper.getReadableDatabase();
//1.开启事务(获取连接后)
database.beginTransaction();
//执行update update person set age=16 where _id=1
ContentValuesvalues = new ContentValues();
values.put("age",16);
intupdateCount = database.update("person", values , "_id=?",new String[]{"1"});
Log.e("TAG","updateCount="+updateCount);
//出了异常
booleanflag = true;
if(flag){
thrownew RuntimeException("出异常啦!!!");
}
//执行update update person set age=17 where _id=3
values= new ContentValues();
values.put("age",17);
intupdateCount2 = 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();
}
}
}
}
SQLite数据库存储