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

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;

	@Override
	protected 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() {
			@Override
			public 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);
		//填充SimpleCursorAdapter
		SimpleCursorAdapter 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);
	}
	
	@Override
	protected 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值