Saving data to a database is ideal for repeating or structured data, such as contact information. This class assumes that you are familiar with SQL databases in general and helps you get started with SQLite databases on Android. The APIs you'll need to use a database on Android are available in the android.database.sqlite package.

Define a Schema and Contract


One of the main principles of SQL databases is the schema: a formal declaration of how the database is organized. The schema is reflected in the SQL statements that you use to create your database. You may find it helpful to create a companion class, known as a contract class, which explicitly specifies the layout of your schema in a systematic and self-documenting way.

A contract class is a container for constants that define names for URIs, tables, and columns. The contract class allows you to use the same constants across all the other classes in the same package. This lets you change a column name in one place and have it propagate throughout your code.

A good way to organize a contract class is to put definitions that are global to your whole database in the root level of the class. Then create an inner class for each table that enumerates its columns.

Note: By implementing the BaseColumns interface, your inner class can inherit a primary key field called _ID that some Android classes such as cursor adaptors will expect it to have. It's not required, but this can help your database work harmoniously with the Android framework.

For example, this snippet defines the table name and column names for a single table:

  1. public final class FeedReaderContract {
  2. // To prevent someone from accidentally instantiating the contract class,
  3. // give it an empty constructor.
  4. public FeedReaderContract() {}
  5.  
  6. /* Inner class that defines the table contents */
  7. public static abstract class FeedEntry implements BaseColumns {
  8. public static final String TABLE_NAME = "entry";
  9. public static final String COLUMN_NAME_ENTRY_ID = "entryid";
  10. public static final String COLUMN_NAME_TITLE = "title";
  11. public static final String COLUMN_NAME_SUBTITLE = "subtitle";
  12. ...
  13. }
  14. }

Create a Database Using a SQL Helper


Once you have defined how your database looks, you should implement methods that create and maintain the database and tables. Here are some typical statements that create and delete a table:

  1. private static final String TEXT_TYPE = " TEXT";
  2. private static final String COMMA_SEP = ",";
  3. private static final String SQL_CREATE_ENTRIES =
  4. "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
  5. FeedEntry._ID + " INTEGER PRIMARY KEY," +
  6. FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
  7. FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
  8. ... // Any other options for the CREATE command
  9. " )";
  10.  
  11. private static final String SQL_DELETE_ENTRIES =
  12. "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;

Just like files that you save on the device's internal storage, Android stores your database in private disk space that's associated application. Your data is secure, because by default this area is not accessible to other applications.

A useful set of APIs is available in the SQLiteOpenHelper class. When you use this class to obtain references to your database, the system performs the potentially long-running operations of creating and updating the database only when needed and not during app startup. All you need to do is call getWritableDatabase() or getReadableDatabase().

Note: Because they can be long-running, be sure that you call getWritableDatabase() or getReadableDatabase() in a background thread, such as with AsyncTask or IntentService.

To use SQLiteOpenHelper, create a subclass that overrides the onCreate(), onUpgrade() and onOpen() callback methods. You may also want to implement onDowngrade(), but it's not required.

For example, here's an implementation of SQLiteOpenHelper that uses some of the commands shown above:

  1. public class FeedReaderDbHelper extends SQLiteOpenHelper {
  2. // If you change the database schema, you must increment the database version.
  3. public static final int DATABASE_VERSION = 1;
  4. public static final String DATABASE_NAME = "FeedReader.db";
  5.  
  6. public FeedReaderDbHelper(Context context) {
  7. super(context, DATABASE_NAME, null, DATABASE_VERSION);
  8. }
  9. public void onCreate(SQLiteDatabase db) {
  10. db.execSQL(SQL_CREATE_ENTRIES);
  11. }
  12. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  13. // This database is only a cache for online data, so its upgrade policy is
  14. // to simply to discard the data and start over
  15. db.execSQL(SQL_DELETE_ENTRIES);
  16. onCreate(db);
  17. }
  18. public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  19. onUpgrade(db, oldVersion, newVersion);
  20. }
  21. }

