Android SQLite详解

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

在使用SQLite时,我建议先下载一个本地SQLite客户端来验证操作,在本地写的SQL语句运行正确后,再转移到Android中。我用的是SQLite Expert Personal
首先创建一个继承在SQLiteOpenHelper的类,并重写onCreate()onUpgrade()方法。

 
  1. public class OrderDBHelper extends SQLiteOpenHelper{

  2. private static final int DB_VERSION = 1;

  3. private static final String DB_NAME = "myTest.db";

  4. public static final String TABLE_NAME = "Orders";

  5.  
  6. public OrderDBHelper(Context context) {

  7. super(context, DB_NAME, null, DB_VERSION);

  8. }

  9.  
  10. @Override

  11. public void onCreate(SQLiteDatabase sqLiteDatabase) {

  12. // create table Orders(Id integer primary key, CustomName text, OrderPrice integer, Country text);

  13. String sql = "create table if not exists " + TABLE_NAME + " (Id integer primary key, CustomName text, OrderPrice integer, Country text)";

  14. sqLiteDatabase.execSQL(sql);

  15. }

  16.  
  17. @Override

  18. public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {

  19. String sql = "DROP TABLE IF EXISTS " + TABLE_NAME;

  20. sqLiteDatabase.execSQL(sql);

  21. onCreate(sqLiteDatabase);

  22. }

  23. }

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

 
  1. public OrderDao(Context context) {

  2. this.context = context;

  3. ordersDBHelper = new OrderDBHelper(context);

  4. }

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

增加数据

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

 
  1. db = ordersDBHelper.getWritableDatabase();

  2. db.beginTransaction();

  3.  
  4. db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (1, 'Arc', 100, 'China')");

  5. db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (2, 'Bor', 200, 'USA')");

  6. db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (3, 'Cut', 500, 'Japan')");

  7. db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (4, 'Bor', 300, 'USA')");

  8. db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (5, 'Arc', 600, 'China')");

  9. db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (6, 'Doom', 200, 'China')");

  10.  
  11. db.setTransactionSuccessful();

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

 
  1. public ContentValues() {

  2. // Choosing a default size of 8 based on analysis of typical

  3. // consumption by applications.

  4. mValues = new HashMap<String, Object>(8);

  5. }

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

 
  1. db = ordersDBHelper.getWritableDatabase();

  2. db.beginTransaction();

  3.  
  4. // insert into Orders(Id, CustomName, OrderPrice, Country) values (7, "Jne", 700, "China");

  5. ContentValues contentValues = new ContentValues();

  6. contentValues.put("Id", 7);

  7. contentValues.put("CustomName", "Jne");

  8. contentValues.put("OrderPrice", 700);

  9. contentValues.put("Country", "China");

  10. db.insertOrThrow(OrderDBHelper.TABLE_NAME, null, contentValues);

  11.  
  12. db.setTransactionSuccessful();

删除数据

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

 
  1. db = ordersDBHelper.getWritableDatabase();

  2. db.beginTransaction();

  3.  
  4. // delete from Orders where Id = 7

  5. db.delete(OrderDBHelper.TABLE_NAME, "Id = ?", new String[]{String.valueOf(7)});

  6. db.setTransactionSuccessful();

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

 
  1. public int delete(String table, String whereClause, String[] whereArgs) {

  2. acquireReference();

  3. try {

  4. SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table +

  5. (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);

  6. try {

  7. return statement.executeUpdateDelete();

  8. } finally {

  9. statement.close();

  10. }

  11. } finally {

  12. releaseReference();

  13. }

  14. }

修改数据

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

 
  1. db = ordersDBHelper.getWritableDatabase();

  2. db.beginTransaction();

  3.  
  4. // update Orders set OrderPrice = 800 where Id = 6

  5. ContentValues cv = new ContentValues();

  6. cv.put("OrderPrice", 800);

  7. db.update(OrderDBHelper.TABLE_NAME,

  8. cv,

  9. "Id = ?",

  10. new String[]{String.valueOf(6)});

  11. 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

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

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

 
  1. db = ordersDBHelper.getReadableDatabase();

  2.  
  3. // select * from Orders where CustomName = 'Bor'

  4. cursor = db.query(OrderDBHelper.TABLE_NAME,

  5. ORDER_COLUMNS,

  6. "CustomName = ?",

  7. new String[] {"Bor"},

  8. null, null, null);

  9.  
  10. if (cursor.getCount() > 0) {

  11. List<Order> orderList = new ArrayList<Order>(cursor.getCount());

  12. while (cursor.moveToNext()) {

  13. Order order = parseOrder(cursor);

  14. orderList.add(order);

  15. }

  16. return orderList;

  17. }

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

 
  1. db = ordersDBHelper.getReadableDatabase();

  2. // select count(Id) from Orders where Country = 'China'

  3. cursor = db.query(OrderDBHelper.TABLE_NAME,

  4. new String[]{"COUNT(Id)"},

  5. "Country = ?",

  6. new String[] {"China"},

  7. null, null, null);

  8.  
  9. if (cursor.moveToFirst()) {

  10. count = cursor.getInt(0);

  11. }

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

转载地址:http://www.jianshu.com/p/5c33be6ce89d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值