上篇博客提到过SQLite,它是嵌入式数据库,由于其轻巧但功能强大,被广泛的用于嵌入式设备当中。后来在智能手机、平板流行之后,它作为文件型数据库,几乎成为了智能设备单机数据库的必选,可以随着安卓app打包到apk文件当中。

SQLite的官方网站是http://www.sqlite.org/,可以任意下载,上面也有详尽的文档可以参考,这篇博客重点关注SQLite在Android开发中如何使用。

在Android开发中,推荐建立一个类继承自SQLiteOpenHelper来创建数据库操作类,比如:

  1. public class DBHelper extends SQLiteOpenHelper {
  2. private static final String database = "test.db";
  3. private static final Integer version = 1;
  4. public DBHelper(Context context) {
  5. // 构造函数初始化各成员变量
  6. super(context, database, null, version);
  7. }
  8. @Override
  9. public void onCreate(SQLiteDatabase db) {
  10. // 当通过SQLiteOpenHelper的子类获取数据库连接时,如果数据库不存在,则调用onCreate方法来创建数据库
  11. String sql = "create table Score(id integer primary key autoincrement,name varchar(20),point integer)";
  12. db.execSQL(sql);
  13. }
  14. @Override
  15. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  16. // 当传入的实例的数据库版本号高于之前的版本号时,系统会自动调用onUpgrade方法更新数据库
  17. // 更新数据库的操作:备份数据库表数据,重新创建或修改表、约束等,然后将原来的数据导入到新建的表中。
  18. }
  19. }

上面的代码有3点需要注意:

1、构造函数(方法)中指定了数据库的名称和版本号

它会默认的在data/data/包名/databases/目录下创建这个数据库,当然你也可以指定数据库文件存在的路径;版本号设置为1,如果你要想升级,可以在构造方法的参数中加上version,以便初始化。

2、onCreate是在数据库文件没有创建的时候执行,如果有了的话则不执行

3、onUpgrade是在新的指定版本号高于旧的指定版本号的时候执行,一般在数据库升级的时候需要操作

然后我们建一个具体的数据库操作类:

  1. /**
  2. * 成绩操作类
  3. *
  4. * @author guwei
  5. *
  6. */
  7. public class ScoreOp {
  8. // 插入一条成绩记录
  9. public long insert(SQLiteDatabase db, String name, Integer point) {
  10. try {
  11. db.beginTransaction();
  12. ContentValues values = new ContentValues();
  13. values.put("name", name);
  14. values.put("point", point);
  15. long result = db.insert("Score", null, values);
  16. if (result != -1) {
  17. db.setTransactionSuccessful();
  18. }
  19. return result;
  20. } finally {
  21. db.endTransaction();
  22. }
  23. }
  24. // 修改一条成绩记录
  25. public int update(SQLiteDatabase db, String name, Integer point) {
  26. try {
  27. db.beginTransaction();
  28. ContentValues values = new ContentValues();
  29. values.put("name", name);
  30. values.put("point", point);
  31. int result = db.update("Score", values, "name = ?",
  32. new String[] { name });
  33. db.setTransactionSuccessful();
  34. return result;
  35. } finally {
  36. db.endTransaction();
  37. }
  38. }
  39. // 删除一条成绩记录
  40. public long delete(SQLiteDatabase db, String name) {
  41. try {
  42. db.beginTransaction();
  43. int result = db.delete("Score", "name = ?", new String[] { name });
  44. db.setTransactionSuccessful();
  45. return result;
  46. } finally {
  47. db.endTransaction();
  48. }
  49. }
  50. // 查询根据name正向排序的前10条总分大于指定分数的人员信息
  51. public Cursor query(SQLiteDatabase db, Integer point) {
  52. return db.query("Score",
  53. new String[] { "name", "sum(point) as points" }, null, null,
  54. "name", "sum(point)>=" + point, "name asc", "0,10");
  55. }
  56. // 更灵活的查询,SQL任意拼接
  57. public Cursor query(SQLiteDatabase db, String sql, String[] selectionArgs) {
  58. return db.rawQuery(sql, selectionArgs);
  59. }
  60. }