To access your database, instantiate your subclass of SQLiteOpenHelper:

  1. FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

Put Information into a Database


Insert data into the database by passing a ContentValues object to the insert() method:

  1. // Gets the data repository in write mode
  2. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  3.  
  4. // Create a new map of values, where column names are the keys
  5. ContentValues values = new ContentValues();
  6. values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
  7. values.put(FeedEntry.COLUMN_NAME_TITLE, title);
  8. values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
  9.  
  10. // Insert the new row, returning the primary key value of the new row
  11. long newRowId;
  12. newRowId = db.insert(
  13. FeedEntry.TABLE_NAME,
  14. FeedEntry.COLUMN_NAME_NULLABLE,
  15. values);

The first argument for insert() is simply the table name. The second argument provides the name of a column in which the framework can insert NULL in the event that the ContentValues is empty (if you instead set this to "null", then the framework will not insert a row when there are no values).

Read Information from a Database


To read from a database, use the query() method, passing it your selection criteria and desired columns. The method combines elements of insert() and update(), except the column list defines the data you want to fetch, rather than the data to insert. The results of the query are returned to you in a Cursor object.

  1. SQLiteDatabase db = mDbHelper.getReadableDatabase();
  2.  
  3. // Define a projection that specifies which columns from the database
  4. // you will actually use after this query.
  5. String[] projection = {
  6. FeedEntry._ID,
  7. FeedEntry.COLUMN_NAME_TITLE,
  8. FeedEntry.COLUMN_NAME_UPDATED,
  9. ...
  10. };
  11.  
  12. // How you want the results sorted in the resulting Cursor
  13. String sortOrder =
  14. FeedEntry.COLUMN_NAME_UPDATED + " DESC";
  15.  
  16. Cursor c = db.query(
  17. FeedEntry.TABLE_NAME, // The table to query
  18. projection, // The columns to return
  19. selection, // The columns for the WHERE clause
  20. selectionArgs, // The values for the WHERE clause
  21. null, // don't group the rows
  22. null, // don't filter by row groups
  23. sortOrder // The sort order
  24. );

To look at a row in the cursor, use one of the Cursor move methods, which you must always call before you begin reading values. Generally, you should start by calling moveToFirst(), which places the "read position" on the first entry in the results. For each row, you can read a column's value by calling one of the Cursor get methods, such as getString() or getLong(). For each of the get methods, you must pass the index position of the column you desire, which you can get by calling getColumnIndex() or getColumnIndexOrThrow(). For example:

  1. cursor.moveToFirst();
  2. long itemId = cursor.getLong(
  3. cursor.getColumnIndexOrThrow(FeedEntry._ID)
  4. );

Delete Information from a Database


To delete rows from a table, you need to provide selection criteria that identify the rows. The database API provides a mechanism for creating selection criteria that protects against SQL injection. The mechanism divides the selection specification into a selection clause and selection arguments. The clause defines the columns to look at, and also allows you to combine column tests. The arguments are values to test against that are bound into the clause. Because the result isn't handled the same as a regular SQL statement, it is immune to SQL injection.

  1. // Define 'where' part of query.
  2. String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
  3. // Specify arguments in placeholder order.
  4. String[] selectionArgs = { String.valueOf(rowId) };
  5. // Issue SQL statement.
  6. db.delete(table_name, selection, selectionArgs);

Update a Database


When you need to modify a subset of your database values, use the update() method.

Updating the table combines the content values syntax of insert() with the where syntax of delete().

  1. SQLiteDatabase db = mDbHelper.getReadableDatabase();
  2.  
  3. // New value for one column
  4. ContentValues values = new ContentValues();
  5. values.put(FeedEntry.COLUMN_NAME_TITLE, title);
  6.  
  7. // Which row to update, based on the ID
  8. String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
  9. String[] selectionArgs = { String.valueOf(rowId) };
  10.  
  11. int count = db.update(
  12. FeedReaderDbHelper.FeedEntry.TABLE_NAME,
  13. values,
  14. selection,
  15. selectionArgs);

