Android知识梳理之Sqlite数据库的使用和优化

          PS.不知不觉间发现自己已经做了很久很久的Android开发了,过去对知识块的梳理总是放在云笔记里面.主要的原因还是自己的笔记太杂乱,没有脉络.本着开源的精神,也趁着这段时间有空将之前云笔记里面的文章梳理下.同时将一些知识点整理出来和大家共同分享.

转载请注明出处: http://blog.csdn.net/unreliable_narrator

         

      我们知道android中主要的五种数据储存形式分别是:文件存储,SharedPreferences,数据库,网络存储,content privder.一般在实际开发中比较少的能用到数据库来存储数据.一般当数据结构比较单一或者是固定的,或者是有关系的数据的时候就需要用到数据库来存储了.例如说聊天记录等等之类的.

      一.数据库的创建.

         常用的创建数据库的方式有两种:一种是通过数据库创建帮助类SQLiteOpenHelper来进行创建的,另外的一种就是直接调用Context.openOrCreateDataBase()来创建一个数据.

                 1.使用帮助类来创建一个数据,首先是创建一个类继承SqLiteOpenHelper,然后重写oncreate()和onupdata().使用getwritbledatabase()就可以打开一个可以读写的数据,如果只是进行数据的查询则使用getreadbledatabse()就可以返回一个可读取的数据库. 通过该方式生成的数据的路径是在dada/data/包名/databases 文件夹里面.     

public class MyDBOpenHelper extends SQLiteOpenHelper {
    /**
     * 创建一个名称为test的数据库
     *
     * @param context
     */
    public MyDBOpenHelper(Context context) {
        super(context, "test.db", null, 1);
    }
    /**
     * 数据库第一次被创建的时候调用,如果数据库已经创建,就不会执行这一句代码
     *
     * @param db 代表的就是我们创建出来的数据库
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建表
        db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20), phone varchar(20)) ");
    }

    /**
     * 当数据库的版本需要更新的时候调用的方法
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //db.execSQL("alter table info add money varchar(10)");
    }
}

          使用时:

MyDBOpenHelper openHelper =newMyDBOpenHelper(MainActivity.this);
//得到一个可以读写的数据库对象
SQLiteDatabase db = openHelper.getWritableDatabase();

             2.直接通过Context.openOrCreateDataBase()来打开或者是创建一个数据库.这种方式世界上内部也是调用的SQLiteDatabase.openOrCreateDatabase()来创建的数据.通过该方式创建的数据的的路径同样是在dada/data/包名/databases 文件夹里面.

SQLiteDatabase open = openOrCreateDatabase("myTest.db",Context.MODE_PRIVATE,null);
//在数据库里面创建info表
open.execSQL("create table info (_id integer primary key autoincrement, name varchar(20), phone varchar(20)) ");

      二.数据的CRUD操作.

        sqlite支持支持标准的sql语句,当然使用这些标准的sql语句也是有点弊端的,那就是无返回值,因此不能够判断对数据库的操作是否是成功了.因此google也提供了另外一套用于操作数据库的api.  

      添加一条数据:除了execSQL(标准的aql语句)可以使用insert(String table,String nullColumnHack,ContentValues values)方法来插入

  ContentValues cV = new ContentValues();
                            cV.put("name", "王小二");
                            cV.put("phone", "114");
                            //插入一条数据,如果返回值是-1就表示插入失败.
                            long info = mDb.insert("info", null, cV);

      删除一条数据:除了execSQL(标准的aql语句)还有delete(String table,String whereClause,String[] whereArgs),whereClause是删除条件,whereArgs是删除条件值数组。

 //删除info表里面name为王小二的数据
                int info = mDb.delete("info", "name=?", new String[]{"王小二"});

      修改一条数据:除了execSQL(标准的aql语句)还可以是update(String table,ContentValues values,String whereClause, String[] whereArgs)

    ContentValues values = new ContentValues();
                values.put("name", "狗蛋");//key为字段名,value为值
                mDb.update("info", values, "name=?", new String[]{"王小二"});

       查询数据:查找数据有两个方法,一是public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);,另外一个是public Cursor  rawQuery(String sql, String[] selectionArgs).rawQuery的写法类似上面的execSQL,在此不做介绍,query方法中的参数如下:

  • table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。
  • columns:要查询出来的列名。相当于select语句select关键字后面的部分。
  • selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
  • selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
  • groupBy:相当于select语句group by关键字后面的部分
  • having:相当于select语句having关键字后面的部分
  • orderBy:相当于select语句order by关键字后面的部分,如:name desc, phone asc;
  • limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。
     Cursor cursor = mDb.query("info", new String[]{"_id", "name", "phone"}, "phone=?", new String[]{"114200"}, null, null, null, null);
                    while (cursor.moveToNext()) {
                        int id = cursor.getInt(0); //获取第一列的值,第一列的索引从0开始
                        String name = cursor.getString(1);//获取第二列的值
                        int phone = cursor.getInt(2);//获取第三列的值
                    }
                    //记得一要把游标关闭,释放资源
                    cursor.close();

数据库的优化操作:

 当我们需要对比较多的数据进行数据库的操作是会阻塞线程,因此需要单独开启一个线程来进行数据库的相关操作.使用数据库的时候我们也可以使用事务来提高数据库的操作效率.

例如:我们要向一个数据库里插入1000条数据,我们看来比较一下开启事务和没有开启事务之间会有多少的性能误差.

 String currentTime = DateFormat.format("yyyy-MM-dd hh:mm:ss", new Date()).toString();
                Log.d("--", "前" + currentTime);
                new Thread() {
                    @Override
                    public void run() {
                        mDb.beginTransaction();
                        for (int x = 0; x < 20000; x++) {
 
                            ContentValues cV = new ContentValues();
                            cV.put("name", "王小二");
                            cV.put("phone", "114" + x);
                            //插入一条数据,如果返回值是-1就表示插入失败.
                            long info = mDb.insert("info", null, cV);
                        }
                        mDb.setTransactionSuccessful(); //循环结束后调用
                        mDb.endTransaction();//最后释放事务
                        String currentTime2 = DateFormat.format("yyyy-MM-dd hh:mm:ss", new Date()).toString();
                        Log.d("--", "后" + currentTime2);
                        mDb.close;
                    }
                }.start();

 

结果如下:

             没有使用事务的时候耗时约为:1分29秒

            

            使用事务后的时候大约是:0.02秒

            

由此可见使用事务的方式能够使对数据的操作起到立竿见影的效果.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值