Android SQLite 数据库存储
SQLite说明
SQLite是一款轻型的关系型数据库服务器,移动设备的数据库存储都是用SQLite
应用运行需要保存一系列有一定结构的数据,比如:公司员工信息
存储的文件类型:.db
数据保存的路径:/data/data/packageName/databases/xxx.db
默认情况下其他应用不能访问,当前应用可以通过ContentProvider提供其他应用操作
应用卸载时会删除此数据
SQLite 特点
安装文件小,最小只有几百K,Android系统已经安装
支持多操作系统,Android,WP,iOS,Windows,Linux等
支持多语言:Java,PHP,C#等
处理速度快:处理速度比MySql,Oracle,SqlServer都要快
数据量不是特别大
SQLite中的一个数据库就是一个.db文件(本质上.db的后缀都可以不指定)
sql语句的操作
SQLite操作数据的sql语句基本与mysql一样,但需要注意两点:
- 创建表时可以不用指定字段类型,sqlite可以适时的自动转换,但除了varchar类型外最好制定类型
- sqlite中主键名称建议使用_id
相关API
- SQLiteOpenHelper:数据库操作的抽象帮助类
SQLiteOpenHelper(Context context, String name
CursorFactory factorv, int version):构造方法,指定数据库文件名和版本号
abstract void onCreate(sQLiteDatabase db): 用于创建表
abstract void onupgrade() :用于版本更新
Salite database getReadableDatabasel):得到数据库连接
- SQLiteOpenHelper: 数据库操作的抽象帮助类
long insert():用于执行insert SQL,返回id值
int update():用于执行update Sql
int deletel(): 用于执行 delete Sql
Cursor query():用于执行select Sql,返回包含查询结果数据的Cursor
void execSql(sql) :执行sql语句
beginTransactiond: 开启事务
setTransaction Successfull:设置事务是成功的
endTransactionl):结束事务,可能提交事务或回滚事务
openDatabase(String path, CursorFactory factory, int flags): 得到数据库连接
- Cursor:包含所有查询结果记录的结果集对象(光标,游标)
int getcount():匹配的总记录数
boolean moveToNext():将游标移动到下一条记录的前面
Xxxx getxxx(columnindex):根据字段下标得到对应值(getString(0) 0是下标位置,从0开始,如果0角标下是一个varchar类型的字段,如果是对应下标字段的类型是int,那么久使用getInt(0))
int getColumnlndex(columnname):根据字段名得到对应的下标
测试用例
先创建一个布局文件,用于测试每个方法
<LinearLayout xmlns:android=""android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testCreateDB"android:text="Create DB" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testUpdateDB"android:text="Update DB" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testInsert"android:text="Insert" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testUpdate"android:text="Update" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testDelete"android:text="Delete" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testQuery"android:text="query" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testTransaction"android:text="Test Transaction" /></LinearLayout>
首先需要SQLiteOpenHelper(数据库操作的抽象帮助类)
package com.atguigu.l04_datastorage;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;public class DBHelper extends SQLiteOpenHelper {public DBHelper(Context context,int version) {super(context, "skyscanner.db", null, version);}/*** 什么时候才会创建数据库文件?* 1). 数据库文件不存在* 2). 连接数据库* * 什么时候调用?* 当数据库文件创建时调用(1次)** 在此方法中做什么?* 建表* 插入一些初始化数据*/@Overridepublic 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);//插入一些初始化数据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)");}//当传入的版本号大于数据库的版本号时调用@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.e("TAG", "DBHelper onUpgrade()");}}
创建库
public void testCreateDB(View v) {DBHelper dbHelper = new DBHelper(this, 1);//获取连接// 当存储空间不够时,如果使用的是getWritableDatabase,那么插入数据,会抛出异常// 当存储空间不够时,如果使用的是getReadableDatabase,那么插入数据无效,没有反应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=4ContentValues 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=2int 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 personCursor 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()) {//_idint id = cursor.getInt(0);//nameString name = cursor.getString(1);//ageint 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=1ContentValues 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=3values = 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();}}}
Android SQLite 数据库存储
SQLite说明
SQLite是一款轻型的关系型数据库服务器,移动设备的数据库存储都是用SQLite
应用运行需要保存一系列有一定结构的数据,比如:公司员工信息
存储的文件类型:.db
数据保存的路径:/data/data/packageName/databases/xxx.db
默认情况下其他应用不能访问,当前应用可以通过ContentProvider提供其他应用操作
应用卸载时会删除此数据
SQLite 特点
安装文件小,最小只有几百K,Android系统已经安装
支持多操作系统,Android,WP,iOS,Windows,Linux等
支持多语言:Java,PHP,C#等
处理速度快:处理速度比MySql,Oracle,SqlServer都要快
数据量不是特别大
SQLite中的一个数据库就是一个.db文件(本质上.db的后缀都可以不指定)
sql语句的操作
SQLite操作数据的sql语句基本与mysql一样,但需要注意两点:
- 创建表时可以不用指定字段类型,sqlite可以适时的自动转换,但除了varchar类型外最好制定类型
- sqlite中主键名称建议使用_id
相关API
- SQLiteOpenHelper:数据库操作的抽象帮助类
SQLiteOpenHelper(Context context, String name
CursorFactory factorv, int version):构造方法,指定数据库文件名和版本号
abstract void onCreate(sQLiteDatabase db): 用于创建表
abstract void onupgrade() :用于版本更新
Salite database getReadableDatabasel):得到数据库连接
- SQLiteOpenHelper: 数据库操作的抽象帮助类
long insert():用于执行insert SQL,返回id值
int update():用于执行update Sql
int deletel(): 用于执行 delete Sql
Cursor query():用于执行select Sql,返回包含查询结果数据的Cursor
void execSql(sql) :执行sql语句
beginTransactiond: 开启事务
setTransaction Successfull:设置事务是成功的
endTransactionl):结束事务,可能提交事务或回滚事务
openDatabase(String path, CursorFactory factory, int flags): 得到数据库连接
- Cursor:包含所有查询结果记录的结果集对象(光标,游标)
int getcount():匹配的总记录数
boolean moveToNext():将游标移动到下一条记录的前面
Xxxx getxxx(columnindex):根据字段下标得到对应值(getString(0) 0是下标位置,从0开始,如果0角标下是一个varchar类型的字段,如果是对应下标字段的类型是int,那么久使用getInt(0))
int getColumnlndex(columnname):根据字段名得到对应的下标
测试用例
先创建一个布局文件,用于测试每个方法
<LinearLayout xmlns:android=""android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testCreateDB"android:text="Create DB" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testUpdateDB"android:text="Update DB" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testInsert"android:text="Insert" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testUpdate"android:text="Update" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testDelete"android:text="Delete" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testQuery"android:text="query" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="testTransaction"android:text="Test Transaction" /></LinearLayout>
首先需要SQLiteOpenHelper(数据库操作的抽象帮助类)
package com.atguigu.l04_datastorage;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;public class DBHelper extends SQLiteOpenHelper {public DBHelper(Context context,int version) {super(context, "skyscanner.db", null, version);}/*** 什么时候才会创建数据库文件?* 1). 数据库文件不存在* 2). 连接数据库* * 什么时候调用?* 当数据库文件创建时调用(1次)** 在此方法中做什么?* 建表* 插入一些初始化数据*/@Overridepublic 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);//插入一些初始化数据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)");}//当传入的版本号大于数据库的版本号时调用@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.e("TAG", "DBHelper onUpgrade()");}}
创建库
public void testCreateDB(View v) {DBHelper dbHelper = new DBHelper(this, 1);//获取连接// 当存储空间不够时,如果使用的是getWritableDatabase,那么插入数据,会抛出异常// 当存储空间不够时,如果使用的是getReadableDatabase,那么插入数据无效,没有反应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=4ContentValues 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=2int 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 personCursor 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()) {//_idint id = cursor.getInt(0);//nameString name = cursor.getString(1);//ageint 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=1ContentValues 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=3values = 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();}}}