Android-SQLite数据库实例

简介: 使用SQLite保存数据SQL的基本语法数据库帮助器SQLiteOpenHelper继承SQLiteOpenHelper类,重写onCreate、onUpgrade、onOpen方法创建表删除表打开数据库表关闭数据库添加数据修改数据查找数据删除数据各参数说明使用游标项目实例:SQLiteDemo.zip

 Android提供了5种方式来让用户保存持久化应用程序数据。根据自己的需求来做选择,比如数据是否是应用程序私有的,是否能被其他程序访问,需要多少数据存储空间等,分别是: 


       ①使用SharedPreferences存储数据 


       ②文件存储数据


     ③SQLite数据库存储数据

       ④使用ContentProvider存储数据


       ⑤网络存储数据 


使用SQLite保存数据


       对于重复数据或结构化数据(例如联系信息),将数据保存到数据库是理想选择。下面咱咱就开始在Android上使用 SQLite 数据库。android.database.sqlite软件包中提供了在Android上使用数据库所需的API。


       咱先玩玩SQLite数据库,后面咱从SQLite迁移到Room。


      注意:虽然这些API功能强大,但它们的级别较低,使用起来需要花费大量时间和精力:


  • 没有针对原始SQL查询的编译时验证。随着数据图表不断发生变化,你需要手动更新受影响的SQL查询。此过程既耗时又容易出错。
  • 你需要使用大量样板代码,在SQL查询和数据对象之间进行转换。


       出于这些原因,咱强烈建议将Room持久性库用作抽象层以访问应用的SQLite数据库中的信息。


SQL的基本语法


       SQL本质上是一种编程语言,它的学名叫作“结构化查询语言”(全称为StructuredQuery Language,简称SQL)。不过SQL语言并非通用的编程语言,它专用于数据库的访问和处理,更像是一种操作命令,所以常说SQL语句而不说SQL代码。标准的SQL语句分为3类:数据定义、数据操纵和数据控制,但不同的数据库往往有自己的实现。


      SQLite是一种小巧的嵌入式数据库,使用方便、开发简单。如同MySQL、Oracle那样,SQLite也采用SQL语句管理数据,由于它属于轻型数据库,不涉及复杂的数据控制操作,因此App开发只用到数据定义和数据操纵两类SQL。此外,SQLite的SQL语法与通用的SQL语法略有不同。


数据库帮助器SQLiteOpenHelper


       由于SQLiteDatabase存在局限性,一不小心就会重复打开数据库,处理数据库的升级也不方便;因此Android提供了数据库帮助器SQLiteOpenHelper,帮助开发者合理使用SQLite。


SQLiteOpenHelper的具体使用步骤如下:


      步骤1:新建一个继承自SQLiteOpenHelper的数据库操作类,按提示重写onCreate和onUpgrade两个方法。其中,onCreate方法只在第一次打开数据库时执行,在此可以创建表结构;而onUpgrade方法在数据库版本升高时执行,在此可以根据新旧版本号变更表结构。


      步骤2:为保证数据库安全使用,需要封装几个必要方法,包括获取单例对象.打开数据库连接、关闭数据库连接,说明如下:


  • 获取单例对象:确保在App运行过程中数据库只会打开一次,避免重复打开引起错误。
  • 打开数据库连接:SQLite有锁机制,即读锁和写锁的处理;故而数据库连接也分两种,读连接可调用getReadableDatabase方法获得,写连接可调用getWritableDatabase获得。
  • 关闭数据库连接:数据库操作完毕,调用数据库实例的close方法关闭连接。


      步骤3:提供对表记录增加、删除、修改、查询的操作方法。


继承SQLiteOpenHelper类,重写onCreate、onUpgrade、onOpen方法


