最近在学习android中SQLite有关的知识,对其有了一部分了解,为了演示SQLite的知识,来建立一个工程来实现数据的存储然后显示出来。
1. 建立一个工程,名字为Events
2. 由于需要使用到一些常量,建立一个Constants接口,继承于BasesColumns,代码如下:
package com.zy.events;
import android.provider.BaseColumns;
public interface Constants extends BaseColumns {
public static final String TABLE_NAME="events";
public static final String TIME="time";
public static final String TITLE="title";
}
每个数据都是存储在SQLite中一行中的,每一行中都有一个_id (primary key ), time, title。
3. 创建一个帮助类命名为EventsData代表数据库的本身,这个类是继承Android中SQLiteOpenHelper类的,SQLiteOpenHelper是用来控制数据的创建和版本号的,我们所要提供的就是构造函数和两个方法。代码如下:
package com.zy.events;
import static com.zy.events.Constants.TABLE_NAME;
import static com.zy.events.Constants.TIME;
import static com.zy.events.Constants.TITLE;
import static android.provider.BaseColumns._ID;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class EventsData extends SQLiteOpenHelper {
private static final String DATBASE_NAME ="events.db";
private static final int DATABASE_VERSION = 1;
public EventsData(Context ctx) {
super(ctx, DATBASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+TABLE_NAME+"("+
_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"+
TIME+" INTEGER,"+
TITLE+" TEXT NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS"+TABLE_NAME);
onCreate(db);
}
}
构造函数中的DATABASE_NAME是数据库文件名,而DATABASE_VERSION仅仅是一个数字,如果是一个真正的项目,version的值是会增加的当你改变了数据库的结构,比如增加了一列。
当你第一次进入到数据库中的时候,SQLiteOpenHelper将会发现它根本不存在,它将会执行onCreate()方法来创造它,在程序中我们执行SQL语句来创造。
当程序发现你是引用一个老的数据库(以version的值为依据),它将会执行onUpgrade()方法,在这里我们删除旧的table,不过在写程序时你可以做任何你想做的。
4. 我们的目的是用一个本地的SQLite数据库来存储和用TextView来展示这些数据,所以布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/text"/>
</ScrollView>
5. 主程序是Events.java,代码如下:
package com.zy.events;
import static com.zy.events.Constants.TABLE_NAME;
import static com.zy.events.Constants.TIME;
import static com.zy.events.Constants.TITLE;
import static android.provider.BaseColumns._ID;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.TextView;
public class Events extends Activity {
private EventsData events;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
events = new EventsData(this);
try {
addEvent("Hell,Android!");
Cursor cursor = getEvents();
showEvents(cursor);
} catch (Exception e) {
// TODO: handle exception
}
}
private void addEvent(String string){
//Insert a new record into the Events data source.
//You would do something similar for delete and update.
SQLiteDatabase db = events.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(TIME, System.currentTimeMillis());
values.put(TITLE, string);
db.insertOrThrow(TABLE_NAME, null,values);
}
private static String[] FROM ={_ID,TIME,TITLE};
private static String ORDER_BY = TIME + " DESC";
private Cursor getEvents(){
//Perform a managed query. The Activity will handle cloding
//and re-querying the cursor when needed.
SQLiteDatabase db = events.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null, null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
private void showEvents(Cursor cursor){
//Stuff them all into a big string
StringBuilder builder = new StringBuilder("Saved events:\n");
while(cursor.moveToNext()){
//Could use getColumIndexOrThrow()to get indexes
long id = cursor.getLong(0);
long time = cursor.getLong(1);
String title = cursor.getString(2);
builder.append(id).append(":");
builder.append(time).append(":");
builder.append(title).append("\n");
}
//Display on the screen
TextView text = (TextView) findViewById(R.id.text);
text.setText(builder);
}
}
从onCreate()方法开始我们展示这个布局,然户创建EventsData类的实例开始一个try语句,在这个语句中不管程序是否出错,这个数据库都会关闭。
如果数据库中没有任何事件将没有任何意义了,所以我们增加了addEvent()方法用来增加事件,任何时候你运行程序,一会得到一个新的事件,在这里你可以增加你喜欢的程序来实现不同的效果。增加完事件后,我们调用showEvent()方法来显示这些事件。下面分别介绍这些相关的类。
在addEvent()类中我们要修改数据,我们运用getWritableDatabase()来获得对数据库中数据的读写权利,然后用现在的时间和内容来填写ContentValues实体,再用insertOrThrow()方法来进行insert数据,我们不用来声明ID因为SQLite自动生成的。
在getEvents()类中,由于我们不需要对其内容进行修改,所以我们调用getReadableDatabase()来获取只读的权利,然后我们用query()来执行Select SQL,其中FROM是我们想要内容的容器,而ORDER_BY是使展现的语句按从新到老的顺序来排列。
虽然在本程序中我们没有用到一些query中的参数,但是还是要说明一下,其中包含where参数,GROUP BY参数和HAVING参数。其实query方法只是用来方便我们,如果可以你可以自己建立select语句来进行数据的输出,最后返回的值是Cursor容器来展现结果的。
Cursor与Java iterator和JDBC ResultSet比较相似的,这个方法你可以得到当前row的信息,然后移动到下一行来进行读取,我们可以看尽应用它一瞬间来显示数据。
这最后的步骤就是调用startManagingCursor(),这个方法告诉activity来注意控制cursor的生命周期依据activity的生命周期,比如:当activity是暂停的,cursor就会暂停,恢复后cursor也会随着恢复,当activity终止了,所有的cursor都会关闭。
showEvents()方法用来显示数据的,在这里我们只是创建了一个大的string来包含所有的事件,这个方法是不被推荐的,但是我们现在用它来实现,以后会改进。Cursor.moveToNext()方法来进行到下一行在数据库中,当你第一次得到Cursor,它是被定义在first record之前的,随着调用moveToNext()方法来得到第一行数据,我们继续执行直到返回的结果为false,则会跳出while。然后我们用getLong()和getString()来获得得到的内容,当所有的行被执行完成,我们调用TextView把big string 放入到其中。
虽然结果与我们预料的一样,但是如果有成百上千的事件,这样 的程序会运行的很慢,而且我们怎么实现用户选择事件功能和做一些自己想做的事情?Android提供了一个更好的方法,一下节我们会对这次的程序进行优化。