在项目开发中,我们或多或少都会用到数据库。在Android中,我们一般使用SQLite,因为Android在android.database.sqlite包封装了很多SQLite操作的API。我自己写了一个Demo来总结SQLite的使用,托管在Github上,大家可以点击下载APK,也可以点击下载源码。Demo截图如下:

在使用SQLite时,我建议先下载一个本地SQLite客户端来验证操作,在本地写的SQL语句运行正确后,再转移到Android中。我用的是SQLite Expert Personal。

首先创建一个继承在SQLiteOpenHelper的类,并重写onCreate()和onUpgrade()方法。

public class OrderDBHelper extends SQLiteOpenHelper{ 
   private static final int DB_VERSION = 1;
   private static final String DB_NAME = "myTest.db";
   public static final String TABLE_NAME = "Orders";  
   public OrderDBHelper(Context context) {    
   super(context, DB_NAME, null, DB_VERSION);
}  @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) { 
       // create table Orders(Id integer primary key, CustomName text, OrderPrice integer, Country text);
       String sql = "create table if not exists " + TABLE_NAME + " (Id integer primary key, CustomName text, OrderPrice integer, Country text)";
       sqLiteDatabase.execSQL(sql);
   }  
@Override
   public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
       String sql = "DROP TABLE IF EXISTS " + TABLE_NAME;
       sqLiteDatabase.execSQL(sql);
       onCreate(sqLiteDatabase);
   }
}

这个类主要用于建数据库和建表用,我们再创建一个OrderDao用于处理所有的数据操作方法。在OrderDao钟实例化OrderDBHelper:

public OrderDao(Context context) {
   this.context = context;
   ordersDBHelper = new OrderDBHelper(context);
}

数据库操作无外乎:“增删查改”。对于“增删改”这类对表内容变换的操作,我们需先调用getWritableDatabase(),在执行的时候可以调用通用的execSQL(String sql)方法或对应的操作API:insert()、delete()、update()。而对“查”,需要调用getReadableDatabase(),这时就不能使用execSQL方法了,得使用query()或rawQuery()方法。下面开始一一介绍。

增加数据

在我的Demo中,有两种增加数据操作:

初始化数据

在进入Demo程序时,先判断表中是否有数据,如果表中没有数据,我将先添加一些数据。在初始化数据时,因为一次性要添加的数据比较多,所以我直接采用的是execSQL方法:

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction(); db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (1, 'Arc', 100, 'China')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (2, 'Bor', 200, 'USA')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (3, 'Cut', 500, 'Japan')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (4, 'Bor', 300, 'USA')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (5, 'Arc', 600, 'China')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (6, 'Doom', 200, 'China')"); db.setTransactionSuccessful();

插入一条新数据

我们还可以使用insert(String table,String nullColumnHack,ContentValues values)方法来插入,ContentValues内部实现就是HashMap,但是两者还是有差别的,ContenValues Key只能是String类型,Value只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西:

public ContentValues() {
   // Choosing a default size of 8 based on analysis of typical
   // consumption by applications.
    mValues = new HashMap<String, Object>(8);
}

使用insert()方法我们插入一条新数据(7, "Jne", 700, "China"),对于修改数据的操作我们一般当作事务(Transaction)处理:

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();
// insert into Orders(Id, CustomName, OrderPrice, Country) values (7, "Jne", 700, "China");
ContentValues contentValues = new ContentValues();
contentValues.put("Id", 7);
contentValues.put("CustomName", "Jne");
contentValues.put("OrderPrice", 700);
contentValues.put("Country", "China");
db.insertOrThrow(OrderDBHelper.TABLE_NAME, null, contentValues); db.setTransactionSuccessful();

删除数据

删除数据的方法除了execSQL还有delete(String table,String whereClause,String[] whereArgs),whereClause是删除条件,whereArgs是删除条件值数组。

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction(); // delete from Orders where Id = 7db.delete(OrderDBHelper.TABLE_NAME, "Id = ?", new String[]{String.valueOf(7)});db.setTransactionSuccessful();

再看删除的源码,里面会拼装删除条件和删除条件值数组:

public int delete(String table, String whereClause, String[] whereArgs) {
   acquireReference();
   try {
       SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
               (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
        try {
            return statement.executeUpdateDelete();
        } finally {
               statement.close();
       }
   } finally {
       releaseReference();
   }
}

修改数据

修改数据和插入数据很相似,调用的方法除了execSQL还可以是update(String table,ContentValues values,String whereClause, String[] whereArgs):

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();
// update Orders set OrderPrice = 800 where Id = 6ContentValues cv = new ContentValues();
cv.put("OrderPrice", 800);
db.update(OrderDBHelper.TABLE_NAME,cv,"Id = ?",new String[]{String.valueOf(6)});
db.setTransactionSuccessful();

查找数据

查找数据有两个方法,一是public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);,另外一个是public Cursor rawQuery(String sql, String[] selectionArgs)。rawQuery的写法类似上面的execSQL,在此不做介绍,query方法中的参数如下:

  • table:表名称

  • columns:列名称数组

  • selection:条件字句,相当于where

  • selectionArgs:条件字句,参数数组

  • groupBy:分组列

  • having:分组条件

  • orderBy:排序列

  • limit:分页查询限制

  • Cursor:返回值,相当于结果集ResultSet

