前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >[翻译]Android教程-保存数据-在SQL数据库中保存数据

[翻译]Android教程-保存数据-在SQL数据库中保存数据

作者头像
LeoXu
发布于 2018-08-15 06:41:35
发布于 2018-08-15 06:41:35
1.8K00
代码可运行
举报
文章被收录于专栏:LeoXu的博客LeoXu的博客
运行总次数:0
代码可运行

定义一个 Schema 和 Contract


SQL数据库的主要原则是模式(schema): 一种数据库被如何组织的正式声明. 模式被反映在你用来创建你的数据库的SQL语句中. 你可能会发现创建一个同伴类很有用,它被称作(contract)协议类, 它用一种系统和自文档化的方式明确指定了你的模式的布局.

协议类是定义的URI、表格和列名称常量的容器. 协议类让你可以在同一个包的所有其它类那里使用相同的常量. 这让你可以在一个地方对列名称的改变传播到你所有的代码.

组织一个协议类最好的方式是将对你的整个数据库全局可用的定义放置到类的根一级别 . 然后为每一个表创建一个内部类,并枚举出它们的列.

注意: 通过实现 BaseColumns 接口, 你的内部类可以继承到一个称作 _ID 的主键域,一些诸如游标适配器的Android类将希望有这个东西 . 它也不是一定要有的,但它有助于你的数据库同Android框架更加的协调 .

例如,这个小代码块为一个表定义了表名和列名 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public final class FeedReaderContract { 
    // To prevent someone from accidentally instantiating the contract class,     
    // give it an empty constructor. 
    public FeedReaderContract() {} 
    /* Inner class that defines the table contents */ 
    public static abstract class FeedEntry implements BaseColumns { 
        public static final String TABLE_NAME = "entry";     
        public static final String COLUMN_NAME_ENTRY_ID = "entryid";
        public static final String COLUMN_NAME_TITLE = "title";   
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
        ... 
    }
}

使用 SQL Helper 创建一个数据库


一旦你定义好了数据库是什么样子,你就会要实现创建和维护数据库及其数据表的方法 . 下面是一些创建和删除一个表格的典型语句 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static final String TEXT_TYPE = " TEXT"; 
private static final String COMMA_SEP = ","; 
private static final String SQL_CREATE_ENTRIES =     "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +     FeedEntry._ID + " INTEGER PRIMARY KEY," + 
    FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +     FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + 
    ... // Any other options for the CREATE command 
    " )"; 
private static final String SQL_DELETE_ENTRIES = 
    "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;

就像是你保存在设备的 内部存储 中的文件, Android 将你的数据库保存在同应用程序相关联的私有磁盘空间上. 你的数据时受到保护的,因为这一区域默认不能被其它应用程序所访问 .

SQLiteOpenHelper 类中有一堆实用的API . 当你想要使用这个类来获取你的数据库的引用时,系统只会在需要时并且不会是应用启动时,执行创建和更新数据库的可耗时较长的操作. 你总共需要做的就是调用 getWritableDatabase() 和 getReadableDatabase().

注意: 以为它们可以是耗时较长的,请确保你是在一个后台线程中调用的 getWritableDatabase() 和 getReadableDatabase(), 使用诸如 AsyncTask 或者 IntentService.

为了使用 SQLiteOpenHelper, 创建一个重载了 onCreate()onUpgrade() 和 onOpen() 回调函数的子类. 你可能还想到要实现 onDowngrade(), 但它不是必须的.

例如,这里是一个使用如下所示的一些命令的 SQLiteOpenHelper 实现 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class FeedReaderDbHelper extends SQLiteOpenHelper {
    // If you change the database schema, you must increment the database version.
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "FeedReader.db";

    public FeedReaderDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}

为了访问你的数据库, 将你的 SQLiteOpenHelper 的子类实例化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

将信息放入一个数据库


通过将一个 ContentValues 对象传入 insert() 方法,来将数据插入一个数据库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);

// Insert the new row, returning the primary key value of the new row
long newRowId;
newRowId = db.insert(
         FeedEntry.TABLE_NAME,
         FeedEntry.COLUMN_NAME_NULLABLE,
         values);

insert() 的第一个参数就是数据表的名称. 第二个参数提供在 ContentValues 为空的事件中,框架可以向其中插入NULL的一列的名称 (如果你将此设置为 "null", 那么在没有值的时候框架将不会插入一行 ).

从一个数据库中读取数据


要从数据库读取数据,使用 query() 方法, 向其传入你所选择的过滤条件和想要获取的列. 该方法结合了 insert() 和 update() 的要素, 除了定义了你想要获取的数据的列清单,而不是要插入的数据 . 向你返回的查询结果在一个 Cursor 对象中.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQLiteDatabase db = mDbHelper.getReadableDatabase();

// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
    FeedEntry._ID,
    FeedEntry.COLUMN_NAME_TITLE,
    FeedEntry.COLUMN_NAME_UPDATED,
    ...
    };