(From developer.androind.com)

[Android 开发教程(1)]-- Saving Data in SQL Databases的更多相关文章

  1. Android学习笔记——保存数据到SQL数据库中(Saving Data in SQL Databases)

    知识点: 1.使用SQL Helper创建数据库 2.数据的增删查改(PRDU:Put.Read.Delete.Update) 背景知识: 上篇文章学习了保存文件,今天学习的是保存数据到SQL数据库中 ...

  2. Android开发教程大全介绍

    Android是由谷歌在2007年推出的一个开放系统平台,主要针对移动设备市场,目前版本为Android 4.0.Android基于Linux,开发者可以使用Java或C/C++开发Android应用 ...

  3. ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView

    原文地址: ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http:/ ...

  4. ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map

    原文地址: ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NE ...

  5. ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置

    原文地址: ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.c ...

  6. ArcGIS Runtime for Android开发教程V2.0(1)基本概念

    原文地址: ArcGIS Runtime for Android开发教程V2.0(1)基本概念 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csd ...

  7. 【Android 开发教程】动态添加Fragments

    本章节翻译自<Beginning-Android-4-Application-Development>,如有翻译不当的地方,敬请指出. 原书购买地址http://www.amazon.co ...

  8. 收集整理Android开发所需的Android SDK、开发中用到的工具、Android开发教程、Android设计规范,免费的设计素材等。

    AndroidDevTools Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.An ...

  9. Android开发教程 - 使用Data Binding(一) 介绍

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

随机推荐

  1. css3的calc()

    计算大小宽度距离的一个计算函数    使用方法  再括号中进行加减乘除的运算   例如: width : calc(100% - 75px) 注意  :符号左右两边要有空格

  2. PTA——各位数之和

    PTA 7-28 求整数的位数及各位数字之和 我的程序: #include<stdio.h> #include<math.h> int main(){ ,t; scanf(&q ...

  3. 识别假tf卡工具

    h2testwhttps://www.heise.de/download/product/h2testw-50539使用HaraldBögeholz的免费测试工具H2testw,可以检查存储介质(如硬 ...

  4. python django day 4 database

    django-admin.py startproject learn_models # 新建一个项目 cd learn_models # 进入到该项目的文件夹 django-admin.py star ...

  5. 【shell编程】之基础知识-语法

    一.shell变量 1.定义变量 定义变量时,变量名不加美元符号($,PHP语言中变量需要), 如: your_name="runoob.com" 注意,变量名和等号之间不能有空格 ...

  6. day10 内容大纲

    01 去年内容回顾 01 去年内容回顾 *args **kwargs: 万能参数,动态参数 * 魔性用法: 函数的定义时,* ** 聚合. 函数的执行时,* ** 打散. 形参顺序: 位置参数,*ar ...

  7. 20165308 2017-2018-2 《Java程序设计》第2周学习总结

    20165308 2017-2018-2 <Java程序设计>第2周学习总结 教材学习内容总结 标识符与关键字 基本数据类型 输入输出数据 循环语句 break continue语句 if ...

  8. How to Export to Excel

    https://simpleisbetterthancomplex.com/tutorial/2016/07/29/how-to-export-to-excel.html Export data to ...

  9. pyspark数据准备

    鸢尾花数据集 5.1,3.5,1.4,0.2,Iris-setosa 4.9,3.0,1.4,0.2,Iris-setosa 4.7,3.2,1.3,0.2,Iris-setosa 4.6,3.1,1 ...

  10. 深入解析 ext2 文件系统 (转)

    http://blog.chinaunix.net/uid-24774106-id-3266816.html 很久以来,就想写一篇关于ext 家族文件系统的文章,源于我刚工作的时候,曾经一不小心rm ...