2018/4/15 15:02:12当前位置推荐好文程序员浏览文章

SQLite 是一款轻量级的关系型数据库,它的运算速度非常快, 占消耗资源很少,通常只要几百 K 的内存就足够了,因此特别适合在移动设施上使消耗。它不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务。这套数据库可是内置于 Android 系统中的哦O(∩_∩)O哈哈~

当需要存储大量复杂的关系型数据时,就要消耗到关系型数据库啦。

1 创立数据库

Android 提供了一个 SQLiteOpenHelper 帮助类,借助这个类能非常简单地对数据库进行创立与更新。

SQLiteOpenHelper

SQLiteOpenHelper 是一个笼统类,所以我们需要创立一个类去继承它并且重写它的两个笼统方法,即 onCreate() 和 onUpgrade(),去实现创立、更新数据库的逻辑。

创立或者打开一个现有的数据库(若已存在则打开,否则创立一个新库),并返回一个可对数据库进行读写操作的对象的实例方法有两种(getReadableDatabase、getWriableDatabase),它们之间的区别是,当数据库不可写入的情况下(如磁盘空间已满):

方法区别
getReadableDatabase()返回的对象将以只读的方式去打开数据库。
getWriableDatabase()抛出异常。

SQLiteOpenHelper 中的一个构造函数是这样的:

SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version)
参数说明
context上下文
name数据库名
factory自己设置游标,不需要就传入 null
version当前数据库的版的本号,消耗于更新数据库

构建出 SQLiteOpenHelper 的实例后,再调消耗它的 getReadableDatabase() 或者 getWritableDatabase() 方法就可以够创立数据库咯,数据库文件会存放在 /data/data/<package name>/databases/ 的目录下。 此时,重写的 onCreate() 方法也会得到执行,能在这里解决少量创立表的逻辑。

假设我们需要建立一个名为 People.db 的数据库,而后在这个数据库中新建一张 people 表,表中有 id(主键)、名字、年龄、体重等字段。建表语句如下:

create table people( id integer primary key autoincrement,name text,age integer,weight real)
数据类型说明
integer整型
real浮点型
text文本类型
blob二进制类型

primary key autoincrement:表示设置某个字段为主键并且自增长。

PeopleDatabaseHelper 类:

public class PeopleDatabaseHelper extends SQLiteOpenHelper {    /      建表语句     /    public static final String CREATE_SQL="create table people( id integer primary key autoincrement,name text,age integer,weight real)";    private Context context;    public PeopleDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version);        this.context=context;    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL(CREATE_SQL);        Toast.makeText(context, "建表成功", Toast.LENGTH_SHORT).show();    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}

我们在 onCreate 方法中 使消耗了 execSQL 来执行建表语句 ,这样即可以在创立数据库之后,创立需要的表。

调消耗语句:

 final PeopleDatabaseHelper helper=new PeopleDatabaseHelper(this,"People.db",null,1);helper.getWritableDatabase();

能使消耗 adb shell 来查看数据库与表的创立情况。

adb 是 Android SDK 自带的调试工具,能直接对连接在电脑上的手机或者者模拟器进行开发调试工作。它的安装方法请参见 在 Android Device Monitor 的 File Explorer 中,无法打开某些文件夹的处理方法

在命令行界面,使消耗命令 adb shell 进入设施控制台(先使消耗 adb root 取得访问权限):

设施控制台

进入目录命令的格式为:

cd /data/data/[包名]/databases/

这里为 cd /data/data/net.deniro.android.databasetest/databases/

进入目录

使消耗命令 ls 查看当前目录下的文件:

.db:是我们创立的数据库。
.db-journal:是为了让数据库可以够支持事务所产生的临时日志文件,一般情况下,它为 0 字节。

使消耗 sqlite3 数据库名 来打开数据库,并使消耗 .table 命令来查看目前的数据库中有哪些表:

使消耗命令 .schema 能查看这些表的创立语句:

键入 .exit 或者 .quit 即可以退出 sqlite,再次键入 .exit 就会退出设施控制台,是不是很简单呀O(∩_∩)O哈哈~

2 更新数据库

能在继承自 SQLiteOpenHelper 类的 onUpgrade 方法中,对数据库进行更新。

假设我们需要新添加一张行业表,建表语句为:

create table Industry(  id integer primary key autoincrement,  industry_name text,  industry_code integer)

修改原来的代码:

/  创立行业表 /public static final String CREATE_INDUSTRY_SQL = "create table Industry(  id integer primary key autoincrement,  industry_name text,  industry_code integer)"; @Overridepublic void onCreate(SQLiteDatabase db) {    db.execSQL(CREATE_PEOPLE_SQL);    db.execSQL(CREATE_INDUSTRY_SQL);    Toast.makeText(context, "建表成功", Toast.LENGTH_SHORT).show();}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    dropTable(db, "People");    dropTable(db, "Industry");    onCreate(db);}/  删除表   @param db  @param tableName 表名称  @return /private void dropTable(SQLiteDatabase db, String tableName) {    db.execSQL("drop table if exists " + tableName);}