// How you want the results sorted in the resulting Cursor
String sortOrder =
    FeedEntry.COLUMN_NAME_UPDATED + " DESC";

Cursor c = db.query(
    FeedEntry.TABLE_NAME,  // The table to query
    projection,                               // The columns to return
    selection,                                // The columns for the WHERE clause
    selectionArgs,                            // The values for the WHERE clause
    null,                                     // don't group the rows
    null,                                     // don't filter by row groups
    sortOrder                                 // The sort order
    );

要在游标对象中浏览一行数据,就使用 Cursor 中的某一个移动方法 , 它们总是必须在你开始读取值时被调用. 一般而言,一开始你应该调用 moveToFirst(), 它会将“读取位置”放在结果的第一条的位置 . 对于每一行,你可以通过调用 Cursor 中的摸一个获取方法来读取一列的值 , 比如 getString() 或者 getLong(). 对于每一个获取方法,你必须传入你想要获取的列的索引位置 , 它可以通过调用 getColumnIndex() 或者 getColumnIndexOrThrow() 获取到. 例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor.getColumnIndexOrThrow(FeedEntry._ID)
);

从数据库中删除信息


要从数据库中删除行,你需要提供识别这些行的选择条件. 数据库API提供了创建能够防止数据库注入的选择条件的机制. 该机制将选择指标分成选择语句和选择参数 . 语句部分定义了要查找的列,同时也允许你结合列测试 . 参数部分是绑定到语句中的测试用的值 . 因为结果不是处理同一个常规的SQL语句,它也就不会受到SQL注入的侵害.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { String.valueOf(rowId) };
// Issue SQL statement.
db.delete(table_name, selection, selectionArgs);

更新数据库


当你想要修改你的数据库值的子集,就是用 update() 方法.

更新数据表将 insert() 内含的values语法内容同delete()的where语法结合了起来.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQLiteDatabase db = mDbHelper.getReadableDatabase();

// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);

// Which row to update, based on the ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };

int count = db.update(
    FeedReaderDbHelper.FeedEntry.TABLE_NAME,
    values,
    selection,
    selectionArgs);

来源:

http://developer.android.com/training/basics/data-storage/databases.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014/05/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Android从零单排系列四十一】《Android数据存储方式-ContentProvider》
小伙伴们,在上文中我们介绍了Android数据存储中的SharedPreference,本文我们继续盘点介绍Android开发中的另一个数据存储方式ContentProvider。
再见孙悟空_
2023/07/17
2940
Android基础总结(5)——数据存储,持久化技术
瞬时数据:指那些存储在内存当中,有可能会因为程序广播或其他原因导致内存被回收而丢失的数据。 数据持久化:指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不丢失。   保存在内存中的数据是瞬时数据,保存在手机设备中的数据是处于持久状态的,持久化技术则是提供了一种机制可以让数据在瞬时状态和持久状态之间进行切换。 1、持久化技术有哪些   Android系统中主要提供了三种方式用于简单地实现数据持久化功能: 文件存储:是Android中最基本的一种数据存储方式。不对存储内
mukekeheart
2018/02/27
1.3K0
Android中的跨进程通信方法实例及特点分析(二):ContentProvider
在Android中有些数据(如通讯录、音频、视频文件等)是要供非常多应用程序使用的。为了更好地对外提供数据,Android系统给我们提供了Content Provider使用,通过它能够訪问上面所说的数据。比如非常多音乐播放器中的扫描功能事实上就用到了Content Provider功能(当然,也有的播放器是自己去实现更底层的功能)。
全栈程序员站长
2022/07/07
7410
Android中的跨进程通信方法实例及特点分析(二):ContentProvider
Android:SQLiteOpenHelper类(SQLlite数据库操作)详细解析
当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据库连接,否则容易出现SQLiteException。
Carson.Ho
2019/02/22
30.8K3
android学习笔记----SQLite数据库
目录一二的增删改查源码地址:https://github.com/liuchenyang0515/CreateDB3
砖业洋__
2023/05/06
1K0
android学习笔记----SQLite数据库
Carson带你学Android:SQLlite数据库操作全解析(SQLiteOpenHelper类)
###4.1 具体代码如下: 建议先下载Demo再进行阅读:Carson的Github:DataBase_Demo
Carson.Ho
2022/03/24
9870
Carson带你学Android:SQLlite数据库操作全解析(SQLiteOpenHelper类)
2014-10-27Android学习------SQLite数据库操作(三)-----数据库模块
以后需要数据库的时候把这两个类放到一个com.xx.xx.db包下,更改里面的数据库名称等,有效的管理自己的代码
wust小吴
2022/03/07
2430
【Android开发基础系列】Sqlite基础专题
       在Android开发中SQLite起着很重要的作用,网上SQLite的教程有很多很多,不过那些教程大多数都讲得不是很全面。本人总结了一些SQLite的常用的方法,借着论坛的大赛,跟大家分享分享的。
