游戏技术文章

数据存储-SQLite基本操作

时间:2017-4-8 10:41:45  作者:棋牌资源网  来源:棋牌资源网  查看:9070  评论:0
内容摘要:1. 数据类型  与其它数据库不同,SQLite的数据类型很简单,只有NULL(空类型)、INTEGER(整型)、REAL(浮点型)、TEXT(字符串型)、BLOB(二进制型)。  SQLite为动态数据类型(弱引用),当向数据库中插入某个...

1. 数据类型

  与其它数据库不同,SQLite的数据类型很简单,只有NULL(空类型)、INTEGER(整型)、REAL(浮点型)、TEXT(字符串型)、BLOB(二进制型)。

  SQLite为动态数据类型(弱引用),当向数据库中插入某个值时,会检查该值的类型,若类型与插入列不匹配,SQLite会尝试将该值转换成相应类型。

2. 创建数据库

  学习SQLite的数据库操作需要对SQL有一定了解,若完全不了解,建议先看一下数据库的基础语法知识:

  MySQL入门笔记(一)

  MySQL入门笔记(二)

  Android中提供了一个SQLiteOpenHelper类,使用该类可非常方便地进行数据库的创建与升级。

  SQLiteHelper是一个抽象类,使用该类必须另外写一个类去继承自它,并实现两个关键的抽象方法onCreate()、onUpgrade(),这两个方法分别用于数据库的创建与升级。

  SQLiteOpenHelper类中提供了两个构造函数可供重写,一般重写4个参数那个即可,其中第一个参数是context,第二个参数是数据库的名称,第三个参数允许在查询数据时返回一个自定义的Cursor,一般传入null,第四个参数是数据库版本号,用于数据库的升级操作。

  在写好自定义的帮助类后,在活动类中进行实例化,再调用它的getReadableDtabase()或者getWritableDatabase()方法即可创建数据库。

  另外,有不少人使用operOrCreateDatabase方法进行数据库的创建,如有兴趣,可前往这篇文章了解:Context与SQLiteDatabase的方法openOrCreateDatabase的区别 (context、SQLiteOpenHelper)

范例:

布局文件(本文后续例子中继续沿用此布局):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="15dp"
    tools:context="com.studying.myapplication.MySQLiteActivity">

    <Button
        android:id="@+id/create_database"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Create Database" />

    <Button
        android:id="@+id/add_data"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:text="Add Data" />

    <Button
        android:id="@+id/delete_data"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:text="Delete Data" />

    <Button
        android:id="@+id/update_data"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:text="Update Data" />

    <Button
        android:id="@+id/query_data"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:text="Query Data" />
</LinearLayout>

SQLiteOpenHelper实现类:

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    //将建表语句定义为字符常量
    public static final String CREATE_BOOK = "create table BOOK ("
            + "id integer primary key autoincrement, " 
            + "name text, " 
            + "author text)";
    private Context mContext;

    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据表
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "创建成功!", Toast.LENGTH_SHORT).show();
    }

    //用于升级数据库,请见下一例子
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

活动类:

public class MySQLiteActivity extends Activity implements View.OnClickListener{

    private MySQLiteOpenHelper mHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_sqlite);
        
        //实例化帮助类
        mHelper = new MySQLiteOpenHelper(this, "BookStore.db", null, 1);
        Button createDb = (Button) findViewById(R.id.create_database);
        createDb.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.create_database:
                //创建或打开数据库
                mHelper.getWritableDatabase();
                break;
        }
    }
}

3. 升级数据库

  上面提到过,升级数据库(通常发生在app更高版本的覆盖安装)需要通过帮助类的onUpgrade()方法实现,而不能直接在onCreate()方法中直接执行修改语句。这是因为onCreate()方法尽在当前数据库未创建的情况下才会调用,若数据库已经存在,则不会再次调用该方法。此时,我们就需要通过onUpgrade()方法实现数据库的升级。

  当实例化帮助类时传入的数据库版本号比上一次传入的大时,onUpgrade()方法就会被调用。因此,在升级数据库时,在onUpgrade()方法中写入改变的内容,而后在活动类中更改传入的版本号即可。

范例1:

  在上面例子的基础上增加一张CATEGORY表。

自定义帮助类:

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table BOOK ("
            + "id integer primary key autoincrement, "
            + "name text, "
            + "author text)";
    //升级测试用建表语句
    public static final String CREATE_CATEGORY = "create table CATEGORY ("
            + "id integer primary key autoincrement, "
            + "category_name text,"
            + "category_code integer)";
    private Context mContext;

    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //如果用户当前是初次安装本程序,即数据库未被创建,则直接创建两个表
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "创建成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        switch (oldVersion) {
            case 1:
                //若用户是覆盖安装,并且当前已创建的数据库版本为1,则仅创建CATEGORY表
                db.execSQL(CREATE_CATEGORY);
            default:
        }
    }
}

活动类:

public class MySQLiteActivity extends Activity implements View.OnClickListener{