这上面封装了CRUD操作,而且都是带事务的(执行多条SQL时需要),值得关注的是最后的两个query方法。

第一个query是指定了一个复杂sql查询语句的情况。

按照顺序,参数的含义如下:

1)、table The table name to compile the query against.

指定的查询的表名

2)、columns A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.

返回的查询列表的列名

3)、selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.

where条件,不包括where关键字

4)、selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.

where条件指定的参数值

5)、groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.

group by分组后面跟着的列名

6)、having A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
having 后面紧跟着的在分组基础上进一步筛选的内容

7)、orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.

order by后面根据某字段排序

8)、limit Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
limit关键字,分页查询时使用

实际上上面对应的这8个参数,就是对应如下SQL查询语句各关键字后面的内容,其原理就是通过指定参数拼接如下SQL语句。

这里顺便提一下,SQLite Expert是非常好用的管理SQLite数据库的工具,可以在http://www.sqliteexpert.com/下载到,也可以直接搜索下载相应破解版本。

回到第二个query方法,参数很简单,只有一个sql语句以及一个string数组(提供sql语句参数的值)。这个方法的意义就在于它很灵活,可以直接把能够执行的sql扔进去执行,而且是参数化的,是第一种查询方法很有力的补充。

好,最后我们就可以写测试代码来验证了。界面很简单,直接放置一个按钮即可。

  1. public class SQLiteActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_sqlite);
  6. Button btn = (Button) findViewById(R.id.btn);
  7. btn.setOnClickListener(new View.OnClickListener() {
  8. @Override
  9. public void onClick(View v) {
  10. DBHelper dbHelper = new DBHelper(SQLiteActivity.this);
  11. //获得一个可写数据库操作对象
  12. SQLiteDatabase wdb = dbHelper.getWritableDatabase();
  13. //添加纪录
  14. ScoreOp scoreOp = new ScoreOp();
  15. scoreOp.insert(wdb, "zhang3", 98);
  16. scoreOp.insert(wdb, "zhang3", 94);
  17. scoreOp.insert(wdb, "li4", 92);
  18. scoreOp.insert(wdb, "wang5", 89);
  19. scoreOp.insert(wdb, "wang5", 82);
  20. //修改记录
  21. scoreOp.update(wdb, "li4", 90);
  22. //删除记录
  23. scoreOp.delete(wdb, "li4");
  24. //获得一个可读数据库操作对象
  25. SQLiteDatabase rdb = dbHelper.getReadableDatabase();
  26. // 1.可以调用系统提供的query方法,以指定参数的形式返回Cursor对象
  27. // Cursor cursor = scoreOp.query(rdb, 192);
  28. // 2.可以直接执行SQL查询语句
  29. Cursor cursor = scoreOp
  30. .query(rdb,
  31. "select name,sum(point) as points from Score group by name having sum(point)>=192 order by name asc limit ?,?",
  32. new String[] { "0", "10" });
  33. while (cursor.moveToNext()) {
  34. String name = cursor.getString(cursor
  35. .getColumnIndex("name"));
  36. Integer points = cursor.getInt(cursor
  37. .getColumnIndex("points"));
  38. Toast.makeText(SQLiteActivity.this,
  39. "姓名:" + name + ";总分:" + points, Toast.LENGTH_SHORT)
  40. .show();
  41. }
  42. cursor.close();
  43. }
  44. });
  45. }
  46. }

点击按钮执行之后就可以弹出符合条件的数据。如果不放心,可以切换到DDMS界面,选择File Explorer选项卡,找到路径下的我们创建的test.db文件,Pull(拉取)到电脑磁盘上,用SQLite Expert等工具打开验证。

