Android中数据库操作的封装、扩展实现

Android中的数据库操作

       在写这篇文章时,数据库部分的封装实现主要是参照开源软件eoe客户端中数据库来设计,很感谢该开源代码,让我又学习到了很多,如果eoe的开发人员看到这篇文章也希望多多指教。

       Android中数据库大家应该都知道了,主要是采用轻量级的开源数据库Sqlite来实现,至于该数据库的一些字段介绍可以参照该篇博客 http://blog.csdn.net/nieweilin/article/details/5919013,或者直接百度搜索即可。

       接下来将介绍如何把我们的数据库查询部分的代码进行封装,可以重复使用。

      1、 首先是创建抽象类DatabaseColumn,该类是从基类BaseColumns进行派生,主要是用来表示数据库中表的抽象基类。

package com.busleep.db;

import java.util.ArrayList;
import java.util.Map;
import android.net.Uri;
import android.provider.BaseColumns;

//数据库表的抽象基类;
public abstract class DatabaseColumn implements BaseColumns {

    /**
     * The identifier to indicate a specific ContentProvider
     */
    public static final String AUTHORITY="com.busleep.provider";
    
    /**
     * The database's name
     */
    public static final String DATABASE_NAME="busleep.db";
    
    /**
     * The version of current database
     */
    public static final int DATABASE_VERSION = 1;
    
    /**
     * Classes's name extends from this class<span style="color:#FF0000;">(基类对象的扩展,下面的AlarmCloumn是实现基类的数据表,此处可以进行任意扩展,只需定义新的数据库表即可。)</span>
     */
    public static final String[] SUBCLASSES=new String[]{
        "com.busleep.db.AlarmColumn"};
    
    public String getTableCreateor(){
        return getTableCreator(getTableName(), getTableMap());
    }
    /**
     * Get sub-classes of this class.
     *
     * @return Array of sub-classes.
     */
    @SuppressWarnings("unchecked")
    public static final Class<DatabaseColumn>[] getSubClasses(){
        ArrayList<Class<DatabaseColumn>> classes=new ArrayList<Class<DatabaseColumn>>();
        Class<DatabaseColumn> subClass=null;
        for(int i=0;i<SUBCLASSES.length;i++){
            try {
                subClass=(Class<DatabaseColumn>) Class.forName(SUBCLASSES[i]);
                classes.add(subClass);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                continue;
            }
        }
        return classes.toArray(new Class[0]);
    }
    
    /**
     * Create a sentence to create a table by using a hash-map.
     * 根据hash表中的值来创建一个数据库中的表;
     * @param tableName
     *     The table's name to create.
     * @param map
     *     A map to store table columns info.
     * @return
     */
    private static final String getTableCreator(String tableName,
            Map<String, String> map){
        String[] keys=map.keySet().toArray(new String[0]);
        String value=null;
        StringBuilder creator=new StringBuilder();
        creator.append("CREATE TABLE ").append(tableName).append("( ");
        int length=keys.length;
        for(int i=0;i<length;i++){
        
            value=map.get(keys[i]);
            creator.append(keys[i]).append(" ");
            creator.append(value);
            if(i < length - 1){
                creator.append(",");
            }
        }
        creator.append(")");
        return creator.toString();
    }

    //抽象类中的三个抽象函数,子类需要实现该对象,从而可以创建子类中定义的数据库表;   
    abstract public String getTableName();
    
    abstract public Uri getTableContent();
    
    abstract protected Map<String, String> getTableMap();
}

   2、定义好了表的基类后,定义一个数据库帮助类DBHelper:

package com.busleep.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;

/**
 * 数据库帮助类;
 * @author Render;
 *
 */
public class DBHelper extends SQLiteOpenHelper{
 </span><span style="font-size:14px;">   
    //数据库名称和数据库版本号 
    private static final String DB_NAME="busleep";
    private static final int DB_VERSION=2;
    
    private SQLiteDatabase db;
    
    //数据库帮助类的单例;
    private static DBHelper mdbHelper;
    
    public static DBHelper getInstance(Context context){
        
        if(mdbHelper==null){
            mdbHelper=new DBHelper(context);
        }
        return mdbHelper;
    }
    
