一:SQLite简介
Google为Andriod的较大的数据处理提供了SQLite,他在数据存储、管理、维护等各方面都相当出色,功能也非常的强大。SQLite具备下列特点:
1.轻量级
使用 SQLite 只需要带一个动态库,就可以享受它的全部功能,而且那个动态库的尺寸想当小。
2.独立性
SQLite 数据库的核心引擎不需要依赖第三方软件,也不需要所谓的“安装”。
3.隔离性
SQLite 数据库中所有的信息(比如表、视图、触发器等)都包含在一个文件夹内,方便管理和维护。
4.跨平台
SQLite 目前支持大部分操作系统,不至电脑操作系统更在众多的手机系统也是能够运行,比如:Android。
5.多语言接口
SQLite 数据库支持多语言编程接口。
6.安全性
SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一个可以写入数据。
- Android通过 SQLite 数据库引擎来实现结构化数据的存储。在一个数据库应用程序中,任何类都可以通过名字对已经创建的数据库进行访问,但是在应用程序之外就不可以。
- SQLite 数据库是一种用C语言编写的嵌入式数据库,它是一个轻量级的数据库,最初为嵌入式设计的。它是在一些基础简单的语句处理上要比oracle / mysql快很多,而且其对内存的要求很低,在内存中只需要几百KB的存储空间。这是Android中采用 SQLite 数据库的主要原因。
- SQLite 支持事务处理功能。Transaction
- SQLite 处理速度比MySQL等著名的开源数据库系统更快。它没有服务器进程。
- SQLite 通过文件保存数据库,该文件是跨平台的,可以自由复制。一个文件就是一个数据库。数据库名即文件名。
- JDBC会消耗太多系统资源,所以JDBC对于手机并不合适,因此Android提供了新的API来使用 SQLite 数据库
二:Android中的SQLite使用:
第一步:
创建一个类继承SQLiteOpenHelper类,我们把这个类命名为DatabaseHelper,它作为一个访问Sqlite的助手类,提供了两方面的功能:
1、 getReadableDatabase()/getWritableDatabase()可以获得SQLiteDatabase对象,通过该对象可以对数据库进行操作;
2、 提供OnCreate()和onUpgrade()两个回调函数,允许我们在创建和升级数据库时,进行自己的操作
第二步:
得到SQLiteDatabase
第三步 :
执行(增删改查)
首先创建数据库类
public class DatabaseHelper extends SQLiteOpenHelper { private static final String DB_NAME = "mydata.db"; //数据库名称 private static final int version = 1; //数据库版本 public DatabaseHelper(Context context) { super(context, DB_NAME, null, version);// TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase db) { String sql = "create table user(username varchar(60) not null, password varchar(60) not null );"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } } |
SQLiteOpenHelper类介绍
SQLiteOpenHelper是SQLiteDatabase的一个帮助类,用来管理数据库的创建和版本的更新。一般是建立一个类继承它,并实现它的onCreate和onUpgrade方法。
方法名 |
方法描述 |
SQLiteOpenHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version) |
构造方法,一般是传递一个要创建的数据库名称那么参数 |
onCreate(SQLiteDatabase db) |
创建数据库时调用 |
onUpgrade(SQLiteDatabase db,int oldVersion , int newVersion) |
版本更新时调用 |
getReadableDatabase() |
创建或打开一个只读数据库 |
getWritableDatabase() |
创建或打开一个读写数据库 |
下面来介绍调用的方法
创建数据库
这里特别的地方是通过调用了SQLiteOpenHelper类的getReadableDatabase()方法来实现创建一个数据库的
1 2 3 |
DatabaseHelper database = new DatabaseHelper(this);//this指传上下文 SQLiteDatabase db = null; db = database.getReadalbeDatabase(); |
SQLiteDatabase类为我们提供了很多种方法,而较常用的方法如下
(返回值)方法名 |
方法描述 |
(int) delete(String tableName,String whereClause,String[] whereArgs) |
删除数据行的便捷方法 |
(long) insert(String table,String nullColumnHack,ContentValues values) |
添加数据行的便捷方法 |
(int) update(String table, ContentValues values, String whereClause, String[] whereArgs) |
更新数据行的便捷方法 |
(void) execSQL(String sql) |
执行一个SQL语句,可以是一个select或其他的sql语句 |
(void) close() |
关闭数据库 |
(Cursor) query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) |
查询指定的数据表返回一个带游标的数据集 |
(Cursor) rawQuery(String sql, String[] selectionArgs) |
运行一个预置的SQL语句,返回带游标的数据集(与上面的语句最大的区别就是防止SQL注入) |
数据的增删改查分别可以通过2种途径来实现
数据的添加
1.使用insert方法
1 2 3 |
ContentValues cv = new ContentValues();//实例化一个ContentValues用来装载待插入的数据cv.put("username","Jack Johnson");//添加用户名 cv.put("password","iLovePopMusic"); //添加密码 db.insert("user",null,cv);//执行插入操作 |
2.使用execSQL方式来实现
1 2 |
String sql = "insert into user(username,password) values ('Jack Johnson','iLovePopMuisc');//插入操作的SQL语句 db.execSQL(sql);//执行SQL语句 |
数据的删除
同样有2种方式可以实现
1 2 3 |
String whereClause = "username=?";//删除的条件 String[] whereArgs = {"Jack Johnson"};//删除的条件参数 db.delete("user",whereClause,whereArgs);//执行删除 |
使用execSQL方式的实现
1 2 |
String sql = "delete from user where username='Jack Johnson'";//删除操作的SQL语句 db.execSQL(sql);//执行删除操作 |
数据修改
同上,仍是2种方式
1 2 3 4 5 |
ContentValues cv = new ContentValues();//实例化ContentValues cv.put("password","iHatePopMusic");//添加要更改的字段及内容 String whereClause = "username=?";//修改条件 String[] whereArgs = {"Jack Johnson"};//修改条件的参数db.update("user",cv,whereClause,whereArgs);//执行修改 |
使用execSQL方式的实现
1 2 |
String sql = "update [user] set password = 'iHatePopMusic' where username='Jack Johnson'";//修改的SQL语句 db.execSQL(sql);//执行修改 |
查询;
select * from sqlite_master where type='table' order by name
db.exeSQL(sql);
条件查询
- String[] columns={"kind","textnum","region"};//你要的数据
- String 条件字段="NUMWEEK=? and YEAR=?",
- String[] selectionArgs={”星期一","2013"};//具体的条件,注意要对应条件字段
- Cursor cursor=db.query(表名, columns, 条件字段,selectionArgs, null, null, null, null);
关于 Cursor 的重要方法:
close() //关闭游标,释放资源
copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) //在缓冲区中检索请求的列的文本,将将其存储
getColumnCount() //返回所有列的总数
getColumnIndex(String columnName) //返回指定列的名称,如果不存在返回-1
getColumnIndexOrThrow(String columnName) //从零开始返回指定列名称,如果不存在将抛出IllegalArgumentException 异常。
getColumnName(int columnIndex) //从给定的索引返回列名
getColumnNames() //返回一个字符串数组的列名
getCount() //返回Cursor 中的行数
moveToFirst() //移动光标到第一行
moveToLast() //移动光标到最后一行
moveToNext() //移动光标到下一行
moveToPosition(int position) //移动光标到一个绝对的位置
moveToPrevious() //移动光标到上一行
事物:
应用程序初始化时需要批量的向sqlite中插入大量数据,单独的使用for+Insert方法导致应用响应缓慢,因为 sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。我的应用初始5000条记录也就是要5000次读写磁盘操作。
而且不能保证所有数据都能同时插入。(有可能部分插入成功,另外一部分失败,后续还得删除。太麻烦)
解决方法:
添加事务处理,把5000条插入作为一个事务
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功,则所有从beginTransaction()开始的操作都会被提交,如果没有调用setTransactionSuccessful() 方法则回滚事务。
注意:getWritableDatabase(),getReadableDatabase的区别是当数据库写满时,调用前者会报错,调用后者不会,所以如果不是更新数据库的话,最好调用后者来获得数据库连接。
// listView.setAdapter(new MyAdapter(MainActivity.this,cursor));
/**
* new SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to , int flags) ;
参数:
1)、Context context, 这个与 SimpleListItemFactory 相关的 ListView 所处运行上下文(context)。也就是这个 ListView 所在的 Activity。
2)、int layout, 显示 list item 的 布局文件。这个 layout 文件中至少要包含在 "to" 参数中命名的 views。
3)、Cursor c, 数据库的光标( Cursor )。如果 cursor 无效,则该参数可以为 null
4)、String[] from, 指定 column 中的哪些列的数据将绑定(显示)到 UI 中。如果 cursor 无效, 则该参数可为 null。
5)、int[] to, 指定用于显示 "from" 参数指定的数据列表的 views。 这些 views 必须都是 TextViews。 "from" 参数的前 N 个值(valus)和 "to" 参数的前 N 个 views 是一一对应的关系。如果 cursor 无效,则该参数可为 null。
6)、flags,用于定义适配器行为的标志位。
Flags used to determine the behavior of the adapter; may be any combination of FLAG_AUTO_REQUERY and FLAG_REGISTER_CONTENT_OBSERVER。
FLAG_AUTO_REQUERY(常量值:1 )从 API11 开始已经废弃。因为他会在应用程序的 UI 线程中执行Cursor查询操作, 导致响应缓慢甚至应用程序停止响应(ANR)application not response的错误。作为替代方案,请使用 LoaderManager 和 CursorLoader.
如果设置FLAG_REGISTER_CONTENT_OBSERVER(常量值:2),适配器会在Cursor上注册一个Observer,当通知到达时会调用 onContentChanged() 方法。
示例代码:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_listview_main,
cursor, new String[] { "news_title","news_addtime" },
new int[] { R.id.text_item_title, R.id.text_item_addtime });
*
* **/
SimpleCursorAdapter adapter=new SimpleCursorAdapter(MainActivity.this,R.layout.item,cursor,new String[]{"username","password"},new int[]{R.id.name,R.id.pwd});
listView.setAdapter(adapter);
class MyAdapter extends CursorAdapter{
private Context context;
public MyAdapter(Context context, Cursor c) {
super(context, c);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ViewHolder holder=new ViewHolder();
View view=LayoutInflater.from(context).inflate(R.layout.item,null);
holder.name=view.findViewById(R.id.name);
holder.pwd=view.findViewById(R.id.pwd);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder= (ViewHolder) view.getTag();
holder.name.setText(cursor.getString(cursor.getColumnIndex("username")));
holder.pwd.setText(cursor.getString(cursor.getColumnIndex("password")));
}
}
class ViewHolder{
TextView name,pwd;
}
使用命令查看:
进入到控制台中,输入adb shell,进入到命令模式的环境中
2,输入:cd /data/data/
3, 选择你所在的数据库文件,比如我的jne.com.order, 输入命令:cd jne.com.order
4, 可以使用ls -l 命令查看当前目录中的文件
5,输入: cd databases 进入到数据库文件中
6, ls -l 显示你数据库中你建立的数据库
7, sqlite3 info.db 进入到你选择的数据库中
8, .tables :查看你建的表
9, select * from table_name;s 可以查看整个表的信息
10, 使用其他的SQL语句可以进一步对表进行操作,注意SQL语句必须用分号(;)结尾
如果输入adb后提示为是内部命令等,请先设置adb环境变量
右键我的电脑->属性->高级->环境变量->Path,在Path中添加Android SDK安装路径中adb.exe的路径,例如本例中的安装路径为D:\Program Files\adt-bundle-windows-x86\adt-bundle-windows-x86\sdk\platform-tools(注意环境变量添加的规范,用';'分号隔开)