江中散人_Jun
2023/10/16
2480
【Android开发基础系列】Sqlite基础专题
Android四大组件之ContentProvider
Android四大组件之ContentProvider ContentProvider 安卓应用程序默认是无法获取到其他程序的数据,这是安卓安全学的基石(沙盒原理)。但是经常我们需要给其他应用
xiangzhihong
2018/01/26
1K0
2014-10-27Android学习------SQLite数据库操作(二)-----数据库的创建--SQLiteHelper extends SQLiteOpenHelper
上篇有篇文章讲了数据库的操作 条件是:数据库已经建好的了,我们只需要从里面获取数据(查询)就可以了,
wust小吴
2022/03/07
7450
2014-10-27Android学习------SQLite数据库操作(二)-----数据库的创建--SQLiteHelper extends SQLiteOpenHelper
【Android从零单排系列四十二】《Android数据存储方式-SQLite数据库》
小伙伴们,在上文中我们介绍了Android数据存储中的ContentProvider,本文我们继续盘点介绍Android开发中的另一个数据存储方式SQLite数据库。
再见孙悟空_
2023/07/17
2610
5.数据库
5.数据库 数据库的操作 创建数据库create database mydb ; 查看创建数据库的语句show create database mydb ; 改变当前的数据库use mydb ; 删除数据库drop database mydb ; 查看所有的数据库show databases ; 修改数据库mydb1的字符集为utf8 alter database mydb1 character set utf8 ; 针对表的操作 创建表t create table t( id int , name va
六月的雨
2018/05/14
7690
Android中ContentProvider简介
翻看Android源码可以发现,Android一般的代码架构如下:activity,service,receiver----contentProvider------db(file) 也就是说创建数据库保存数据,借助contentprovider对数据进行增删该查,上层利用Android组件进行交互。于是想着给自己新写的项目也添加个contentProvider来学习Android谷歌工程师的高大上,但从未用过contentprovider,这是第一次用,用完之后就发现一个问题 第一,contentprov
fanfan
2018/01/24
7200
【Android开发基础系列】数据持久化专题
http://blog.csdn.net/wulianghuan/article/details/8501063
江中散人_Jun
2023/10/16
4790
【Android开发基础系列】数据持久化专题
【鼠】安卓学习杂记(十三)——Android数据存储之SQLite数据库存储
轻量级嵌入式数据库引擎,它支持SQL 语言,并且只利用很少的内存就有很好的性能。可存储大量的数据。
訾博ZiBo
2025/01/06
450
【鼠】安卓学习杂记(十三)——Android数据存储之SQLite数据库存储
[android] 手机卫士黑名单功能(列表展示)
先把要拦截的电话号码保存到数据库中,拦截模式用个字段区分,1 电话拦截,2 短信拦截,3全部拦截
唯一Chat
2019/09/10
6550
[android] 手机卫士黑名单功能(列表展示)
Android数据库加密
SQLite是一个轻量的、跨平台的、开源的数据库引擎,它的读写效率、资源消耗总量、延迟时间和整体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方案(如Android、iOS)。Android系统内置了SQLite数据库,并且提供了一整套的API用于对数据库进行增删改查操作,具体就不详细说明了。
全栈程序员站长
2022/08/27
2.3K0
Android数据库加密
安卓第七夜 雅典学院
我之前只使用了一种持续保存数据的方法,即SharedPreferences。然而,SharedPreferences只能存储少量松散的数据,并不适合大量数据的存储。安卓带有SQLite数据库,它是一个简单版本的关系型数据库,可以应对更复杂的数据存取需求。我将在这里说明安卓中该数据库的使用方法。这里只专注于安卓中SQLite数据库的接口使用,并没有深入关系型数据库和SQL语言的背景知识。 《雅典学院》是拉斐尔的画。他在这幅壁画中描绘了许多古典时代的哲学家,如苏格拉底、柏拉图、亚里士多德等。画中的哲学家生活在不
Vamei
2018/01/18
1.3K0
安卓第七夜 雅典学院
Android | SQLite的使用
构建SQLiteOpenHelper实例后, 再调用他的getReadableDatabase()/getWritableDatabase()方法就能创建数据库了 (数据库文件会存放在/data/data/<package name>/databases/目录下)。 此时重写的onCreate()方法被执行(通常处理创建表的逻辑)。!!!!!!
凌川江雪
2019/06/11
1.6K0
Android使用内容提供者实现增删改查操作
这里需要建立两个项目:SiYouShuJuKu(使用内容提供者暴露相关的操作),DQDYGApplication(使用内容解析者对第一个应用进行相关的解析)
Dream城堡
2019/02/27
9370
推荐阅读
相关推荐
【Android从零单排系列四十一】《Android数据存储方式-ContentProvider》
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文