Android数据库开发——SQLite的更多相关文章

  1. Android数据库之SQLite数据库

    Android数据库之SQLite数据库 导出查看数据库文件 在android中,为某个应用程序创建的数据库,只有它可以访问,其它应用程序是不能访问的,数据库位于Android设备/data/data ...

  2. Android数据库(sqlite)之Room

    说在前面: 1.使用Room需要添加的依赖: dependencies { def room_version = "2.2.3" implementation "andr ...

  3. DBExecutor android 数据库框架

    https://github.com/eltld/DBExecutor android 数据库框架,sqlite database

  4. 深入解析Sqlite的完美替代者,android数据库新王者——Realm

    写在前面: 又到一年一度七夕虐狗节,看着大家忍受着各种朋友圈和QQ空间还有现实生活中的轮番轰炸,我实在不忍心再在这里给大家补刀,所以我觉得今天不虐狗,继续给大家分享有用的. 如果你比较关心androi ...

  5. (转)Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解

    原文:http://blog.csdn.net/lidew521/article/details/8655229 1.SQLite介绍:最大特点是,无数据类型;除了可以使用文件或SharedPrefe ...

  6. Android数据库高手秘籍(一)——SQLite命令

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/38461239 要想熟练地操作不论什么一个数据库.最最主要的要求就是要懂SQL语言, ...

  7. Unity3D游戏开发之SQLite让数据库开发更简单

    各位朋友大家好.欢迎大家关注我的博客,我是秦元培,我是博客地址是http://blog.csdn.net/qinyuanpei.在经历了一段时间的忙碌后,博主最终有时间来研究新的东西啦,今天博客向和大 ...

  8. iOS开发数据库篇—SQLite简单介绍

    iOS开发数据库篇—SQLite简单介绍 一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1 ...

  9. iOS开发数据库篇—SQLite的应用

    iOS开发数据库篇—SQLite的应用 一.简单说明 在iOS中使用SQLite3,首先要添加库文件libsqlite3.dylib和导入主头文件. 导入头文件,可以使用库中的函数(是纯C语言的) 二 ...

随机推荐

  1. 使用FileZilla解决从Windows上传文件到Linux vsftpd的乱码问题!

    日前将golang的开发环境从windows转移到了CentOS6上,为了把以前写得项目代码上传到centos,架设了vsftpd服务,设置为本地用户登录,然后用惯用的ftp软件flashfxp上传了 ...

  2. 《HTTP权威指南》学习笔记——HTTP报文

    HTTP报文 HTTP:互联网的信使 HTTP报文:信使用来搬东西的包裹 1.报文流 HTTP报文:HTTP应用程序之间发送的数据块 组成:元信息开头(文本形式,描述报文的内容和含义)+可选的数据部分 ...

  3. Java基础之深入理解Class对象与反射机制

    深入理解Class对象 RRIT及Class对象的概念 RRIT(Run-Time Type Identification)运行时类型识别.在<Thinking in Java>一书第十四 ...

  4. pdf转换成word转换器免费版

    在平时的办公中,我们只需要有一款比较好用的pdf转换成word转换器,就能提高我们的工作效率,但是国内外的pdf转换成word转换器应该怎么选呢?小编因为是文职工作者,所以在日常的实践中选出了ABBY ...

  5. hibernate 一级缓存,二级缓存,查询缓存

    1.一级缓存是session级的缓存,session结束即事务提交,session关闭,缓存清除.效果不大 get方式:一个session内,第二次查询不连数据库.适用于一级缓存 load方式:懒加载 ...

  6. JS匿名函数理解

    匿名函数的基本形式为(function(){...})(); 前面的括号包含函数体,后面的括号就是给匿名函数传递参数并立即执行之 匿名函数的作用是避免全局变量的污染以及函数名的冲突   1.小括号的作 ...

  7. C#静态构造函数调用机制

    https://blog.csdn.net/cjolj/article/details/56329230 若一个类中有静态构造函数,在首次实例化该类或任何的静态成员被引用时,.NET自动调用静态构造函 ...

  8. org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'parentId' in 'class java.lang.String'

    Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ' ...

  9. Linux+Redis实战教程_day02_消息订阅与发布_多数据库_redis批量操作-事务_redis持久化

    5.扩展知识-消息订阅与发布(了解) 订阅新闻,新闻发布 subscribe channel:订阅频道,例:subscribe mychat,订阅mychat这个频道 psubscribe chann ...

  10. mongodb 搭建主从服务器

    mongodb 主从配置比较简单,只需要在启动的时候添加参数(-master.-slave -source IP:PORT). Ubuntu 16.04 系统环境 监听端口分别为:27010.2701 ...