Android SQLite数据库之一,使用sql语句操作SQLite数据库

来源:互联网 发布:淘宝开店注意事项 编辑:程序博客网 时间:2024/04/30 03:03

SQLite数据库

Android系统集成了一个轻量级的数据库:Sqlite,Sqlite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机、PDA等)适量数据存取。

虽然Sqlite支持绝大部分SQL92语法,也允许开发者使用sql语句操作数据库中的数据,但sqlite并不像Oracle,mySql数据库那样需要安装,启动服务器进程,sqlite数据库只是一个文件。

从本质上看,sqlite的操作方式只是一种更为便捷的文件操作。当应用程序创建或打开一个Sqlite数据库时,其实只是打开一个文件准备读写,因此有人说Sqlite有点像Microsoft的Access(实际上Sqlite的功能要强大的多)。可能在实际项目中有大量数据需要读写,而且需要面临大量用户的并发存储怎么办?对于这种情况,本身并不应该把数据存放在手机的sqlite数据库里,毕竟手机还是手机,它的存储能力、计算能力都不足以让它充当服务器的角色。

SQLiteDatabase简介

Android提供了SQLiteBatabase代表一个数据库(底层就是一个数据库文件),一旦应用程序获得了代表指定数据库的SQLiteDatabase对象,接下来就可通过SQLiteDatabase对象来管理、操作数据库了。

SQLiteDatabase提供了如下静态方法来打开一个文件对应的数据库。

》static SQLiteDatabase openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags):打开path文件所代表的SQLite数据库。

》static SQLiteDatabase openOrCreateDatabase(File file, SQLiteDatabase.CursorFactory factory):打开或创建(如果不存在)file文件所代表的SQLite数据库。

》static SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory):打开或创建(如果不存在)path文件所代表的SQLite数据库。

在程序中获取了SQLiteDatabase对象之后,接下来就可调用SQLiteDatabase的如下方法来操作数据库了。

》execSQL(String sql, Object[] bindArgs):执行带占位符的SQL语句。

》execSQL(String sql):执行sql语句。

》insert(String table, String nullColumnHack, ContentValues values):向执行表中插入数据。

》update(String table, ContentValues values, String whereClause, String[] whereArgs):更新指定表中的特定数据。

》delete(String table, String whereClause, String[] whereArgs):删除指定表中的特定数据。

》Cursor query(String table, String[] columns, String whereClause, String[] whereArgs, String groupBy, String baving, String orderBy):对执行数据表执行查询。

》Cursor query(String table, String[] columns, String whereClause, String[] whereArgs, String groupBy, String having, String orderBy, String limit):对执行数据表执行查询。limit参数控制最多查询几条记录(用于控制分页的参数)。

》Cursor query(boolean distinct, String table, String[] columns, String whereClause, String[] whereArgs, String groupBy, String having, String orderBy, String limit):对指定表执行查询语句。其中第一个参数控制是否去除重复值。

》rawQuery(String sql, String[] selectionArgs):执行带占位符的SQL查询。

》beginTransaction():开始事物。

》endTransaction():结束事物。

从上面的方法不难看出,其实SQLiteDatabase的作用有点类似JDBC的Connection接口,但是SQLiteDatabase提供的方法更多,比如insert,update,delete,query等方法,其实这些方法完全可通过执行sql语句来完成,但Android考虑到部分开发者对sql语法不熟悉,所以提供这些方法帮助开发者以更简单的方法来操作数据表的数据。

上面的查询方法都是返回一个Cursor对象,Android中的Cursor类似于JDBC的ResuleSet,Cursor同样提供了如下方法来移动查询结果的记录指针。

》move(int offset):将记录指针向上或向下移动指定的行数。offset为正数时向下移动,为负数时就是向上移动。

》boolean moveToFirst():将记录指针移动到第一行,如果移动成功则返回true。

》boolean moveToLast():将记录指针移动到最后一行,如果移动成功则返回true。

》boolean moveToNext():将记录指针移动到下一行,如果移动成功则返回true。

》boolean moveToPosition(int position):将记录指针移动到指定行,如果移动成功则返回true。

》boolean moveToPrevious():将记录指针移动到上一行,如果移动成功则返回true。

一旦将记录指针移动到指定行之后,接下来就可以调用Cursor的getXxx()方法获取该行的指定列的数据。

其实如果具有JDBC编程的经验,完全可以把SQLiteDatabase当成JDBC中Connection和Statement的混合体,因为SQLiteDatabase即代表了与数据库的连接,也可直接用于执行sql操作;而android中Cursor则可当成ResultSet,而且Cursor提供了更多便捷的方法来操作结果集。

创建数据库和表

前面说到,使用SQLiteDatabase的静态方法即可打开或创建数据库,例如如下代码:

SQLiteDatabase.openOrCreateDatabase(this.getFilesDir().toString()+"/temp.db3", null);

上面的代码就是用于打开或者创建一个SQLite数据库,如果/mnt/db/目录下的temp.db3文件(该文件就是一个数据库)存在,那么程序就是打开该数据库;如果文件不存在,则上面的代码将会在该目录下创建temp.db3文件(即对应于数据库)。

上面的代码中没有指定SQLiteDatabase.CurosrFactory参数,该参数是一个用于返回Cursor的工厂,如果指定该参数为null,则意味着使用默认的工厂。

上面的代码即可返回一个SQLiteDatabase对象,该对象的execSQL可执行任意的SQL语句,因此程序可通过如下代码在程序中创建数据表:

// 定义建表语句
String sql = "create table
 user_info "+ "(user_id integer primary key autoincrement, user_name varchar(255), user_pass varchar(255))";
// 执行sql语句
mSqLiteDatabase.execSQL(sql);

在程序中执行上面的代码即可在数据库中创建一个数据表。