    private DBHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }
    
    private DBHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, factory, version);
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        this.db=db;
        operateTable(db, "");
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        
        if(newVersion==oldVersion){
            return;
        }
        operateTable(db, "DROP TABLE IF EXISTS ");
        onCreate(db);
    }
    
    public void operateTable(SQLiteDatabase db,String actionString){
        
        Class<DatabaseColumn>[] columnsClasses=DatabaseColumn.getSubClasses();
        DatabaseColumn columns=null;
        for(int i=0;i<columnsClasses.length;i++){
            try {
                columns=columnsClasses[i].newInstance();
                if("".equals(actionString)||actionString==null){
                    db.execSQL(columns.getTableCreateor());
                }else {
                    db.execSQL(actionString+columns.getTableName());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 插入数据;
     * @param Table_Name
     * @param values
     * @return
     */
    public long insert(String Table_Name,ContentValues values){
        
        if(db==null){
            db=getWritableDatabase();
        }
        return db.insert(Table_Name, null, values);
    }
    
    /**
     * 根据Id来删除数据;
     * @param Table_Name
     * @param id
     * @return
     */
    public int delete(String Table_Name,int id){
        if(db==null){
            db=getWritableDatabase();
        }
        return db.delete(Table_Name, BaseColumns._ID+"=?", 
                new String[] {String.valueOf(id)});
    }
    
    /**
     * 更新数据库中的数据;
     * @param Table_Name
     * @param values
     * @param whereClause
     * @param wherwArgs
     * @return
     */
    public int update(String Table_Name,ContentValues values,
            String whereClause,String[] whereArgs){
        if(db==null){
            db=getWritableDatabase();
        }
        return db.update(Table_Name, values, whereClause, whereArgs);
    }
    
    /**
     * 查询数据库;
     * @param Table_Name
     * @param columns
     * @param whereStr
     * @param whereArgs
     * @return
     */
    public Cursor query(String Table_Name,String[] columns,
            String whereStr,String[] whereArgs){
        if(db==null){
            db=getReadableDatabase();
        }
        return db.query(Table_Name, columns, whereStr, whereArgs,null,null,null);
    }
    
    public Cursor rawQuery(String sql,String[] args){
        if(db==null){
            db=getReadableDatabase();
        }
        return db.rawQuery(sql, args);
    }
    
    public void ExecSQL(String sql){
        if(db==null){
            db=getWritableDatabase();
        }
        db.execSQL(sql);
    }
    
    public void closeDb(){
        if(db!=null){
            db.close();
            db=null;
        }
    }   
}

3、创建好数据库帮助类和数据库表基类后,接下来创建一个具体的数据库表的实体类AlarmColumn,该实体数据表类派生于DatabaseColumn,主要实现抽象的方法,并定义好字段与创建数据时的字段因映射表即可实现该表的动态创建。

package com.busleep.db;

import java.util.HashMap;
import java.util.Map;

import android.net.Uri;

public class AlarmColumn extends DatabaseColumn{

	public static final String TABLE_NAME="alarm";
	public static final Uri    CONTENT_URI=Uri.parse("content://"+AUTHORITY+"/"+TABLE_NAME);
	
	//数据库字段常量;
	public static final String STATIONNAME="station_name";
	public static final String DISTANCE="distance";
	public static final String LONGTITUDE="longtitude";
	public static final String LATITUDE="latitude";
	public static final String ISON="ison";
	
	//定义表字段与数据库操作字段的映射表;
	private static final Map<String, String> mColumnMap=new HashMap<String,String>();
	
	static{
		mColumnMap.put(_ID, "integer primary key autoincrement");
		mColumnMap.put(STATIONNAME, "station_name");
		mColumnMap.put(DISTANCE, "distamce");
		mColumnMap.put(LONGTITUDE, "longtitude");
		mColumnMap.put(LATITUDE, "latitude");
		mColumnMap.put(ISON, "ison");
	}
	
	
	@Override
	public String getTableName() {
		// TODO Auto-generated method stub
		return TABLE_NAME;
	}

	@Override
	public Uri getTableContent() {
		// TODO Auto-generated method stub
		return CONTENT_URI;
	}

	@Override
	protected Map<String, String> getTableMap() {
		// TODO Auto-generated method stub
		return mColumnMap;
	}

}
4、利用DBHelper进行操作数据库,例如插入数据到表AlarmColumn中,如下:
   mDBHelper=DBHelper.getInstance(getActivity());
   
   //自定义的包含数据的对象;
   MrAlarm alarm=CustomApplication.getInstance().getAlarm();
		
   ContentValues cv=new ContentValues();

   cv.put(AlarmColumn.STATIONNAME, alarm.getBusStationName());
   cv.put(AlarmColumn.DISTANCE, alarm.getDistanceThreshold());
   cv.put(AlarmColumn.LONGTITUDE, alarm.getLongtitude());
   cv.put(AlarmColumn.LATITUDE, alarm.getLatitude());
   cv.put(AlarmColumn.ISON, alarm.isOn());
   mDBHelper.insert(AlarmColumn.TABLE_NAME, cv);
  
   //同样的查询数据、更新数据、删除数据等也可以直接利用DBHelper的接口来实现,并且支持任意表数据的扩展。


5、总结:本文主要是采用封装的方式来实现数据库中表的任意扩展,结构更加清晰并且容易理解,如果需要使用ContentProvider来实现的话,则可以直接在DBHelper的基础上进行封装实现。最后,再次感谢eoe社区中的开源eoe客户端代码,写的真不错。文章中有不妥之处,或者性能不高之处,望各位读者不啬赐教,谢谢!







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
一个简单的基于Android的Sqlite数据库操作封装,它有如下的好处:便捷地创建表和增添表字段灵活的数据类型处理通过操作对象来insert或者update表记录支持多种查询方式,支持多表自定义的复杂查询,支持分页查询支持事务快速开始:    1. 设计表:@Table(name="t_user") public class UserModel {     @Table.Column(name="user_id",type=Column.TYPE_INTEGER,isPrimaryKey=true)     public Integer userId;     @Table.Column(name="user_name",type=Column.TYPE_STRING,isNull=false)     public String userName;     @Table.Column(name="born_date",type=Column.TYPE_TIMESTAMP)     public Date bornDate;     @Table.Column(name="pictrue",type=Column.TYPE_BLOB)     public byte[] pictrue;     @Table.Column(name="is_login",type=Column.TYPE_BOOLEAN)     public Boolean isLogin;     @Table.Column(name="weight",type=Column.TYPE_DOUBLE)     public Double weight; }2. 初始化对象:SQLiteDatabase db = context.openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null); DbSqlite dbSqlite = new DbSqlite(db); IBaseDao userDAO = DaoFactory.createGenericDao(dbSqlite, UserModel.class);3. 创建表:userDAO.createTable(); 4. Insert 记录:UserModel user = new UserModel(); user.userName = "darcy"; user.isLogin = true; user.weight = 60.5; user.bornDate = new Date(); byte[] picture = {0x1,0x2,0x3,0x4}; user.pictrue = picture; userDAO.insert(user);5. Update 记录:UserModel user = new UserModel(); user.weight = 88.0; userDAO.update(user, "user_name=?", "darcy");6. 查询://单条结果查询 UserModel user = userDAO.queryFirstRecord("user_name=?", "darcy"); //一般查询 List userList = userDAO.query("user_name=? and weight > ?", "darcy" , "60"); //分页查询 PagingList pagingList = userDAO.pagingQuery(null, null, 1, 3);7. 事务支持:DBTransaction.transact(mDb, new DBTransaction.DBTransactionInterface() {         @Override         public void onTransact() {             // to do                 } };8. 更新表(目前只支持添加字段)@Table(name="t_user" , version=2) //修改表版本 public class UserModel {     //members above...     //new columns     @Table.Column(name="new_column_1",type=Column.TYPE_INTEGER)     public Integer newColumn;     @Table.Column(name="new_column_2",type=Column.TYPE_INTEGER)     public Integer newColumn2; } userDAO.updateTable();缺点和不足:还没支持多对一或者一多的关系没支持联合主键没支持表的外键设计其他...实例:SqliteLookup(Android内查看Sqlite数据库利器): https://github.com/YeDaxia/SqliteLookup 标签:SQLiteUtils

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值