android SQLite数据库及SQLiteOpenHelper

1.SQLite数据库的好处
     SQLite是轻量级的数据库,是嵌入式的,不需要安装,启动服务器进程,而且也支持事物管理,占用的系统资源也比较少,专门适用于在资源有限的设备上适量数据存取。
     用官方的话来说:当所有的功能被打开的时候,根据目标平台和编译器的优化设置,库文件的大小可以小于500k(64位码更大,有的编译器优化也会导致更大),如果省略可选功能,可以减少到低于300k,SQLite占用的堆栈空间只有4~100k,在内存使用和速度上面有一个平衡。总之就是一个劲的跨它小而不失性能,简而不缺功能。

2.创建SQLite数据库
  看sqlitedabase的api上面的方法创建:
  openOrCreateDatabase(File file, CursorFactory factory);   //factory传null是调用默认的CursorFactory 
  openOrCreateDatabase(String path, CursorFactory factory);
  openOrCreateDatabase(String path, CursorFactory factory, DatabaseErrorHandler errorHandler);

 但是为了数据版本的升级和维护一般我们用的都是SQLiteOpenHelper创建,所以上面大家了解就够了。

3.数据库的操作 
  execSQL(String sql, Object[] bindArgs);    //增删改,返回指为null,开始我还一直想为啥查询不也用这个,逗比的发现没返回值,查出来也得不到...
  rawQuery(String sql, String[] selectionArgs) ; //用于查询操作,返回的cursor(下面有简单介绍cursor)

  //android提供很多方法来操作数据库,但是还是建议利用上面的方法,毕竟写数据库语句都是通用。
  insert(String table, String nullColumnHack, ContentValues values);
  query(String table, String[] columns, String selection,
            String[] selectionArgs, String groupBy, String having,
            String orderBy, String limit) ;          //api里面提供很多,不一一列出。
  replace(String table, String nullColumnHack, ContentValues initialValues);
  delete(String table, String whereClause, String[] whereArgs);
  update(String table, ContentValues values, String whereClause, String[] whereArgs) ;

4.什么是cursor
  源码里面给出的说明是:这个接口提供随机读写访问一个数据库查询返回的结果集。
  网上给的说明:Cursor 是每行的集合。
                           使用 moveToFirst() 定位第一行。 
                           你必须知道每一列的名称。 你必须知道每一列的数据类型。 
                            Cursor 是一个随机的数据源。
                            所有的数据都是通过下标取得。
  我给出代码吧:
Cursor c = db.rawQuery( "SELECT * from tablename where group_id = ? " , new String[] { group_id });
  while(c.moveToNext())
  {
        //假设第一列的列名为name,下面是两种取name数据的方式
       String name = c.getString(c.getColumnIndex("name"));    //这就是为什么要知道每列的数据类型和名称了
       String name2 = c.getString(0);    //不知道名称就要知道他是第几列(还是建议写上面的吧,方便维护代码)
   }
   c.close();  //一定要关闭cursor,不然会很悲剧的...
5.事物处理
   beginTransaction();               //手动设置事务开始,启动模式EXCLUSIVE mode
    beginTransactionNonExclusive();   //启动模式 IMMEDIATE mode
    setTransactionSuccessful();    //设置事务处理成功,不设置会自动回滚不提交。
    inTransaction();                   //判断是否在事务处理中,返回类型为boolean
    endTransaction();                  //处理完成
6.SQLiteOpenHelper的升级或降低数据库版本原理。
   我看的项目涉及到数据库,有直接在项目里面导入数据库的,有用内容提供者操作的,但是我在上家公司写的数据库还是用的SQLiteOpenHelper。
    SQLiteOpenHelper的构造方法:
   SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version);
   从源码上面来在调用getWritableDatabase和getReadableDatabase会执行getDatabaseLocked方法,在此方法中
有此代码,当版本高于数据库原版本则调用onUpgrade(),当小于原版本则调用onDowngrade():
            final int version = db.getVersion();
            if (version != mNewVersion) {
                if (db.isReadOnly()) {
                    throw new SQLiteException("Can't upgrade read-only database from version " +
                            db.getVersion() + " to " + mNewVersion + ": " + mName);
                }
                db.beginTransaction();
                try {
                    if (version == 0) {
                        onCreate(db);
                    } else {
                        if (version > mNewVersion) {
                            onDowngrade(db, version, mNewVersion);
                        } else {
                            onUpgrade(db, version, mNewVersion);
                        }
                    }
                    db.setVersion(mNewVersion);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
7.SQLiteOpenHelper类的具体实现代码。
public class DBHelper extends SQLiteOpenHelper {

 public static final String TABLE_NAME= "mytable";

 private static final int CURRENT_VERSION = 1;  //每次升级的时候数字加1

 public DBHelper(Context context, String name, CursorFactory factory) {
  //name为数据库名,null为默认的CursorFactory
  super(context, name , null, CURRENT_VERSION);
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
  db.execSQL("CREATE table IF NOT EXISTS "
    + TABLE_NAME
    + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, img TEXT,time TEXT,num TEXT,"
    + "message TEXT, group_id TEXT, isgroup TEXT, other_id TEXT)");
 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 //看上面第6部分贴的源码可知oldVersion即db.getVersion();(得到是已存在的数据库版本),newVersion为升级后的版本号。
  switch (newVersion) {
  case 2:
            if(oldVersion<2)
            {
                //执行从版本1升级到版本2操作
             }
  case 3:
            if(oldVersion<3)
            {
                //执行从版本2升级到版本3操作
             }
  case 4:
           break;
  }
 }
}


简单的写下数据库操作类:
    
public class GroupInfoDB {
 private DBHelper helper;

 public GroupInfoDB(Context context,String name,) {
  helper = new DBHelper(context,name ,null);
 }
 
 public void addGroup(GroupInfoBean entity) {
  SQLiteDatabase db = helper.getWritableDatabase(); 
  //建议用sql语句写,本例只是个demo
  ContentValues values = new ContentValues();
  values.put("group_id", entity.getGroup_id());
  db.insert(DBHelper.TABLE_NAME, null, values);
 }
 public void close() {
  if (db.isOpen())
   db.close();
 }
}




8.getWritableDatabase与getReadableDatabase的区别
      原谅我英文翻译水平,借用一篇博客的解释(上面也贴了源码):
     getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就会出错。
         getReadableDatabase()方法则是先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。如果该问题成功解决,则只读数据库对象就会关闭,然后返回一个可读写的数据库对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值