    private MySQLiteOpenHelper mHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_sqlite);

        //活动类仅需在实例化时将版本号增大
        mHelper = new MySQLiteOpenHelper(this, "BookStore.db", null, 2);
        Button createDb = (Button) findViewById(R.id.create_database);
        createDb.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.create_database:
                mHelper.getWritableDatabase();
                break;
        }
    }
}

  这里注意一个细节,onUpgrade()方法中的switch语句里的每一个分支都并没有break,这是为了保证在跨版本升级时能顺利依次完成中间的所有升级。例如从版本1直接升级到版本3时,就会依次进行2和3的升级。

范例2:

  在范例1的基础上给BOOK表增加一个category_id字段。

帮助类:

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table BOOK ("
            + "id integer primary key autoincrement, "
            + "name text, "
            + "author text, "
            + "category_id integer)";//增加一个字段
    public static final String CREATE_CATEGORY = "create table CATEGORY ("
            + "id integer primary key autoincrement, "
            + "category_name text,"
            + "category_code integer)";
    private Context mContext;

    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //如果用户当前是初次安装本程序,即数据库未被创建,则直接创建两个表
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "创建成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //没有break,如果用户直接从第一版app升级到第三版app,则依次执行case 1和case 2。
        switch (oldVersion) {
            case 1:
                db.execSQL(CREATE_CATEGORY);
            case 2:
                db.execSQL("alter table BOOK column category_id integer");
            default:
        }
    }
}

4. 数据操作

  上面已经学习了如何使用SQLiteOpenHelper类进行数据库的创建和升级,但是我们并没有使用到调用getReadableDatabase()或者getWritableDatabase()方法时返回的SQLiteDatabase对象,而这一对象,就是用来对数据进行“增删改查”操作的。

4.1 添加数据

insert(String table, String nullColumnHack, ContentValues values)

  table:指定插入记录的表。

  nullColumnHack:若某些允许为空的列没有赋值,则自动赋值为null,传入null即可。

  values:ContentValues对象,相当于一个容器的作用,可通过它的put(key, values)方法(key为列名称,values为该列的值)将每一行的数据一一添加,而后再传入数据库。注意当插入多条记录时,每两次插入之间要调用clear()方法进行清空。

范例:

帮助类:(后面的删改查将沿用该帮助类)

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table BOOK ("
            + "id integer primary key autoincrement, "
            + "name text, "
            + "author text)";
    private Context mContext;

    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "创建成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

活动类:

public class MySQLiteActivity extends Activity implements View.OnClickListener{

    private MySQLiteOpenHelper mHelper;
    private SQLiteDatabase mDb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_sqlite);

        mHelper = new MySQLiteOpenHelper(this, "BookStore.db", null, 1);
        Button createDb = (Button) findViewById(R.id.create_database);
        createDb.setOnClickListener(this);
        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            //省略创建数据库分支
            case R.id.add_data:
                //获取SQLiteDatabase对象
                mDb = mHelper.getWritableDatabase();
                
                //实例化ContentValues对象并进行数据组装
                ContentValues values = new ContentValues();
                values.put("name", "A");
                values.put("author", "aa");
                //插入数据
                mDb.insert("BOOK", null, values);
                //若需要插入多条记录,在这一步一定要调用values的clear()方法清空现有的数据
                values.clear();
                
                values.put("name", "B");
                values.put("author", "bb");
                mDb.insert("BOOK", null, values);
                values.clear();
                
                values.put("name", "C");
                values.put("author", "cc");
                mDb.insert("BOOK", null, values);
                break;
        }
    }
}

4.2 删除数据

delete(String table, String whereClause, String[] whereArgs)

  whereClausewhereArgs:指定删除条件,若不指定则删除表中所有数据。相当于将一个条件语句拆分成两部分,第二个参数是用占位符替代了具体值的条件语句,第三个参数则是条件语句的值,例如将age > 30的记录删除,则第二个参数为"age > ?",第三个参数为new String[] {"30"}。

范例:

活动类:

public class MySQLiteActivity extends Activity implements View.OnClickListener{

    private MySQLiteOpenHelper mHelper;
    private SQLiteDatabase mDb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_sqlite);

        mHelper = new MySQLiteOpenHelper(this, "BookStore.db", null, 1);
        Button createDb = (Button) findViewById(R.id.create_database);
        createDb.setOnClickListener(this);
        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(this);
        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            //省略其它几个分支
            case R.id.delete_data:
                mDb = mHelper.getWritableDatabase();
                
                //删除数据,?是一个占位符,第二、第三个参数合起来即删除id > 2的记录
                mDb.delete("BOOK", "id > ?", new String[] {"2"});
                break;
        }
    }
}

4.3 更新数据

update(String table, ContentValues values, String whereClause, String[] whereArgs)

  这里的四个参数相信大家已经很熟悉了,第一个为表名,第二个为ContentValues对象,装载更新数据,第三、第四个则为约束条件,指定更新的行,若不指定则更新全部行。