public class UserDBHelper extends SQLiteOpenHelper {
    private static final String DB_NAME = "user.db";//数据库的名称
    private static UserDBHelper mHelper = null;//数据库帮助器的实例
    private SQLiteDatabase mDB = null;//数据库的实例
    public static final String TABLE_NAME = "user_info";
    public static final String _ID = "_id";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_AGE = "age";
    public static final String COLUMN_UPDATE_TIME = "update_time";
    /**
     * @param context 上下文环境(例如,一个 Activity)
     *                DB_NAME  数据库名字
     *                factory  null  一个可选的游标工厂(通常是 Null)
     * @param version 数据库模型版本的整数
     *                会调用父类 SQLiteOpenHelper的构造函数
     */
    public UserDBHelper(Context context, int version) {
        super(context, DB_NAME, null, version);
    }
    //利用单例模式获取SQLiteOpenHelper的唯一实例
    public static UserDBHelper getInstance(Context context, int version) {
        if (version > 0 && mHelper == null) {
            mHelper = new UserDBHelper(context, version);
        }
        return mHelper;
    }
    //创建数据库表,执行建表语句
    @Override
    public void onCreate(SQLiteDatabase db) {
    }
    /**
     * 当数据库需要修改的时候(两个数据库版本不同),Android系统会主动的调用这个方法。
     * 一般我们在这个方法里边删除数据库表,并建立新的数据库表.
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
    @Override
    public void onOpen(SQLiteDatabase db) {
        //每次成功打开数据库后首先被执行
        super.onOpen(db);
    }
}


创建表


       表格的创建动作由create命令完成,格式为“CREATE TABLE IFNOT EXISTS表格名称(以逗号分隔的各字段定义);”。以用户信息表为例,它的建表语句如下所示:


//创建数据库表,执行建表语句
@Override
public void onCreate(SQLiteDatabase db) {
    Log.e(getClass().getName(), "onCreate");
    //创建表语句
    String SQL_CREATE_ENTRIES = "CREATE TABLE IF NOT EXISTS "
            + TABLE_NAME + "("
            + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
            + COLUMN_NAME+" VARCHAR NOT NULL,"
            + COLUMN_AGE+" INTEGER NOT NULL,"
            + COLUMN_UPDATE_TIME+" VARCHAR NOT NULL" + "); ";
    //执行完整的sQL语句
    db.execSQL(SQL_CREATE_ENTRIES);
}


上面的SQL语法与其他数据库的SQL语法有所出入,相关的注意点说明见下:


       ①SQL语句不区分大小写,无论是create与table这类关键词,还是表格名称、字段名称,都不区分大小写。唯一区分大小写的是被单引号括起来的字符串值。


       ②为避免重复建表,应加上IF NOT EXISTS关键词,例如CREATE TABLE IFNOT EXISTS表格名称......


       ③SQLite支持整型INTEGER、长整型LONG、字符串VARCHAR、浮点数FLOAT,但不支持布尔类型。布尔类型的数据要使用整型保存,如果直接保存布尔数据,在入库时sQLite会自动将它转为0或1,其中0表示false,1表示true。


       ④建表时需要唯一标识字段,它的字段名为_id。创建新表都要加上该字段定义,例如_id lNTEGER PRIMARY KEY AUTOINCREMENT NOT NULL。


删除表


       表格的删除动作由drop命令完成,格式为“DROP TABLE IFEXISTS表格名称;”。下面是删除用户信息表的SQL语句例子:


//删除表
public void deleteTable(SQLiteDatabase db) {
    String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + TABLE_NAME;
    db.execSQL(SQL_DELETE_ENTRIES);
}


打开数据库表


       下面这段代码会返回一个 SQLiteDatabase 类的实例,使用这个对象,你就可以查询或者修改数据库。 


1.//打开数据库的读连接(查询数据库)
public SQLiteDatabase openReadLink() {
    if (mDB == null || !mDB.isOpen()) {
        mDB = mHelper.getReadableDatabase();
    }
    return mDB;
}
//打开数据库的写连接(可写数据库)
public SQLiteDatabase openwriteLink() {
    if (mDB == null || !mDB.isOpen()) {
        mDB = mHelper.getWritableDatabase();
    }
    return mDB;
}


关闭数据库


//由于在数据库关闭时,调用getWritableDatabase()和getReadableDatabase()的成本比较高,
// 因此只要您有可能需要访问数据库,就应保持数据库连接处于打开状态。通常情况下,
// 最好在发出调用的Activity的onDestroy()中关闭数据库。
@Override
protected void onDestroy() {
    userDBHelper.closeLink();
    super.onDestroy();
}


添加数据


       使用 SQLiteDatabase 对象的insert()。


//往该表添加多条记录
public long insert(List<UserInfoBean> infoList) {
    long result = -1;
    for (int i = 0; i < infoList.size(); i++) {
        UserInfoBean info = infoList.get(i);
        //不存在唯一性重复的记录,则插入新记录
        ContentValues cv = new ContentValues();
        cv.put(_ID, info.get_id());
        cv.put(COLUMN_NAME, info.getName());
        cv.put(COLUMN_AGE, info.getAge());
        cv.put(COLUMN_UPDATE_TIME, info.getUpdate_time());
        //执行插入记录动作,该语句返回插入记录的行号
        result = mDB.insert(TABLE_NAME, "", cv);
        if (result == -1) {//添加成功则返回行号,添加失败则返回-1
            return result;
        }
    }
    return result;
}


 方法使用:


List<UserInfoBean> list = new ArrayList<>();
list.add(new UserInfoBean("10", "帅次次", 20, "09:00"));
list.add(new UserInfoBean("12", "朱元璋", 30, "11:00"));
list.add(new UserInfoBean("15", "赵匡胤", 40, "13:00"));
list.add(new UserInfoBean("18", "李世民", 50, "15:00"));
long l = userDBHelper.insert(list);
tv_sql.setText("插入成功:" + l);


微信图片_20220520113215.png


修改数据


       使用SQLiteDatabase 对象的update()方法。


1.//根据条件更新指定的表记录
public int update(UserInfoBean info, String condition) {
    ContentValues cv = new ContentValues();
    cv.put(COLUMN_NAME, info.getName());
    cv.put(COLUMN_AGE, info.getAge());
    cv.put(COLUMN_UPDATE_TIME, info.getUpdate_time());
    //执行更新记录动作,该语句返回更新的记录数量
    return mDB.update(TABLE_NAME, cv, condition, null);
}


方法使用:


UserInfoBean bean = new UserInfoBean("武媚娘", 32,"12:00");
userDBHelper.update(bean, "_id=18");


微信图片_20220520113327.png


查找数据


       使用SQLiteDatabase 对象的query()方法。


//根据指定条件查询记录,并返回结果数据列表
public List<UserInfoBean> query() {
    List<UserInfoBean> infoList = new ArrayList<UserInfoBean>();
    //执行记录查询动作,该语句返回结果集的游标
    //SELECT语句内容作为 query()方法的参数,比如:要查询的表名,要获取的字段名,WHERE条件,
    //包含可选的位置参数,去替代WHERE条件中位置参数的值,GROUP BY条件,HAVING条件。
    //除了表名,其他参数可以是null
    Cursor cursor = mDB.query(TABLE_NAME, null, null, null, null, null, null);
    //循环取出游标指向的每条记录
    while (cursor.moveToNext()) {
        UserInfoBean info = new UserInfoBean();
        info._id = cursor.getString(0);//取出字符串
        info.name = cursor.getString(1);//取出字符串
        info.age = cursor.getInt(2);//取出整型数
        info.update_time = cursor.getString(3);//取出字符串
        infoList.add(info);
    }
    cursor.close();
    // 查询完毕,关闭数据库游标
    return infoList;
}


 方法使用:


userDBHelper.query();


微信图片_20220520113430.png


删除数据


       使用SQLiteDatabase 对象的delete()方法。


//根据指定条件删除表记录
public int delete(String condition) {
    //执行删除记录动作,该语句返回删除记录的数目
    return mDB.delete(TABLE_NAME, condition, null);
}


方法使用:


userDBHelper.delete("_id=12");


微信图片_20220520114233.png


未创建表或者删除表后不要对表进行操作报错

       1、添加数据失败(Error)程序报错

android.database.sqlite.SQLiteException: no such table: user_info (code 1)


       2、删改查数据(AndroidRuntime)程序崩溃

android.database.sqlite.SQLiteException: no such table: user_info (code 1)


各参数说明


       table:表名称


       colums:列名称数组


       selection:条件子句,相当于where


       selectionArgs:条件语句的参数数组


       groupBy:分组


       having:分组条件


       orderBy:排序类


       limit:分页查询的限制


       Cursor:返回值,相当于结果集ResultSet


使用游标


       不管你如何执行查询,都会返回一个 Cursor,这是 Android 的 SQLite 数据库游标,使用游标,你可以:  


       通过使用 getCount() 方法得到结果集中有多少记录; 


       通过 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍历所有记录;


       通过 getColumnNames() 得到字段名;


       通过 getColumnIndex() 转换成字段号;


       通过 getString(),getInt() 等方法得到给定字段当前记录的值;


       通过 requery() 方法重新执行查询得到游标;


       通过 close() 方法释放游标资源;


项目实例:SQLiteDemo.zip

相关文章
|
1月前
|
存储 监控 安全
数据库多实例的部署与配置方法
【10月更文挑战第23天】数据库多实例的部署和配置需要综合考虑多个因素,包括硬件资源、软件设置、性能优化、安全保障等。通过合理的部署和配置,可以充分发挥多实例的优势,提高数据库系统的运行效率和可靠性。在实际操作中,要不断总结经验,根据实际情况进行调整和优化,以适应不断变化的业务需求。
|
1月前
|
负载均衡 网络协议 数据库
选择适合自己的数据库多实例负载均衡技术
【10月更文挑战第23天】选择适合自己的数据库多实例负载均衡技术需要全面考虑多种因素。通过深入的分析和评估,结合自身的实际情况,能够做出明智的决策,为数据库系统的高效运行提供有力保障。
113 61
|
1月前
|
存储 负载均衡 监控
数据库多实例的深入解析
【10月更文挑战第24天】数据库多实例是一种重要的数据库架构方式,它为数据库的高效运行和灵活管理提供了多种优势。在实际应用中,需要根据具体的业务需求和技术环境,合理选择和配置多实例,以充分发挥其优势,提高数据库系统的性能和可靠性。随着技术的不断发展和进步,数据库多实例技术也将不断完善和创新,为数据库管理带来更多的可能性和便利。
106 57
|
8天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
72 15
|
1月前
|
存储 SQL 数据库
数据库知识:了解SQLite或其他移动端数据库的使用
【10月更文挑战第22天】本文介绍了SQLite在移动应用开发中的应用,包括其优势、如何在Android中集成SQLite、基本的数据库操作(增删改查)、并发访问和事务处理等。通过示例代码,帮助开发者更好地理解和使用SQLite。此外,还提到了其他移动端数据库的选择。
41 8
|
1月前
|
缓存 负载均衡 监控
数据库多实例的负载均衡技术深入
【10月更文挑战第23天】数据库多实例负载均衡技术是确保数据库系统高效运行的重要手段。通过合理选择负载均衡策略、实时监控实例状态、不断优化调整,能够实现资源的最优分配和系统性能的提升。在实际应用中,需要根据具体情况灵活运用各种负载均衡技术,并结合其他相关技术,以满足不断变化的业务需求。
|
2月前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
39 4
|
1月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】启动与关闭MySQL数据库实例
MySQL数据库安装完成后,可以通过命令脚本启动、查看状态、配置开机自启、查看自启列表及关闭数据库。本文提供了详细的操作步骤和示例代码,并附有视频讲解。
|
2月前
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
84 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
|
2月前
|
存储 关系型数据库 数据库
轻量级数据库的利器:Python 及其内置 SQLite 简介
轻量级数据库的利器:Python 及其内置 SQLite 简介
65 3