这里首先在 onCreate 方法中,创立行业表;接着在 onUpgrade 方法中,删除相应的表,并调消耗 onCreate,重新创立表结构。

最后在 PeopleDatabaseHelper 的构造函数中,把版的本号(最后一个参数)改为 2:

创立成功后,能通过之前详情的 adb shell 方法查看新创立的表结构:


3 新添加数据

对数据进行的操作一般有四种,即 CRUD:增加(Create),查询(Retrieve),升级(Update),删除(Delete)。

SQLiteOpenHelper 中的 getReadableDatabase() 或者 getWritableDatabase() 方法都会返回一个 SQLiteDatabase 对象,借助这个对象能对数据进行 CRUD 操作。

SQLiteDatabase 类包含 方法:

public long insert(String table, String nullColumnHack, ContentValues values)
参数名说明
table表名
nullColumnHack在未指定增加数据的情况下给某些可为空的列自动赋值,一般传入 null。
values是一个ContentValues 对象,它包含一系列的 put() 方法重载,消耗于向 ContentValues 中增加数据(列名与列的内容逐个对应)。

新添加操作:

SQLiteDatabase db= helper.getWritableDatabase();//新添加ContentValues values=new ContentValues();values.put("name","deniro");values.put("age",22);values.put("weight",70);db.insert("People",null,values);

由于 id 为自增长的列,所以这里毋庸赋值。

查看结果:

 from People;

4 升级数据

SQLiteDatabase 类包含 方法:

public int update(String table, ContentValues values, String whereClause, String[] whereArgs) 
参数名说明
table表名
valuesContentValues 对象,存放要升级的数据
whereClausewhere SQL 语句(占位符形式)
whereArgswhere SQL 语句中的参数,与语句中的占位符逐个对应

调消耗代码:

SQLiteDatabase db= helper.getWritableDatabase();//修改ContentValues values=new ContentValues();values.put("age",24);db.update("People",values,"name = ?",new String[]{"deniro"});

这里把所有 name = deniro 的数据中的 age 都升级为 24。

升级结果:


5 删除数据

SQLiteDatabase 类中包含 方法来删除数据:

public int delete(String table, String whereClause, String[] whereArgs) 
参数名说明
table表名
whereClausewhere SQL 语句(占位符形式)【可选】
whereArgswhere SQL 语句中的参数,与语句中的占位符逐个对应【可选】

调消耗代码:

SQLiteDatabase db = helper.getWritableDatabase();//删除db.delete("People", "name = ?", new String[]{"deniro"});

执行后,在 sqlite 命令中就会发现,数据被删除咯。

6 查询数据

SQLiteDatabase 中提供了 query() 方法消耗于查询数据。 这个方法的参数非常复杂,最短的一个方法重载也需要传入七个参数。

query 的各种重载方法
 public Cursor query(String table, String[] columns, String selection,            String[] selectionArgs, String groupBy, String having,            String orderBy)
参数名说明示例
table表名from table_name
columns列名column1,column2
selectionwhere 条件where column = value
selectionArgswhere 条件中的占位符参数值-
groupBy需要分组的列group by column
having分组条件having column = value
orderBy排序条件order by column1,column2

返回 Cursor 对象,查询到的数据能从这个对象中取出。

调消耗代码:

SQLiteDatabase db = helper.getWritableDatabase();//查询Cursor cursor = db.query("People", null, null, null, null, null, null);if (cursor.moveToFirst()) {    do {        Log.d(TAG, "name: " + cursor.getString(cursor.getColumnIndex("name")));        Log.d(TAG, "age: " + cursor.getInt(cursor.getColumnIndex("age")));    } while (cursor.moveToNext());}cursor.close();

得到 Cursor 对象后,使消耗 moveToFirst 把数据指针移到第一行,而后进入循环。getColumnIndex 获取某一列在表中的位置索引,而后把这个索引传入相应类型的取值方法中(比方 int 型,使消耗 getInt 方法),即可以读取数据啦。最后记得关闭 cursor。

7 使消耗原生 SQL 操作数据库

我们也能直接使消耗原生 SQL 来完成前面说过的新添加、修改与删除操作,这就是 SQLiteDatabase 类中的 execSQL 方法:

public void execSQL(String sql, Object[] bindArgs)
参数名说明
sqlSQL 语句
bindArgs占位符绑定的参数

查询数据能使消耗 SQLiteDatabase 类中的 rawQuery方法:

 public Cursor rawQuery(String sql, String[] selectionArgs)

参数说明与 execSQL 方法相似,是不是很简单呀O(∩_∩)O哈哈~

上一篇: ansible实现lamp
下一篇:3分钟搞掂Set集合
网友评论