范例:

活动类:

public class MySQLiteActivity extends Activity implements View.OnClickListener{

    private MySQLiteOpenHelper mHelper;
    private SQLiteDatabase mDb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_sqlite);

        mHelper = new MySQLiteOpenHelper(this, "BookStore.db", null, 1);
        Button createDb = (Button) findViewById(R.id.create_database);
        createDb.setOnClickListener(this);
        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(this);
        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(this);
        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            //省略其它几个分支
            case R.id.update_data:
                mDb = mHelper.getWritableDatabase();

                ContentValues values = new ContentValues();
                //需要改哪一列数据就添加哪一列的,不一定要全部
                values.put("name", "D");

                mDb.update("BOOK", values, "id < ?", new String[] {"3"});
                break;
        }
    }
}

4.4 查询数据

query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

  如果你学过SQL语言的话,相信对上面这一看起来非常复杂的参数列表是比较熟悉的,里面的参数基本上都可以与SQL中的select语句的修饰符对应上。调用query()方法会返回一个Cursor对象,里面含有所有查询结果。

  table:对应SQL中的from table_name,指定查询的表名。

  columns:对应select column1, column2, ...,指定查询的列名称。

  selection:对应where column = value,指定查询的行的约束条件。

  selectionArgs:为selection重的占位符(?)提供具体值。

  groupBy:对应group by column,指定对哪一列进行分组。

  having:对应having column = value,进一步对分组后的结果进行约束。

  orderBy:对应order by column1, column2, ...,指定查询结果的排序方式。

  这里仅介绍最简单的查询,后面几个参数的使用可先前往了解SQL的语法:MySQL入门笔记(一)

范例:

活动类:

public class MySQLiteActivity extends Activity implements View.OnClickListener{

    private MySQLiteOpenHelper mHelper;
    private SQLiteDatabase mDb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_sqlite);

        mHelper = new MySQLiteOpenHelper(this, "BookStore.db", null, 1);
        Button createDb = (Button) findViewById(R.id.create_database);
        createDb.setOnClickListener(this);
        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(this);
        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(this);
        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(this);
        Button queryData = (Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            //省略其它几个分支
            case R.id.query_data:
                mDb = mHelper.getWritableDatabase();
                //查询BOOK中所有数据
                Cursor cursor = mDb.query("BOOK", null, null, null, null, null, null);
                if (cursor.moveToFirst()) {
                    do {
                        //遍历cursor,取出数据
                        int id = cursor.getInt(cursor.getColumnIndex("id"));
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        String author = cursor.getString(cursor.getColumnIndex("author"));
                        //打印数据
                        Log.d("MySQLiteData", id + ". 《" + name + "》  " + author);
                    }while (cursor.moveToNext());
                    //关闭Cursor对象
                    cursor.close();
                }
                break;
        }
    }
}

5. 事务

  SQLite是支持事务的,那么什么是事务呢?试想,假设有个数据表中的数据都很旧了,现在要将其全部替换成新的,就要先删除旧数据,而后再插入新数据。但是在过程中出现了异常,旧数据被删除之后,新数据没有成功插入,那这一个数据表的信息就全没了。而事务的特性就是保证某一个系列的操作,或者全部完成,或者全部不完成。也就是如果前面替换数据这一系列操作放在事务中进行,则要么数据替换成功,表内全部换成新数据,要么失败,保留旧数据,不会出现删了旧数据,但是没插入新数据的情况。

  事务的使用方法比较简单,以下是Android中事务的标准用法:

//第一步,开启事务,db为SQLiteDatabase对象
db.beginTransaction();
try {
    //在异常捕获的代码块中进行具体的操作
    //在全部操作结束后将事务设置为成功
    db.setTransactionSuccessful();
} catch (Exception e) {
    e.printStackTrace();
} finally (
    //结束事务
    db.endTransaction();
)
标签:数据存储SQLite基本操作 

欢迎加入VIP,【VIP售价:只要288元永久VIP会员】畅享商业棋牌游戏程序下载,点击开通!

下载说明


☉本站所有源码和资源均由站长亲自测试-绝对保证都可以架设,运营!
☉如源码和资源有损坏或所有链接均不能下载,请告知管理员,

☉本站软件和源码大部分为站长独资,资源购买和收集,放心下载!

☉唯一站长QQ:1004003180  [人格担保-本站注重诚信!]

☉购买建议E-mail:1004003180@qq.com   源码收购 E-mail:1004003180@qq.com    

☉本站文件解压密码  【文章内都自带解压密码,每个密码不同!】


本站提供的所有源码,均来源站长提供,仅学习交流 浙ICP备09009969号

由此产生不良后果和法律责任与本站无关,如果侵犯了您的版权,请来信告知 1004003180@qq.com 将及时更正和删除! 

Copyright © 2008-2022 棋牌资源网,你身边的棋牌资源下载站    All Rights Reserved