我们可以看到返回的类型都是Cursor,Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法。Cursor游标常用方法如下:

我们先来查一查用户名为"Bor"的信息:

db = ordersDBHelper.getReadableDatabase();
// select * from Orders where CustomName = 'Bor'cursor = db.query(OrderDBHelper.TABLE_NAME,ORDER_COLUMNS,"CustomName = ?",new String[] {"Bor"},null, null, null);
if (cursor.getCount() > 0) {
   List<Order> orderList = new ArrayList<Order>(cursor.getCount());
       while (cursor.moveToNext()) {
       Order order = parseOrder(cursor);
       orderList.add(order);
   }
       return orderList;
}

当然我们也可以查询总数、最大值最小值之类的,以查询Country为China的用户总数为例:

db = ordersDBHelper.getReadableDatabase();
// select count(Id) from Orders where Country = 'China'cursor = db.query(OrderDBHelper.TABLE_NAME, new String[]{"COUNT(Id)"}, "Country = ?", new String[] {"China"}, null, null, null);
if (cursor.moveToFirst()) {
   count = cursor.getInt(0);
}

至此SQLite就介绍完了,大家可以下载Demo详细查看。Demo中还有一些其他比较干货的东西,大家可以挖掘挖掘。当然Demo中也有些不足,我还会更新,尽量做到让用户通过Demo就能学会如何使用SQLite。

Android SQlite详解的更多相关文章

  1. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  2. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  3. Android ActionBar详解

    Android ActionBar详解 分类: Android2014-04-30 15:23 1094人阅读 评论(0) 收藏 举报 androidActionBar   目录(?)[+]   第4 ...

  4. Android 签名详解

    Android 签名详解 AndroidOPhoneAnt设计模式Eclipse  在Android 系统中,所有安装 到 系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程 ...

  5. Android编译系统详解(一)

    ++++++++++++++++++++++++++++++++++++++++++ 本文系本站原创,欢迎转载! 转载请注明出处: http://blog.csdn.net/mr_raptor/art ...

  6. Android布局详解之一:FrameLayout

      原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6702273 FrameLayout是最简单的布局了.所有放在布局里的 ...

  7. 【整理修订】Android.mk详解

    Android.mk详解 1. Android.mk 的应用范围 Android.mk文件是GNU Makefile的一小部分,它用来对Android程序进行编译. 一个Android.mk文件可以编 ...

  8. Android菜单详解(四)——使用上下文菜单ContextMenu

    之前在<Android菜单详解(二)——创建并响应选项菜单>和<Android菜单详解(三)——SubMenu和IconMenu>中详细讲解了选项菜单,子菜单和图标菜单.今天接 ...

  9. Android签名详解(debug和release)

    Android签名详解(debug和release)   1. 为什么要签名 1) 发送者的身份认证 由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,以此保证签名不同的包 ...

随机推荐

  1. 2016CCPC东北地区大学生程序设计竞赛 1008 HDU5929

    链接http://acm.hdu.edu.cn/showproblem.php?pid=5929 题意:给你一种数据结构以及操作,和一种位运算,最后询问:从'栈'顶到低的运算顺序结果是多少 解法:根据 ...

  2. Codeforces Round #373 (Div. 2) B

    Description Anatoly lives in the university dorm as many other students do. As you know, cockroaches ...

  3. Codeforces Round #372 (Div. 2) B

    Description ZS the Coder loves to read the dictionary. He thinks that a word is nice if there exists ...

  4. Android多分辨率适配

    前一阶段开发android项目,由于客户要求进行多分辨率适配,能够支持国内主流的分辨率手机.因此经过了几次开发走了很多弯路,目前刚刚领略了android多分辨率适配的一些方法. 先介绍一下所走的弯路, ...

  5. Vi编辑器下使用分屏显示【已自己验证所有】

    :new 水平分割出一个新窗口 :vnew,:vne 垂直分割出一个新窗口 :new+文件路径/文件名; 在新的水平分屏中 载入/新建 文件.[文件存在则载入,不存在则在指定的路径新建,下同] :vn ...

  6. 【转】雪崩光电二极管(APD)偏置电源及其电流监测

    摘要:本文提供的参考设计用于实现APD偏置电源及其电流监测.基于MAX15031 DC-DC转换器,该电路能够将2.7V至11V范围的输入电压经过DC-DC电源转换器后得到一个70V.4mA电源. 下 ...

  7. ABAP断点调试

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. [SAP ABAP开发技术总结]DIALOG屏幕流逻辑

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. Object-c:两种文件读写的对比

    一.读写方法对比:(主要针对本地读取本地文件) 方式\操作 读 写 非URL方式 stringWithContentsOfFile writeToFile URL方式 stringWithConten ...

  10. [poj3349]Snowflake Snow Snowflakes(hash)

    Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 37615 Accepted: ...