zoukankan      html  css  js  c++  java
  • Android--SQLite讲解

    转自 应用 here 

      简介 here

    值得一提的是,袖珍型的SQLite竟然可以支持高达2TB大小的数据库,每个数据库都是以单个文件的形式存在,这些数据都是以B-Tree的数据结构形式存储在磁盘上。

    在事务处理方面,SQLite通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。在某个进程或线程想数据库执行写操作之前,必须获得独占锁。在获得独占锁之后,其他的读或写操作将不会再发生。

    SQLite采用动态数据类型,当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值转换成该列的类型,如果不能转换,则该值将作为本身的类型存储,SQLite称这为“弱类型”。但有一个特例,如果是INTEGER PRIMARY KEY,则其他类型不会被转换,会报一个“datatype missmatch”的错误。

    概括来讲,SQLite支持NULL、INTEGER、REAL、TEXT和BLOB数据类型,分别代表空值、整型值、浮点值、字符串文本、二进制对象。

     1     @Override
     2     protected void onCreate(Bundle savedInstanceState) {
     3         super.onCreate(savedInstanceState);
     4         
     5         //打开或创建test.db数据库
     6         SQLiteDatabase db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);
     7         db.execSQL("DROP TABLE IF EXISTS person");
     8         //创建person表
     9         db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT)");
    10         Person person = new Person();
    11         person.name = "john";
    12         person.age = 30;
    13         //插入数据
    14         db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age});
    15         
    16         person.name = "david";
    17         person.age = 33;
    18         //ContentValues以键值对的形式存放数据
    19         ContentValues cv = new ContentValues();
    20         cv.put("name", person.name);
    21         cv.put("age", person.age);
    22         //插入ContentValues中的数据
    23         db.insert("person", null, cv);
    24         
    25         cv = new ContentValues();
    26         cv.put("age", 35);
    27         //更新数据
    28         db.update("person", cv, "name = ?", new String[]{"john"});
    29         
    30         Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});
    31         while (c.moveToNext()) {
    32             int _id = c.getInt(c.getColumnIndex("_id"));
    33             String name = c.getString(c.getColumnIndex("name"));
    34             int age = c.getInt(c.getColumnIndex("age"));
    35             Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);
    36         }
    37         c.close();
    38         
    39         //删除数据
    40         db.delete("person", "age < ?", new String[]{"35"});
    41         
    42         //关闭当前数据库
    43         db.close();
    44         
    45         //删除test.db数据库
    46 //        deleteDatabase("test.db");
    47     }

    在执行完上面的代码后,系统就会在/data/data/[PACKAGE_NAME]/databases目录下生成一个“test.db”的数据库文件,如图:

    上面的代码中基本上囊括了大部分的数据库操作;对于添加、更新和删除来说,我们都可以使用

    1 db.executeSQL(String sql);
    2 db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集

    除了统一的形式之外,他们还有各自的操作方法:

    1 db.insert(String table, String nullColumnHack, ContentValues values);
    2 db.update(String table, Contentvalues values, String whereClause, String whereArgs);
    3 db.delete(String table, String whereClause, String whereArgs);

    以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age > ? and age < ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样。

    下面来说说查询操作。查询操作相对于上面的几种操作要复杂些,因为我们经常要面对着各种各样的查询条件,所以系统也考虑到这种复杂性,为我们提供了较为丰富的查询形式:

    1 db.rawQuery(String sql, String[] selectionArgs);
    2 db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);
    3 db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);
    4 db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

    上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;下面的几种参数都很类似,columns表示要查询的列所有名称集,selection表示WHERE之后的条件语句,可以使用占位符,groupBy指定分组的列名,having指定分组条件,配合groupBy使用,orderBy指定排序的列名,limit指定分页参数,distinct可以指定“true”或“false”表示要不要过滤重复值。需要注意的是,selection、groupBy、having、orderBy、limit这几个参数中不包括“WHERE”、“GROUP BY”、“HAVING”、“ORDER BY”、“LIMIT”等SQL关键字。
    最后,他们同时返回一个Cursor对象,代表数据集的游标,有点类似于JavaSE中的ResultSet。

    下面是Cursor对象的常用方法:

     1 c.move(int offset);    //以当前位置为参考,移动到指定行
     2 c.moveToFirst();    //移动到第一行
     3 c.moveToLast();        //移动到最后一行
     4 c.moveToPosition(int position);    //移动到指定行
     5 c.moveToPrevious();    //移动到前一行
     6 c.moveToNext();        //移动到下一行
     7 c.isFirst();        //是否指向第一条
     8 c.isLast();        //是否指向最后一条
     9 c.isBeforeFirst();    //是否指向第一条之前
    10 c.isAfterLast();    //是否指向最后一条之后
    11 c.isNull(int columnIndex);    //指定列是否为空(列基数为0)
    12 c.isClosed();        //游标是否已关闭
    13 c.getCount();        //总数据项数
    14 c.getPosition();    //返回当前游标所指向的行数
    15 c.getColumnIndex(String columnName);//返回某列名对应的列索引值
    16 c.getString(int columnIndex);    //返回当前行指定列的值

    在上面的代码示例中,已经用到了这几个常用方法中的一些,关于更多的信息,大家可以参考官方文档中的说明。

    最后当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据库连接,否则容易出现SQLiteException。

  • 相关阅读:
    查询类里面对象个数
    动手动脑2
    关于随机数的产生-动手动脑1
    单词频率代码测试
    反码补码报告
    动手动脑课上总结
    java开学第一周测试代码
    【P1825】表达式整除
    工程代码の初體驗
    差分:IncDec Sequence 差分数组
  • 原文地址:https://www.cnblogs.com/wangziqiang/p/4146711.html
Copyright © 2011-2022 走看看