• VS/Xamarin Android开发Follow Me(十)


    SQLiteOpenHelper

    一、前言

    在手机中进行网络连接不仅是耗时也是耗电的,而耗电却是致命的。所以我们就需要数 据库帮助我们存储离线数据,以便在用户未使用网络的情况下也可以能够使用应用的部分功能,而在需要网络连接的功能上采用提示方式,让用户决定是否打开网 络。而本节我们将会学习如何访问数据库以及提供基本的增删改查功能,并且使他们尽量的解耦。

    二、数据库

    Xamarin.Android下创建本地数据库与在Java下的方式相同,而我们必须掌握使用SQLiteOpenHelper,因为这个类会简化我们创建数据的步骤,让我们只需要关注创建数据库中的表,并在数据库版本需要更新时进行操作。其中我们必须实现OnCreate方法和OnUpgrade方法,OnCreate方法仅会在数据库不存在的情况下才执行,所以不会重复执行。比如下面的代码。

     1         class LocationSqliteOpenHelper : SQLiteOpenHelper
     2         {
     3             public override void OnCreate(SQLiteDatabase db)
     4             {
     5             }
     6 
     7             public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
     8             {
     9             }
    10         }

    但是我们还需要使用父类的构造函数,指定数据库的名称以及初始版本。比如下面的代码我们将创建一个名为“test”的数据,并且初始版本为1.。

    1         class LocationSqliteOpenHelper : SQLiteOpenHelper
    2         {
    3             public LocationSqliteOpenHelper(Context context)
    4                 : base(context, “test”, null,1)
    5             {
    6             }
    7         }

    学会了上面的操作,下面我们就可以创建一个名为Test的数据库,并且该数据库中含有一个USER表(SQLite数据库下的主键需要为INTEGER类型,并且是自增的)。

     1     public class TestSQLiteOpenHelper : SQLiteOpenHelper
     2     {
     3         public TestSQLiteOpenHelper(Context context)
     4             : base(context, "Test", null, 1)
     5         {
     6         }
     7 
     8         public override void OnCreate(SQLiteDatabase db)
     9         {
    10             db.ExecSQL("CREATE TABLE USER(id INTEGER PRIMARY KEY NOT NULL,uname TEXT NOT NULL,upwd TEXT NOT NULL)");
    11         }
    12 
    13         public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    14         {
    15             db.ExecSQL("DROP TABLE IF EXISTS USER");
    16             OnCreate(db);
    17         }
    18 }

    创建了数据库对象,下面我们就可以利用这个对象对数据库进行操作了,首先我们需要在MainActivity中的OnCreate方法中初始化该数据库对象。

    TestSQLiteOpenHelper dbHelper = new TestSQLiteOpenHelper(this);

    但是我们还不能直接使用dbHelper访问数据库,必须通过它的WritableDatabase属性或ReadableDatabase属性获取对应权限的数据库访问对象,WritableDataBase可以对数据库进行全部操作,ReadableDatabase可以对数据库进行读取操作。他们的返回类型都是SQLiteDataBase。所以我们还要根据需要获取他们的对象。

    SQLiteDatabase db = dbHelper.WritableDatabase;

    这样我们就可以通过db的InsertUpdateQueryDelete进行操作了,当然也可以使用ExecSQL直接执行我们SQL语句。下面我们将逐一介绍这些方法的使用。

    1.添加(Insert)

    首先是该方法的定义:

    public virtual long Insert(string table, string nullColumnHack, ContentValues values);

    其中参数的含义如下:

    table:需要插入的表名。

    nullColumnHack:当values为空或里面的值都为空时,数据库是不允许插入一个空行的,如果需要插入空行,则需要指定一个字段名称,这样当发生如上情况后将会将该字段设为NULL然后在尝试插入。

    values:需要插入的数据。

    关于前两个参数很简单不用过多介绍,如要介绍的是最后一个参数,它是一个ContentValues类型,通过它我们可以大大的简化自己拼接插入语句的繁琐,比如下面我们可以设置uname字段的值为yzf,upwd的值为123。

    1 ContentValues cv = new ContentValues();
    2 cv.Put("uname","yzf");
    3 cv.Put("upwd","123");

    关键就是Put方法,它拥有以下的重载方法。

    1 public void Put(string key, bool value);
    2 public void Put(string key, byte[] value);
    3 public void Put(string key, double value);
    4 public void Put(string key, float value);
    5 public void Put(string key, int value);
    6 public void Put(string key, long value);
    7 public void Put(string key, sbyte value);
    8 public void Put(string key, short value);
    9 public void Put(string key, string value);

    通过这些重载方法我们就可以插入不同类型的参数了,当然我们也可以通过Remove方法删除,如果我们需要为某个字段插入NULL值可以使用PutNull方法,判断某个字段是否存在可以用ContainsKey方法,最后就是对应的获取不同字段的值。

     1 public Object Get(string key);
     2 public bool GetAsBoolean(string key);
     3 public sbyte GetAsByte(string key);
     4 public byte[] GetAsByteArray(string key);
     5 public double GetAsDouble(string key);
     6 public float GetAsFloat(string key);
     7 public int GetAsInteger(string key);
     8 public long GetAsLong(string key);
     9 public short GetAsShort(string key);
    10 public string GetAsString(string key);

    简单的介绍完ContentValues的使用,下面我们将使用它来添加一条数据,比如下面的代码将添加一条数据到User表中。

    long id = db.Insert("User", null, cv);

    返回值则为所插入数据的主键。

    2.查询(Query)

    首先是该方法的定义:

    1 public virtual ICursor Query(string table, string[] columns, string selection, string[] selectionArgs, string groupBy, string having, string orderBy);
    2 public virtual ICursor Query(string table, string[] columns, string selection, string[] selectionArgs, string groupBy, string having, string orderBy, string limit);
    3 public virtual ICursor Query(bool distinct, string table, string[] columns, string selection, string[] selectionArgs, string groupBy, string having, string orderBy, string limit);

    其中参数的含义如下:

    table:需要查询的表名

    columns:需要获取的字段,如果传入null则表示获取所有字段

    selection:条件语句,其中我们可以实用”?”作为参数的占位符(不同于SQL SERVER中的@)

    selectionArgs:条件参数,用于替换查询语句中的”?”

    groupBy:分组语句

    having:分组条件

    orderBy:排序语句

    limit:分页语句(如”1,3”表示获取第1到第3的数据共3条)

    之前通过Insert插入的数据,此时我们可以通过Query方法从数据库中获取,比如下面的代码

    ICursor ic = db.Query("User", new string[] { "id", "uname", "upwd" }, " id = ? ", new string[] { id.ToString() }, null, null, null);

    该方法最后会返回一个实现了ICursor接口的对象,利用这个接口我们就可以从中获取数据了,下面我们获取其中的用户名和密码

    1 ic.MoveToFirst();
    2 string uname = ic.GetString(ic.GetColumnIndex("uname"));
    3 string upwd = ic.GetString(ic.GetColumnIndex("upwd"));

    因为ICursor是针对一个结果集的,所以我们需要先定位到第一条数据,所以采用MoveToFirst方法,然后通过GetString获取参数,但是还需要传递一个字段的位置,所以我们还需要使用GetColumnIndex获取指定字段名称的位置。

    下面是关于ICursor方法的介绍

    Count:获取多少条数据

    IsAfterLast:当前是否在最后一条数据之后

    IsBeforeFirst:当前是否在第一条数据之前

    IsClosed:是否已关闭

    IsFirst:是否是第一条数据

    IsLast:是否是最后一条数据

    Position:当前位置

    GetColumnIndex:根据字段名获取位置,如果不存在该字段则返回-1

    GetColumnName:根据位置获取字段名

    MoveToFirst:移动到第一条数据

    MoveToFirst:移动到最后一条数据

    MoveToNext:移动到下一条数据

    MoveToPosition:移动指定的位置

    MoveToPrevious:移动到上一条数据

    以下是根据位置获取对应类型的数据

    GetDoubleGetFloatGetIntGetLongGetShortGetString

    3.更新(Update)

    首先是该方法的定义:

    Update(string table, ContentValues values, string whereClause, string[] whereArgs);

    其中参数的含义如下

    table:需要更新的数据所在的表

    values:更新后字段的值

    whereClause:查询语句

    whereArgs:查询语句中需要的参数

    有了插入、查询数据的帮助下,我们可以在插入数据之后更新这条数据,然后再通过Query获取该数据,查看数据的是否变动。

    1 ContentValues ncv = new ContentValues();
    2 ncv.Put("uname", "zn");
    3 ncv.Put("upwd", "456");
    4 db.Update("User", ncv, " id = ? ", new string[] { id.ToString() });

    这里的条件语句跟查询中的语句是类似的,然后我们查看获取的数据可以发觉的确发生了修改。

    4.删除(Delete)

    首先是该方法的定义:

    public virtual int Delete(string table, string whereClause, string[] whereArgs);

    关于参数的说明跟Update是相同的,所以实用方式这里就不做介绍了。

    全部实例的全部代码如下所示:

    TestSQLiteOpenHelper.cs

     1     public class TestSQLiteOpenHelper : SQLiteOpenHelper
     2     {
     3         public TestSQLiteOpenHelper(Context context)
     4             : base(context, "Test", null, 1)
     5         {
     6         }
     7 
     8         public override void OnCreate(SQLiteDatabase db)
     9         {
    10             db.ExecSQL("CREATE TABLE USER(id INTEGER PRIMARY KEY NOT NULL,uname TEXT NOT NULL,upwd TEXT NOT NULL)");
    11         }
    12 
    13         public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    14         {
    15             db.ExecSQL("DROP TABLE IF EXISTS USER");
    16             OnCreate(db);
    17         }
    18 }

    MainActivityOnCreate

     1             TestSQLiteOpenHelper dbHelper = new TestSQLiteOpenHelper(this);
     2             SQLiteDatabase db = dbHelper.WritableDatabase;
     3             
     4             ContentValues cv = new ContentValues();
     5             cv.Put("uname","yzf");
     6             cv.Put("upwd","123");
     7             long id = db.Insert("User", null, cv);
     8 
     9             ContentValues ncv = new ContentValues();
    10             ncv.Put("uname", "zn");
    11             ncv.Put("upwd", "456");
    12             db.Update("User", ncv, " id = ? ", new string[] { id.ToString() });
    13 
    14             ICursor ic = db.Query("User", new string[] { "id", "uname", "upwd" }, " id = ? ", new string[] { id.ToString() }, null, null, null);
    15             ic.MoveToFirst();
    16             string uname = ic.GetString(ic.GetColumnIndex("uname"));
    17             string upwd = ic.GetString(ic.GetColumnIndex("upwd"));

    今天就到这里……

  • 相关阅读:
    10-02 青蛙跳台阶(斐波那契数列的应用)
    10-01 斐波那契数列
    08 二叉树的下一个节点
    07 重建二叉树
    Java中如何调用静态方法
    Java中如何调用静态方法
    Java方法调用数组,是否改变原数组元素的总结
    Java方法调用数组,是否改变原数组元素的总结
    JAVA中,一个类中,方法加不加static的区别,
    JAVA中,一个类中,方法加不加static的区别,
  • 原文地址:https://www.cnblogs.com/xtxk110/p/12174952.html
Copyright © 2020-2023  润新知