使用SQL语句操作SQLite数据库

前面说到,SQLiteDatabase的execSQL方法可执行任意SQL语句,包括带占位符的sql语句。但由于该方法没有返回值,一般用于执行DDL语句或DML语句;如果需要执行查询语句,则可调用SQLiteDatabase的rawQuery(String sql, String[] selectionArfs)方法。

例如如下代码可用于执行DML语句。

mSqLiteDatabase.execSQL("insert into " + TABLE_NEWS_INFO
+ " values(null, ?, ?)", new String[] { title, context });

下面的程序示范了如何在Android应用中操作SQLite数据库,该程序提供了两个文本框,可以输入内容,单击按钮时,会将文本框中的内容插入到数据库。

1.activity

package com.example.androidioanddatastore.splite;import android.app.Activity;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.support.v4.widget.CursorAdapter;import android.support.v4.widget.SimpleCursorAdapter;import android.text.TextUtils;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.Toast;import com.example.androidioanddatastore.R;public class SQLiteActivity extends Activity {/** 数据库名称 */public final static String SQLiteName = "/temp.db3";/** 数据表user_info */public final static String TABLE_USER_INFO = "user_info";/** 数据表news_info */public final static String TABLE_NEWS_INFO = "news_info";private SQLiteDatabase mSqLiteDatabase;/** 显示数据库数据 */private ListView mListView;/** 向数据库提交数据 */private Button mSubmit;/*** Title,Context */private EditText mTitle, mContext;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sqlite);// 创建或打开数据库(此处需要使用绝对路径)mSqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(this.getFilesDir().toString()+SQLiteName, null);//initTable();initView();initEvent();}/*** * 创建数据库表 */private void initTable() {// 定义建表语句String sql = "create table "+ TABLE_USER_INFO+ "(user_id integer primary key autoincrement, user_name varchar(255), user_pass varchar(255))";// 执行sql语句mSqLiteDatabase.execSQL(sql);// 定义建表语句sql = "create table "+ TABLE_NEWS_INFO+ "(news_id integer primary key autoincrement, news_title varchar(255), news_content varchar(255))";// 执行sql语句mSqLiteDatabase.execSQL(sql);}/*** * 添加事件监听器 */private void initEvent() {mSubmit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//获取数据String title = mTitle.getText().toString();String context = mContext.getText().toString();//插入数据insertData(title, context);//查询数据queryData();}});}/*** * 查询数据库数据 */protected void queryData() {// 执行查询Cursor cursor = mSqLiteDatabase.rawQuery("select news_id AS _id, news_title, news_content from "+ TABLE_NEWS_INFO, null);//填充SimpleCursorAdapterSimpleCursorAdapter adapter = new SimpleCursorAdapter(SQLiteActivity.this, R.layout.item_line, cursor, new String[] {"news_title", "news_content" }, new int[] {R.id.text_left, R.id.text_right },CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);//显示数据mListView.setAdapter(adapter);}/*** * 向数据库插入数据 *  * @param title * @param context */protected void insertData(String title, String context) {if(TextUtils.isEmpty(title)&&TextUtils.isEmpty(context)){Toast.makeText(SQLiteActivity.this, "数据不能为空", Toast.LENGTH_SHORT).show();return;}// 执行插入语句mSqLiteDatabase.execSQL("insert into " + TABLE_NEWS_INFO+ " values(null, ?, ?)", new String[] { title, context });}/** * 初始化组件 */private void initView() {mListView = (ListView) findViewById(R.id.sqlite_listview);mSubmit = (Button) findViewById(R.id.sqlite_submit);mTitle = (EditText) findViewById(R.id.sqlite_title);mContext = (EditText) findViewById(R.id.sqlite_context);}@Overrideprotected void onDestroy() {super.onDestroy();//mSqLiteDatabase.isOpen():如果数据库是当前打开的返回true。if(mSqLiteDatabase != null && mSqLiteDatabase.isOpen()){//释放数据库对象mSqLiteDatabase.close();}}}
3.xml布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <EditText         android:id="@+id/sqlite_title"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="title"/>    <EditText         android:id="@+id/sqlite_context"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="context"/>    <Button         android:id="@+id/sqlite_submit"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="submit"/>    <ListView         android:id="@+id/sqlite_listview"        android:layout_width="match_parent"        android:layout_height="match_parent"/></LinearLayout>
3.listview的item布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <TextView         android:id="@+id/text_left"        android:layout_width="0dp"        android:layout_weight="1"        android:layout_height="wrap_content"        android:text="dddd"        />     <TextView         android:id="@+id/text_right"        android:layout_width="0dp"        android:layout_weight="1"        android:layout_height="wrap_content"        android:text="dddd"        /></LinearLayout>


需要指出的是,使用SimpleCursorAdapter封装Cursor时要求底层数据表的主键列的列明为_id,因为SimpleCursorAdapter只能识别列名为_id的主键。因此上面的程序创建数据表示制定了主键列的列明为_id,否则就会出现java.lang.IllegalArgumentException: column '_id' does not exist错误,但是我上面的sql查询语句中,已经给了解决方法。

上面的程序中重写了Activity的onDestroy()方法,当应用程序退出该Activity时将会回调该方法,程序在该方法中关闭了SQLiteDatabase,就像JDBC编程中需要关闭Statement和Connection一样,这里也需要关闭SQLiteDatabase,否则可能引发资源泄露。总结起来使用SQLiteDatabase进行数据库操作的步骤如下:

1、获取SQLiteDatabase对象,它代表了与数据库的连接。

2、调用SQLiteDatabase的方法来执行sql语句。

3、操作sql语句的执行结果,比如用SimpleCursorAdapter封装Cursor。

4、关闭SQLiteDatabase,回收资源。

0 0