欢迎学习Android SQLite示例教程。Android SQLite是Android应用程序最受欢迎的数据存储方式。对于许多应用程序来说,无论是直接使用还是通过某个第三方包装使用,SQLite都是应用程序的主干。下面是我们今天将使用Android SQLite数据库创建的最后一个应用程序。
Android SQLite
Android SQLite是Android操作系统附带的一个非常轻量级的数据库。Android SQLite结合了一个干净的SQL界面、非常小的内存占用和不错的速度。对于Android,SQLite被)、索引等。我们可以创建自己的表来存放相应的数据。这种结构称为模式 。
Android SQLite SQLiteOpenHelper
Android提供了处理数据库模式变化的功能,这些功能主要依赖于使用SQLiteOpenHelper
类。SQLiteOpenHelper 旨在解决两个非常常见的问题。
1.当应用程序第一次运行时--此时,我们还没有数据库。因此,我们将不得不创建表、索引、起始数据等。 2.当应用程序升级到较新的架构时-我们的数据库仍将使用旧版本应用程序的旧架构。我们将选择更改数据库模式以匹配应用程序其余部分的需求。
SQLiteOpenHelper
封装了这些逻辑,以按照我们的规范创建和升级数据库。为此,我们需要创建SQLiteOpenHelper
的定制子类,至少实现以下三个方法。
1.构造函数 :它接受上下文(例如,一个活动)、数据库的名称、一个可选的游标工厂(我们将在后面讨论这一点),以及一个表示您正在使用的数据库模式版本的整数(通常从1开始,稍后递增)。
1公共数据库帮助程序(上下文上下文){
2SUPER(CONTEXT,DB_NAME,NULL,DB_VERSION);
3}
2.onCreate(SQLiteDatabase Db) :没有数据库,APP需要数据库时调用。它向我们传递一个指向新创建的数据库的SQLiteDatabase
对象,我们可以用表和初始数据填充该对象。
3.onUpgrade(SQLiteDatabase db,int oldVersion,int new Version) :当我们需要的模式版本与数据库的模式版本不匹配时,它会调用它,它会传递一个** SQLiteDatabase** 对象以及旧版本号和新版本号。因此,我们可以找出将数据库从旧模式转换为新模式的最佳方法。
我们定义了一个DBManager
类来执行所有数据库CRUD(创建、读取、更新和删除)操作。
打开和关闭Android SQLite数据库连接
在表中执行插入、更新、删除记录等数据库操作之前,请先调用getWritableDatabase() 方法打开数据库连接,如下图所示:
1public DBManager open() throws SQLException {
2 dbHelper = new DatabaseHelper(context);
3 database = dbHelper.getWritableDatabase();
4 return this;
5 }
DBHelper 是SQLiteOpenHelper
的子类的实例。要关闭数据库连接,需要调用以下方法。
1public void close() {
2 dbHelper.close();
3 }
在Android SQLite数据库表中插入新记录
下面的代码片段展示了如何在Android SQLite数据库中插入新记录。
1public void insert(String name, String desc) {
2 ContentValues contentValue = new ContentValues();
3 contentValue.put(DatabaseHelper.SUBJECT, name);
4 contentValue.put(DatabaseHelper.DESC, desc);
5 database.insert(DatabaseHelper.TABLE_NAME, null, contentValue);
6 }
内容值 使用给定的初始大小创建一组空值。我们将在进入编码部分时讨论其他实例值。
更新Android SQLite数据库表记录
以下代码片段显示了如何更新单个记录。
1public int update(long _id, String name, String desc) {
2 ContentValues contentValues = new ContentValues();
3 contentValues.put(DatabaseHelper.SUBJECT, name);
4 contentValues.put(DatabaseHelper.DESC, desc);
5 int i = database.update(DatabaseHelper.TABLE_NAME, contentValues, DatabaseHelper._ID + " = " + _id, null);
6 return i;
7 }
Android SQLite-删除记录
我们只需要传递要删除的记录的id,如下所示。
1public void delete(long _id) {
2 database.delete(DatabaseHelper.TABLE_NAME, DatabaseHelper._ID + "=" + _id, null);
3 }
Android SQLite游标
游标表示查询的整个结果集。获取查询后,调用cursor.moveToFirst() 。调用moveToFirst()会做两件事:
- 它允许我们测试查询是否返回空集(通过测试返回值)
- 它将光标移动到第一个结果(当集合不为空时)
以下代码用于获取所有记录:
1public Cursor fetch() {
2 String[] columns = new String[] { DatabaseHelper._ID, DatabaseHelper.SUBJECT, DatabaseHelper.DESC };
3 Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, null, null, null, null, null);
4 if (cursor != null) {
5 cursor.moveToFirst();
6 }
7 return cursor;
8 }
另一种使用游标的方法是将其包装在一个CursorAdapter
中。就像ArrayAdapter
适配数组一样,CursorAdapter
适配游标对象,使其数据可供AdapterView
如ListView
使用。让我们跳到使用SQLite存储一些有意义的数据的项目。
Android SQLite示例项目结构
在此应用程序中,我们希望以ListView 的形式创建存储国家名称及其各自货币的记录。我们涵盖了上面讨论的所有功能。
Android SQLite项目代码
该应用程序由5个类组成。我们首先定义DatabaseHelper ,它是SQLiteOpenHelper的子类,如下所示:DatabaseHelper.java
1package com.journaldev.sqlite;
2
3import android.content.Context;
4import android.database.sqlite.SQLiteDatabase;
5import android.database.sqlite.SQLiteOpenHelper;
6
7public class DatabaseHelper extends SQLiteOpenHelper {
8
9 // Table Name
10 public static final String TABLE_NAME = "COUNTRIES";
11
12 // Table columns
13 public static final String _ID = "_id";
14 public static final String SUBJECT = "subject";
15 public static final String DESC = "description";
16
17 // Database Information
18 static final String DB_NAME = "JOURNALDEV_COUNTRIES.DB";
19
20 // database version
21 static final int DB_VERSION = 1;
22
23 // Creating table query
24 private static final String CREATE_TABLE = "create table " + TABLE_NAME + "(" + _ID
25 + " INTEGER PRIMARY KEY AUTOINCREMENT, " + SUBJECT + " TEXT NOT NULL, " + DESC + " TEXT);";
26
27 public DatabaseHelper(Context context) {
28 super(context, DB_NAME, null, DB_VERSION);
29 }
30
31 @Override
32 public void onCreate(SQLiteDatabase db) {
33 db.execSQL(CREATE_TABLE);
34 }
35
36 @Override
37 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
38 db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
39 onCreate(db);
40 }
41}
如上所述,除了构造函数之外,我们还覆盖了onCreate()
和onUpgrade()
方法。我们将数据库和表的名称分别指定为JOURNALDEV_COUNTRIES. DB和COUNTRIES。每当插入新行时,索引列自动递增。国家和货币的列名是subject
和description
。DBManager类是初始化DatabaseHelper和定义CRUD操作的地方。下面是这个类的代码:DBManager.java
1package com.journaldev.sqlite;
2
3import android.content.ContentValues;
4import android.content.Context;
5import android.database.Cursor;
6import android.database.SQLException;
7import android.database.sqlite.SQLiteDatabase;
8
9public class DBManager {
10
11 private DatabaseHelper dbHelper;
12
13 private Context context;
14
15 private SQLiteDatabase database;
16
17 public DBManager(Context c) {
18 context = c;
19 }
20
21 public DBManager open() throws SQLException {
22 dbHelper = new DatabaseHelper(context);
23 database = dbHelper.getWritableDatabase();
24 return this;
25 }
26
27 public void close() {
28 dbHelper.close();
29 }
30
31 public void insert(String name, String desc) {
32 ContentValues contentValue = new ContentValues();
33 contentValue.put(DatabaseHelper.SUBJECT, name);
34 contentValue.put(DatabaseHelper.DESC, desc);
35 database.insert(DatabaseHelper.TABLE_NAME, null, contentValue);
36 }
37
38 public Cursor fetch() {
39 String[] columns = new String[] { DatabaseHelper._ID, DatabaseHelper.SUBJECT, DatabaseHelper.DESC };
40 Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, null, null, null, null, null);
41 if (cursor != null) {
42 cursor.moveToFirst();
43 }
44 return cursor;
45 }
46
47 public int update(long _id, String name, String desc) {
48 ContentValues contentValues = new ContentValues();
49 contentValues.put(DatabaseHelper.SUBJECT, name);
50 contentValues.put(DatabaseHelper.DESC, desc);
51 int i = database.update(DatabaseHelper.TABLE_NAME, contentValues, DatabaseHelper._ID + " = " + _id, null);
52 return i;
53 }
54
55 public void delete(long _id) {
56 database.delete(DatabaseHelper.TABLE_NAME, DatabaseHelper._ID + "=" + _id, null);
57 }
58
59}
CountryListActivity.java
类是在应用程序启动时启动的活动。下面是为其定义的布局:Fragment_emp_list.xml
1<?xml version="1.0" encoding="utf-8"?>
2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent" >
5
6 <ListView
7 android:id="@+id/list_view"
8 android:layout_width="match_parent"
9 android:layout_height="wrap_content"
10 android:dividerHeight="1dp"
11 android:padding="10dp" >
12 </ListView>
13
14 <TextView
15 android:id="@+id/empty"
16 android:layout_width="wrap_content"
17 android:layout_height="wrap_content"
18 android:layout_centerInParent="true"
19 android:text="@string/empty_list_text" />
20
21</RelativeLayout>
这里定义了一个ListView组件来包含存储在数据库中的记录。最初,ListView将是空的,因此使用TextView来显示它。CountryListActivity.java
1package com.journaldev.sqlite;
2
3import android.content.Intent;
4import android.database.Cursor;
5import android.os.Bundle;
6import android.support.v4.widget.SimpleCursorAdapter;
7import android.support.v7.app.ActionBarActivity;
8import android.view.Menu;
9import android.view.MenuItem;
10import android.view.View;
11import android.widget.AdapterView;
12import android.widget.ListView;
13import android.widget.TextView;
14
15public class CountryListActivity extends ActionBarActivity {
16
17 private DBManager dbManager;
18
19 private ListView listView;
20
21 private SimpleCursorAdapter adapter;
22
23 final String[] from = new String[] { DatabaseHelper._ID,
24 DatabaseHelper.SUBJECT, DatabaseHelper.DESC };
25
26 final int[] to = new int[] { R.id.id, R.id.title, R.id.desc };
27
28 @Override
29 protected void onCreate(Bundle savedInstanceState) {
30 super.onCreate(savedInstanceState);
31
32 setContentView(R.layout.fragment_emp_list);
33
34 dbManager = new DBManager(this);
35 dbManager.open();
36 Cursor cursor = dbManager.fetch();
37
38 listView = (ListView) findViewById(R.id.list_view);
39 listView.setEmptyView(findViewById(R.id.empty));
40
41 adapter = new SimpleCursorAdapter(this, R.layout.activity_view_record, cursor, from, to, 0);
42 adapter.notifyDataSetChanged();
43
44 listView.setAdapter(adapter);
45
46 // OnCLickListiner For List Items
47 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
48 @Override
49 public void onItemClick(AdapterView<?> parent, View view, int position, long viewId) {
50 TextView idTextView = (TextView) view.findViewById(R.id.id);
51 TextView titleTextView = (TextView) view.findViewById(R.id.title);
52 TextView descTextView = (TextView) view.findViewById(R.id.desc);
53
54 String id = idTextView.getText().toString();
55 String title = titleTextView.getText().toString();
56 String desc = descTextView.getText().toString();
57
58 Intent modify_intent = new Intent(getApplicationContext(), ModifyCountryActivity.class);
59 modify_intent.putExtra("title", title);
60 modify_intent.putExtra("desc", desc);
61 modify_intent.putExtra("id", id);
62
63 startActivity(modify_intent);
64 }
65 });
66 }
67
68 @Override
69 public boolean onCreateOptionsMenu(Menu menu) {
70 getMenuInflater().inflate(R.menu.main, menu);
71 return true;
72 }
73
74 @Override
75 public boolean onOptionsItemSelected(MenuItem item) {
76
77 int id = item.getItemId();
78 if (id == R.id.add_record) {
79
80 Intent add_mem = new Intent(this, AddCountryActivity.class);
81 startActivity(add_mem);
82
83 }
84 return super.onOptionsItemSelected(item);
85 }
86
87}
在本活动中,将调用DBManager对象来执行CRUD操作。定义SimpleCursorAdapter以将游标对象中返回的查询结果中的元素添加到列表中。在列表项上,单击一个意图以打开ModifyCountryActivity类。该菜单包含从ActionBar添加新记录的项。这里再次执行了打开AddCountryActivity类的意图。下面是menu.xml
代码。menu.xml
1<menu xmlns:android="https://schemas.android.com/apk/res/android"
2 xmlns:app="https://schemas.android.com/apk/res-auto"
3 xmlns:tools="https://schemas.android.com/tools"
4 tools:context="com.example.sqlitesample.MainActivity" >
5
6 <item
7 android:id="@+id/add_record"
8 android:icon="@android:drawable/ic_menu_add"
9 android:orderInCategory="100"
10 android:title="@string/add_record"
11 app:showAsAction="always"/>
12
13</menu>
AddCountryActivity.java
文件的XML布局和代码定义如下:active_add_record.xml
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical"
6 android:padding="20dp" >
7
8 <EditText
9 android:id="@+id/subject_edittext"
10 android:layout_width="match_parent"
11 android:layout_height="wrap_content"
12 android:ems="10"
13 android:hint="@string/enter_title" >
14
15 <requestFocus />
16 </EditText>
17
18 <EditText
19 android:id="@+id/description_edittext"
20 android:layout_width="match_parent"
21 android:layout_height="wrap_content"
22 android:ems="10"
23 android:hint="@string/enter_desc"
24 android:inputType="textMultiLine"
25 android:minLines="5" >
26 </EditText>
27
28 <Button
29 android:id="@+id/add_record"
30 android:layout_width="wrap_content"
31 android:layout_height="wrap_content"
32 android:layout_gravity="center"
33 android:text="@string/add_record" />
34
35</LinearLayout>
定义了两个EditText组件,它们接受国家和货币的输入以及一个按钮,用于将值添加到数据库中并在ListView中显示。AddCountryActivity.java
1package com.journaldev.sqlite;
2
3import android.app.Activity;
4import android.content.Intent;
5import android.os.Bundle;
6import android.view.View;
7import android.view.View.OnClickListener;
8import android.widget.Button;
9import android.widget.EditText;
10
11public class AddCountryActivity extends Activity implements OnClickListener {
12
13 private Button addTodoBtn;
14 private EditText subjectEditText;
15 private EditText descEditText;
16
17 private DBManager dbManager;
18
19 @Override
20 protected void onCreate(Bundle savedInstanceState) {
21 super.onCreate(savedInstanceState);
22
23 setTitle("Add Record");
24
25 setContentView(R.layout.activity_add_record);
26
27 subjectEditText = (EditText) findViewById(R.id.subject_edittext);
28 descEditText = (EditText) findViewById(R.id.description_edittext);
29
30 addTodoBtn = (Button) findViewById(R.id.add_record);
31
32 dbManager = new DBManager(this);
33 dbManager.open();
34 addTodoBtn.setOnClickListener(this);
35 }
36
37 @Override
38 public void onClick(View v) {
39 switch (v.getId()) {
40 case R.id.add_record:
41
42 final String name = subjectEditText.getText().toString();
43 final String desc = descEditText.getText().toString();
44
45 dbManager.insert(name, desc);
46
47 Intent main = new Intent(AddCountryActivity.this, CountryListActivity.class)
48 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
49
50 startActivity(main);
51 break;
52 }
53 }
54
55}
这里执行的CRUD操作是向数据库添加新记录。ModifyCountryActivity.Java文件的XML布局和代码定义如下:Activity_Modify_record.xml
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical"
6 android:padding="10dp" >
7
8 <EditText
9 android:id="@+id/subject_edittext"
10 android:layout_width="match_parent"
11 android:layout_height="wrap_content"
12 android:layout_marginBottom="10dp"
13 android:ems="10"
14 android:hint="@string/enter_title" />
15
16 <EditText
17 android:id="@+id/description_edittext"
18 android:layout_width="match_parent"
19 android:layout_height="wrap_content"
20 android:ems="10"
21 android:hint="@string/enter_desc"
22 android:inputType="textMultiLine"
23 android:minLines="5" >
24 </EditText>
25
26 <LinearLayout
27 android:layout_width="fill_parent"
28 android:layout_height="wrap_content"
29 android:weightSum="2"
30 android:gravity="center_horizontal"
31 android:orientation="horizontal" >
32
33 <Button
34 android:id="@+id/btn_update"
35 android:layout_width="wrap_content"
36 android:layout_height="wrap_content"
37 android:layout_weight="1"
38 android:text="@string/btn_update" />
39
40 <Button
41 android:id="@+id/btn_delete"
42 android:layout_width="wrap_content"
43 android:layout_height="wrap_content"
44 android:layout_weight="1"
45 android:text="@string/btn_delete" />
46 </LinearLayout>
47
48</LinearLayout>
除了添加了修改和删除按钮外,它与以前的布局类似。ModifyCountryActivity.java
1package com.journaldev.sqlite;
2
3import android.app.Activity;
4import android.content.Intent;
5import android.os.Bundle;
6import android.view.View;
7import android.view.View.OnClickListener;
8import android.widget.Button;
9import android.widget.EditText;
10
11public class ModifyCountryActivity extends Activity implements OnClickListener {
12
13 private EditText titleText;
14 private Button updateBtn, deleteBtn;
15 private EditText descText;
16
17 private long _id;
18
19 private DBManager dbManager;
20
21 @Override
22 protected void onCreate(Bundle savedInstanceState) {
23 super.onCreate(savedInstanceState);
24
25 setTitle("Modify Record");
26
27 setContentView(R.layout.activity_modify_record);
28
29 dbManager = new DBManager(this);
30 dbManager.open();
31
32 titleText = (EditText) findViewById(R.id.subject_edittext);
33 descText = (EditText) findViewById(R.id.description_edittext);
34
35 updateBtn = (Button) findViewById(R.id.btn_update);
36 deleteBtn = (Button) findViewById(R.id.btn_delete);
37
38 Intent intent = getIntent();
39 String id = intent.getStringExtra("id");
40 String name = intent.getStringExtra("title");
41 String desc = intent.getStringExtra("desc");
42
43 _id = Long.parseLong(id);
44
45 titleText.setText(name);
46 descText.setText(desc);
47
48 updateBtn.setOnClickListener(this);
49 deleteBtn.setOnClickListener(this);
50 }
51
52 @Override
53 public void onClick(View v) {
54 switch (v.getId()) {
55 case R.id.btn_update:
56 String title = titleText.getText().toString();
57 String desc = descText.getText().toString();
58
59 dbManager.update(_id, title, desc);
60 this.returnHome();
61 break;
62
63 case R.id.btn_delete:
64 dbManager.delete(_id);
65 this.returnHome();
66 break;
67 }
68 }
69
70 public void returnHome() {
71 Intent home_intent = new Intent(getApplicationContext(), CountryListActivity.class)
72 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
73 startActivity(home_intent);
74 }
75}
这里执行的CRUD操作是更新和删除记录。以下图片是我们项目最终输出的屏幕截图。第一个图像是第一次启动应用程序时看到的输出。第二张图片是点击操作栏中的菜单选项添加新记录的结果,如下所示。
第三张图片显示了添加3条记录时的输出:
第四张图片显示了点击任何列表项以修改或删除记录时的输出:
最终图片是删除记录时的输出。在本例中,我们删除了第一条记录:
打开Android SQLite数据库文件
正如我们在本教程前面讨论的,数据库文件存储在内部存储中,可以从Android设备监视器访问该存储,如下图所示。要查看此数据库,我们需要将此文件从设备拉到我们的桌面。这可以通过点击右上角的菜单选项来完成,如下图所示:
拉取文件以打开该文件从This链接)下载SQLiteBrowser。下面的代码片段显示了浏览器中的架构和表。
要查看表格,请转到顶部的浏览数据选项卡。如下图所示:
这结束了Android SQLite教程。最终的Android SQLite项目 可从以下链接下载。