SQLite是非常流行的嵌入式关系型数据库,轻载,速度快,而且是开源。在Android中,runtime提供SQLite,所以我们可以使用SQLite,而且是全集的SQLite。SQLite提供SQL接口,和一般的数据库一样。
和一般的SQL数据库比较,最大的差异是数据类型,例如我们定义一个表的某个column的数据类型为INTEGET,如果在插入时这个数值采用String,在SQLite中是包会产生错误,我们可以将定义表格的数据类型作为一个提示,用于说明期待的数据类型,但是并不真实起到检测作用。如果真的需要限制,要以来程序的其他部分进行判断。
SQLite支持绝大部分SQL-92标准,不支持:FOREIGN KEY constraints, nested transactions, RIGHT OUTER JOIN, FULL OUTER JOIN, and some flavors of ALTER TABLE.而我们在手持终端上使用SQLite,一般并不涉及太复杂的数据库处理,除了上诉,其他的SQL,包括tirger、transaction等都是支持,应该说SQLite提供的功能是足够。
1、建立我们的数据库
我们需要通过继承SQLiteOpenHelper这个类来达到目的。对于抽象类SQLiteOpenHelper的继承,需要重写:1)constructor,2)onCreate()和onUpgrade()。
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "cigarette";
public static final int DATABASE_VERSION = 1;
public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS ";
public static final String DROP_TABLE = "DROP TABLE IF EXISTS ";
public static final String LABEL_TABLE_NAME = "LABELLIST";//标签表
public static final String ID = "id";
public static final String label_category ="category";
public static final String label_id ="label_id";
public static final String label_name ="name";
public static final String label_value ="value";
public DBHelper(Context context) {
/* 第一个参数 为当前环境
* 第二个参数 String name为数据库文件,如果数据存放在内存 ,则为null,
* 第三个参数 为SQLiteDatabase.CursorFactory factory,存放cursor,缺省设置为null
* 第四个参数 为int version数据库的版本,从1开始,如果版本旧,则通过onUpgrade()进行更新,如果版本新则通过onDowngrade()进行发布。例如,我要更改mytable表格,增加一列,或者修改初始化的数据,或者程序变得复杂,我需要增加一个表,这时我需要在版本的数字增加,在加载时,才会对SQLite中的数据库个更新,这点非常重要,同时参见onUpgrade()的说明 */
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
/*如果Android系统中第一次创建我们的数据库时(即后面介绍调用getWritableDatabase()或者getReadbleDatabase()时),将调用onCreate(),这这里创建数据库
*/
public void onCreate(SQLiteDatabase db) {
db.execSQL(createLabelList());// 创建标签数据库表();
}
@Override
/*重写onUpgrade(),如果版本比原来的高,将调用onUpgrade(),在这个例子中,我们删除原来的表格,根据新需求创建*/
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_TABLE + LABEL_TABLE_NAME);// 保存所有标签表信息
onCreate(db);
}
/**
* 创建标签
*/
private String createLabelList() {
//创建table:SQL的语句是“CREATE TABLE constants(_id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT, value REAL);”,
StringBuilder sb = new StringBuilder();
sb.append(CREATE_TABLE);
sb.append(LABEL_TABLE_NAME);
sb.append("(");
sb.append(ID).append(
" integer primary key autoincrement,");
sb.append(label_category).append(" varchar(32) not null,");
sb.append(label_id).append(" integer,");
sb.append(label_name).append(" varchar(32),");
sb.append(label_value).append(" varchar(32)");
sb.append(")");
return sb.toString();
}
}
2.这样数据库表就创建好了,接下来我们写一个类,实现对数据库的增删改查。
/**
* 数据库操作类 封装对SQLite数据库的各种操作
*
*
*/
public class DBAdapter {
private static DBAdapter adapterInstance;
public static final String LOG_TAG = DBAdapter.class.getSimpleName();
private Context context;
private DBHelper tvmDBHelper;
private SQLiteDatabase db;
private DBAdapter(Context ctx) {
this.context = ctx;
tvmDBHelper = new DBHelper(context);
}
/**
* return DBAdapter instance
*
* @param ctx
* @return
*/
public static synchronized DBAdapter getInstance(Context ctx) {
if (adapterInstance == null) {
adapterInstance = new DBAdapter(ctx);
adapterInstance.openWriteable();
}
return adapterInstance;
}
/**
* open the database to write
*
* @throws SQLException
*/
public void openWriteable() throws SQLException {
db = tvmDBHelper.getWritableDatabase();
}
/**
* open the database to read only
*
* @throws SQLException
*/
public void openReadable() throws SQLException {
db = tvmDBHelper.getReadableDatabase();
}
/**
* close the database
*/
public void close() {
if (tvmDBHelper != null) {
tvmDBHelper.close();
tvmDBHelper = null;
adapterInstance = null;
}
}
/**
* 将所有获取到标签信息保存到数据库中
*
* @param list
* 标签列表
* @return
*/
public long insertLables(List<Lable> list) {
int count = 0;
if (null != list && list.size() > 0) {
db.beginTransaction();
ContentValues initialValues = null;
for (Lable lable : list) {
initialValues = new ContentValues();
if (hasLabelItemMsg(lable.id)) {//判断包含该id的行是否存在,存在更新,不存在创建
updateUserInfo(lable);//更新id为该id的行
} else {
initialValues.put(DBHelper.label_category,
lable.category);
initialValues.put(DBHelper.label_id, lable.id);
initialValues.put(DBHelper.label_name, lable.name);
initialValues.put(DBHelper.label_value, lable.value);
//数据库表的增
//它接收三个参数,第一个参数是表名,我们希望向哪张表里添加数据,这里就传入该表的名字。第二个参数用于在未/指定添加数据的情况下给某些可为空的列自动赋值NULL,一般我们用不到这个功能,直接传入null即可。第三个参数是一个ContentValues对象,它提供了一系列的put()方法重载,用于向ContentValues中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。
db.insert(DBHelper.LABEL_TABLE_NAME, null, initialValues);
Log.i("tag","添加标签"+lable.category+"成功" );
}
}
db.setTransactionSuccessful();
db.endTransaction();
}
Log.i("tag","总共长度为:"+ list.size());
return count;
}
/**
* 根据id查询标签是否存在
* @return 存在返回true 不存在返回false
*/
public Boolean hasLabelItemMsg(int id) {
Boolean b = false;
Cursor cursor = null;
if (!"".equals(id)) {
// table表名 columns返回哪些列传递null返回所有列 selection一个过滤器声明哪些行返回传空返回给定表的所有行
// selectionArgs按顺序给选定的行赋值 groupBy组行 having过滤器声明哪些行组包含指针 orderBy排序
//
// query(String table, String[] columns, String selection,
// String[] selectionArgs, String groupBy, String having,
// String orderBy)
cursor = db.query(DBHelper.LABEL_TABLE_NAME, null,
DBHelper.label_id + "=?", new String[] { id+"" }, null, null,
null);
b = cursor.moveToFirst();
}
if (!cursor.isClosed()) {
cursor.close();
}
return b;
}
/**
* 更新标签信息
*/
public void updateUserInfo(Lable lable) {
ContentValues initialValues = getContentValues(lable);//获取ContentValues
//接收四个参数,第一个参数和insert()方法一样,也是表名,在这里指定去更新哪张表里的数据。第二个参数是ContentValues对象,要把更新数据在这里组装进去。第三、第四个参数用于去约束更新某一行或某几行中的数据,不指定的话默认就是更新所有行。第三个参数对应的是SQL语句的where部分,表示去更新所有name等于?的行,而?是一个占位符,可以通过第四个参数提供的一个字符串数组为第三个参数中的每个占位符指定相应的内容。
//事例代码:db.update("Book", values, "name = ?", new String[] { "The Da Vinci Code" }
int id = db.update(DBHelper.LABEL_TABLE_NAME, initialValues,
DBHelper.label_id + " =" +lable.id, null);
Log.v("tag", lable.name + "=更新标签成功。。。");
}
/*
*把lable的数据放入ContentValues中
*/
public ContentValues getContentValues(Lable lable) {
ContentValues initialValues = new ContentValues();
initialValues.put(DBHelper.label_category, lable.category);
initialValues.put(DBHelper.label_id, lable.id);
initialValues.put(DBHelper.label_name, lable.name);
initialValues.put(DBHelper.label_value, lable.value);
return initialValues;
}
/**
* 删除标签列表
*
* @return
*/
public boolean deleteLABEL_TABLE_NAME() {
//,这个方法接收三个参数,第一个参数仍然是表名,这个已经没什么好说的了,第二、第三个参数又是用于去约束删除某一行或某几行的数据,不指定的话默认就是删除所有行。
//事例代码:db.delete("Book", "pages > ?", new String[] { "500" });删除Book表中的数据,并且通过第二、第三个参数来指定仅删除那些页数超过500页的书籍
return db.delete(DBHelper.LABEL_TABLE_NAME, null, null) > 0;
}
/**
* 搜索标签
*
* @param name
* @return
*/
public List<Lable> getLabels(String category) {
Cursor cursor = null;
cursor = db.query(DBHelper.LABEL_TABLE_NAME, null,
DBHelper.label_category + " =?",
new String[] { category.trim() }, null, null, null);
return getListCLabellMsg(cursor);
}
/**
* 根据label_category查询是该需要的信息
* @return
*/
public List<Lable> getListCLabellMsg(Cursor cursor) {
List<Lable> list = null;
if (cursor != null) {
list = new ArrayList<Lable>();
while (cursor.moveToNext()) {
Lable user = new Lable();
user.category = cursor.getString(cursor
.getColumnIndex(DBHelper.label_category));
user.id = cursor.getInt(cursor
.getColumnIndex(DBHelper.label_id));
user.name = cursor.getString(cursor
.getColumnIndex(DBHelper.label_name));
user.value = cursor.getString(cursor
.getColumnIndex(DBHelper.label_value));
Log.v("tag", user.value + "-----搜索zhi");
list.add(user);
}
if (!cursor.isClosed()) {
cursor.close();
}
}
return list;
}
}
3.数据库的使用
dbAdapter = DBAdapter.getInstance(ac);
spinerlist = dbAdapter.getLabels("car_type");
4.扩展实现:多条件查询
查询中使用到按区间查询 模糊查询 ,通过拼接sql字符串实现多条件查询
/**
* 搜索条件+排序 得到所有卷烟
*
* @param IS_PROMOTE
* //0表示是促销,1表示卷烟列表
* @param priceValues
* 价格排序 :1 降序,2升序
*
* @param price
* 批发价 默认为:不限 按价格区间搜索
String price = ac.getResources().getStringArray(
R.array.search_prices_value)[index];
arrays.xml中的一个子列
<string-array name="search_prices_value">
<item>全部</item>
<item>PRICE<=150 and PRICE>=0</item>
<item>PRICE<=400 and PRICE>=151</item>
<item>PRICE<=800 and PRICE>=401</item>
<item>PRICE>=801</item>
</string-array>
* @param cigaretteFactory
* 烟厂 默认为:不限
* @param activity
* 活动:经营类型1:新品,2:紧俏,3:顺销,9:其他 默认为:不限
*/
public List<Cigarette> getCigaretteAll(String IS_PROMOTE,int priceValues, String price,
String cigaretteFactory, String activity,String isSearch,String searchText) {
StringBuffer sb = new StringBuffer();
String NOLIMIT = "全部";
// 经营类型1:,2:紧俏,3:顺销,9:其他
if(activity.equals("新品")){
activity="1";
}else if(activity.equals(NOLIMIT)){
activity=NOLIMIT;
}else if(activity.equals("紧俏")){
activity="2";
}else if(activity.equals("顺销")){
activity="3";
}else if(activity.equals("其他")){
activity="9";
}
if (!price.equals(NOLIMIT)) { //判断价格是否是全部 不是添加 是不添加
sb.append(price);
}
if (!cigaretteFactory.equals(NOLIMIT)) {//判断工厂是否是全部
if(!price.equals(NOLIMIT)){ //判断上次添加的价格是否是全部 不是全部添加一个and 是全部不添加
sb.append(" AND ");
}
sb.append(" MFR_NAME =").append("'").append(cigaretteFactory+"' ");//搜索的值是string 用单引号引起
}
if (!activity.equals(NOLIMIT)) {
if(!cigaretteFactory.equals(NOLIMIT)){
sb.append(" AND ");
}
sb.append(" BRD_TYPE=").append("'").append(activity+"'");
}
if (IS_PROMOTE.equals("0")) {//0表示是促销,1表示卷烟列表
if(sb.toString().length()>0){
sb.append(" AND ");
}
sb.append(DBHelper.IS_PROMOTE+"=").append("'").append(IS_PROMOTE+"' ");
}
Log.d("tag","搜索"+Boolean.valueOf(isSearch)+searchText);
if(isSearch.equals("true")){
if(sb.toString().length()>0){
sb.append(" AND ");
}
sb.append( "CGT_NAME LIKE ").append(" '").append("%"+searchText+"%"+"'");//模糊搜索 注意单引号
}
Cursor cursor = null;
String values = "";
if (priceValues == 1) {
values = DBHelper.PRICE + " DESC";
} else {
values = DBHelper.PRICE + " ASC";
}
Log.v("tag", "赛选条件:"+sb.toString());
if (sb.length() == 0) {
cursor = db.query(DBHelper.CIGARETTE_TABLE_NAME, null, null, null,
null, null, values);
} else {
cursor=db.rawQuery("SELECT * FROM "+DBHelper.CIGARETTE_TABLE_NAME+" WHERE "+sb
.toString().trim(), null);
}
return getListCigarette(cursor);
}
5.直接使用SQL来完成CRUD
添加数据的方法如下:
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",
new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" });
更新数据的方法如下:
db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99", "The Da Vinci Code" });
删除数据的方法如下:
db.execSQL("delete from Book where pages > ?", new String[] { "500" });
查询数据的方法如下:
db.rawQuery("select * from Book", null);