Android数据存储有多种方式,其中SQLite是轻量级的嵌入式的数据库,支持sql结构化查询语言,能够满足普通软件开发需要。
本例子主要实现的功能是:
1、输入单词及其释义,点击按钮将其写入数据库;
2、输入要查询的单词,点击按钮在新Activity中列表显示出来;
该项目整体实现流程:
1. 实现SQLiteOpenHelper数据库助手类
该类主要用于创建数据表,首先定义创建表sql语句:
String CREATE_TABLE = create table(id integer primary key autoincrement,word varchar(255),detail varchar(255));
然后在该类的oncreate方法中,调用SQLiteDatabase.execSQL(CREATE_TABLE)方法,执行创建表语句
2. 实现MainActivity主界面类
该类是核心,负责主要功能的实现。
2.1、首先实例化SQLiteOpenHelper类对象:
MyDataBase myDataBase = new MyDataBase(this,"mydb.db",1);
此处三个参数,第一个this为context上下文;第二个为要使用的数据库名称,若不存在则创建;第三个为版本号,用于更新数据库。
2.2、设置添加生词按钮监听器,在onclick()方法中,实现向数据库写入生词及释义的功能
此处调用insertWord()方法,传入三个参数:
1、myDataBase.getReadableDatabase()可读数据库;
2、生词;
3、释义。
在insertWord()方法中,首先定义写入单词的sql语句:
String INSERT_WORD =" insert into mytable(id,word,detail) values(null,?,?)";
调用传入参数中的可读数据库的execSQL()方法执行该sql语句:
db.execSQL(INSERT_WORD,new String[]{word,detail});
此处new String中的两个参数对应values中的两个问号。
2.3、设置查询生词按钮监听器
首先实现对数据库的查询功能,定义查询SQL语句:
String QUERY_SQL = "select * from mytable where word like ?";
定义Cursor游标指针用于对查询结果进行操作:
Cursor cursor = myDataBase.getWritableDatabase().rawQuery(QUERY_SQL,new String[]{"%"+searchWord+"%"});
此时cursor已经指向查询结果集第一行数据的前一行,接下来就是依次取出这些数据并存入ArrayList中。
2.4、利用cursor取出数据并存入ArrayList中的方法实现
public ArrayList<Map<String,String>> cursorToList(Cursor cursor){
ArrayList<Map<String,String>> list = new ArrayList<Map<String,String>>();
while(cursor.moveToNext()){
Map<String,String> map = new HashMap<String,String>();
map.put("word",cursor.getString(1));
map.put("detail",cursor.getString(2));
list.add(map);
}
return list;
}
上面的方法实现了将数据库查询结果存入list,下面代码调用之,并将cursor传入即可:
ArrayList<Map<String,String>> list = cursorToList(cursor);
2.5、将查询结果list封装到Bundle对象,通过Intent传给新打开的Activity进行显示
Bundle bundle = new Bundle(); //实例化bundle对象
bundle.putSerializable("list",list); //将列表list装入bundle,若为String等基本类型,则使用putString()等
Intent intent = new Intent(MainActivity.this,ShowActivity.class);//实例化Intent对象
intent.putExtras(bundle);//将bundle装入intent
startActivity(intent);//打开新Activity,并传入该intent
3. 结果显示页面ShowActivity.class
首先绑定视图控件listView:
ListView listView = (ListView)findViewById(R.id.listView);
接收来自MainActivity传来的Intent中的bundle数据:
Bundle bundle = getIntent().getExtras();
接收该Bundle中的ArrayList:
ArrayList<Map<String,String>> list = (ArrayList<Map<String,String>>)bundle.getSerializable("list");
设置适配器用于将数据显示在listview控件中:
SimpleAdapter adapter = new SimpleAdapter(this,list,R.layout.activity_list,new String[]{"word","detail"},new int[]{R.id.tv_word,R.id.tv_detail});
参数1:context上下文,传this一般没错
参数2:要显示在具体哪个布局资源上,即:使用什么样的列表样式,传入该布局资源的id
参数3:从list中取出哪些数据用于显示,此处取出word和detail的内容
参数4:要将取出的内容如何对应显示到资源文件中的具体控件上,此处传入两个布局文件中的textview的id
至此,实现该功能的全部主要流程已写完,该实例除了有对数据库的读写操作,还包括了Bundle数据绑定、Intent意图传递数据、Adapter适配器实现自定义列表等方面的内容,实用意义很大。
详细代码看下面:
界面布局不说了,先看数据库类 MyDataBaseActivity.java
该类主要实现了创建数据库表
package com.fukang.sqlitetest;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDataBase extends SQLiteOpenHelper {
final String CREAT_TABLE = "create table mytable(id integer primary key autoincrement,word varchar(255),detail varchar(255))";
//创建数据库表的sql语句
public MyDataBase(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREAT_TABLE);
//执行创建数据库表
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
主界面MainActivity.java源码:
package com.fukang.sqlitetest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
/**
* SQLite数据存储与读取的简单实例
* @author fukang
*/
public class MainActivity extends Activity {
//声明变量
EditText et_word, et_detail, et_search;
Button btn_add, btn_search;
MyDataBase myDataBase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//加载主页面布局资源
myDataBase = new MyDataBase(this, "mydb.db", null, 1);//实例化SQLiteOpenHelper类,数据库名称mydb.db,版本号1
initView();//初始化控件绑定
setOnclickListener();//设置按钮监听器
}
private void setOnclickListener() {
// TODO Auto-generated method stub
btn_add.setOnClickListener(new OnClickListener() { //添加生词按钮监听器
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
insertWord(myDataBase.getReadableDatabase(), et_word.getText()
//调用insertWord方法,传入下列三个参数
//由助手类得到的可读数据库,生词,生词释义
}
});
btn_search.setOnClickListener(new OnClickListener() { //查询生词按钮监听器
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String querySql = "select * from mytable where word like ?";
//设置查询sql语句
//设置查询结果集的游标指针
querySql,
new String[] { "%" + et_search.getText().toString()
//***此处尚未搞懂***//
+ "%" });
//得到数组列表list,该数组每个元素都是一个Map类对象,该Map对象的键值对类型都为String
//调用cursorToList方法,依次改变cursor,取出Map<String,String>类型数据,存入该list
Bundle bundle = new Bundle();
bundle.putSerializable("list", list);
//实例化Bundle对象,存入数组类数据时,调用putSerializable方法
Intent intent = new Intent(MainActivity.this,
ShowActivity.class);
intent.putExtras(bundle); //实例化Intent意图,存入bundle数据
startActivity(intent); //打开新的Activity
}
});
}
private void initView() {
// TODO Auto-generated method stub
et_word = (EditText) findViewById(R.id.et_word);
et_detail = (EditText) findViewById(R.id.et_detail);
et_search = (EditText) findViewById(R.id.et_search);
btn_add = (Button) findViewById(R.id.btn_add);
btn_search = (Button) findViewById(R.id.btn_search);
}
public void insertWord(SQLiteDatabase db, String word, String detail) {
final String INSERT_WORD = "insert into mytable(id,word,detail) values(null,?,?)";
//此处null表示id自动生成,?表示占位符
//第二个参数中word和detail分别替换上句中的?占位符
}
public ArrayList<Map<String, String>> cursorToList(Cursor cursor) {
//利用查询得到的cursor,依次取出数据并存入ArrayList中
ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
//当cursor移动后不为null,则执行。(cursor最初在第一个数据的前一位,因此首次执行该循环时,正好移动到第一个数据位置)
Map<String, String> map = new HashMap<String, String>();
//实例化Map类对象
//取出索引index为1的字符串作为value,word作为key存入map中
map.put("detail", cursor.getString(2));
//取出索引index为2的字符串作为value,detail作为key存入map中 (索引从0开始,0为id值)
list.add(map);//每移动一次cursor,往list中存入一个map对象
}
return list;//全部读取完成后,将该list返回。
}
}
最后是查询结果的显示页面源码ShowActivity.java
package com.fukang.sqlitetest;
import java.util.ArrayList;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class ShowActivity extends Activity {
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
Bundle bundle = getIntent().getExtras();
//实例化一个bundle,用来接收从MainActivity中传来的Intent中的bundle
@SuppressWarnings("unchecked")
ArrayList<Map<String, String>> list = (ArrayList<Map<String, String>>) bundle
.getSerializable("list");
//实例化ArrayList对象list,取出bundle中存储的list
SimpleAdapter adapter = new SimpleAdapter(this, list,
//实例化adapter适配器,绑定listView视图
R.layout.list_show, new String[] { "word", "detail" },
// 对应关系,从{"word","detail"}取出数据
new int[] { R.id.tv_word, R.id.tv_detail });
// 显示到{ R.id.tv_word, R.id.tv_detail }
listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter); // 给listview加载该适配器
}
}