Android开发中SQLite Expert的操作技巧

来源:互联网 发布:c语言实现面向对象 编辑:程序博客网 时间:2024/06/06 09:46

最近学习SQLite Expert,了解过后,才觉得和MySql同工异曲,深度学习android开发,就必须了解Sqlite Expert,才能更上一层楼。

在之前的一篇文章中我已经粗浅的介绍了SQLite的基本使用方法,这一骗我重点介绍一下SQlite的事务操作,适配器操作,分页操作等技巧.

当然,先简单的温习一下Sqlite基本方法,http://blog.csdn.net/google_huchun/article/details/71105034

学习SQLite ,就必须学习语法技巧,对query要有很深的理解,才能进步。

    SQLiteDatabase db = SQLiteDb.getWritableDatabase();                /**                 * query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)                 * String table 表示查询的表名                 * String[] columns 表示查询表中的字段名称,null 查询所有                 * String selection 表示查询条件 where子句                 * String[] selectionArgs 表示查询条件占位符的取值                 * String groupBy 表示分组条件 group by 子句                 * String having 表示率选条件 having 子句                 * String orderBy 表示排序条件 order by 子句                 */                Cursor cursor=db.query(Constant.TABLE_NAME, null, Constant._ID+">?", new String[]{"10"}, null, null, Constant._ID+" desc");                List<Person> list = DbManager.cursorToList(cursor);                for (Person p : list){                    Log.i("tag", p.toString());                }                db.close();

这是query使用说明。

增删改查是SQLite的基本使用方法,认识后,再来看SQLite事务操作,用代码介绍;

SQLiteDatabase db = mHelper.getWritableDatabase();    // 开启事务    db.beginTransaction();    for (int i=1;i<=100;i++){        String sql = "replace into "+ Constant.TABLE_NAME+ " values("+i+", 'hucc"+i+"', 1822220)";        db.execSQL(sql);    }    // 设置事务标志成功,当结束事务时就会提交事务    db.setTransactionSuccessful();    // 结束事务    db.endTransaction();    db.close();

解释一下,这里使用的replace 代替了 insert 方法,因为使用insert容易引起
Android:android.database.sqlite.SQLiteConstraintException:UNIQUE constraint failed。

SQlite使用的适配器,是SimpleCursorAdapter和CursorAdapter,而Cursor游标就相当于Java中的HashMap一样,使用起来很方便。

SimpleCursorAdapter:

  /**     * 将数据源数据加载到适配器中     * SimpleCursorAdapter(Context context, int list_item, Cursor c, String[] from, int[] to, int flags)     *  Context context 上下文对象     *  int list_item 表示适配器控件中每项item 的布局id     *  Cursor c 表示Cursor 数据源     *  String[] from 表示cursor 中数据表字段的数组     *  int[] to 表示展示字段对应值的控件资源id     *  int flags 设置适配器的标记     */ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, new String[]{Constant._ID, Constant.NAME, Constant.PHONE}, new int[]{R.id.tv_id, R.id.tv_name,R.id.tv_phone}                                 SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

CursorAdapter:

 /**      *  以内部类的定义形式适配器 */  /**     *  表示创建适配器控件中每个item对应的view对象     * @param context 上下文     * @param cursor  数据源cursor对象     * @param parent  当前item的父布局     * @return  每项item的view对象     */    @Override    public View newView(Context context, Cursor cursor, ViewGroup parent) {        View view = LayoutInflater.from(context).inflate(R.layout.list_item,null);        return view;    }/**     *  通过newview()方法确定了每个item展示的view对象,在bindview()对布局中的控件进行填充     * @param view 由newView()返回的每项view对象     * @param context  上下文     * @param cursor  数据源cursor对象     */    @Override    public void bindView(View view, Context context, Cursor cursor) {        TextView tv_id = (TextView) view.findViewById(R.id.tv_id);        TextView tv_name = (TextView) view.findViewById(R.id.tv_name);        TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone);        tv_id.setText(cursor.getInt(cursor.getColumnIndex(Constant._ID))+"");        tv_name.setText(cursor.getString(cursor.getColumnIndex(Constant.NAME)));        tv_phone.setText(cursor.getInt(cursor.getColumnIndex(Constant.PHONE))+"");    }

常用的数据适配器就是以上两种,这是我根据自己的程序张贴出该模块。

当然了,也可以使用BaseAdapter操作,下来我会介绍这个适配器。

说起数据,我们使用数据就是要处理数据,根据数据才能持续开发,数据的分页操作是SQLite的重点。这里我就用ListView+BaseAdapter来介绍。

数据的分页需要自定义几类参数,

private int totalNum; //表示加载当前控件加载数据总条目private int pageSize = 20; // 表示当前数据条目private int pageNum; // 表示总页码private int currentPage = 1; // 当前页码private boolean isDivPage;private List<Person> totalList;

在onCreate()初始化数据操作,

// 获取数据表数据总数目    totalNum = DbManager.getDataCount(db,Constant.TABLE_NAME);    // 根据总条目与每页展示数据条目,获得总页数    pageNum = (int) Math.ceil(totalNum / pageSize);    if (currentPage == 1){         totalList = DbManager.getListByCurrentPage(db,Constant.TABLE_NAME,currentPage,pageSize);    } final MyBaseAdapter mAdapter = new MyBaseAdapter(this, totalList);    mListView.setAdapter(mAdapter);    mListView.setOnScrollListener(new AbsListView.OnScrollListener() {        @Override        public void onScrollStateChanged(AbsListView view, int scrollState) {            if (isDivPage && AbsListView.OnScrollListener.SCROLL_STATE_IDLE == scrollState){                if (currentPage<pageNum){                    currentPage++;                    // 根据最新页码加载获取集合存储到数据源中                    totalList.addAll(DbManager.getListByCurrentPage(db,Constant.TABLE_NAME, currentPage,pageSize));                    mAdapter.notifyDataSetChanged();                }            }        }        @Override        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {            isDivPage = ((firstVisibleItem + visibleItemCount)==totalItemCount);        }    });

这是我事先操作了一个数据表”info.db”,添加在assets中,这样就需要打开该数据表,

private SQLiteDatabase openDatabase(Context context) {    File file = new File(DATABASE_PATH);    //查看数据库文件是否存在    if (file.exists()){        Log.i("test", "存在数据库");        // 存在则直接返回打开的数据库        return SQLiteDatabase.openOrCreateDatabase(file, null);    }else{        //不存在先创建文件夹        File path = new File(DATABASE_PATH);        Log.i("test", "pathStr="+path);        if (path.mkdir()){            Log.i("test", "创建成功");        }else{            Log.i("test", "创建失败");        }        try {            //得到资源            AssetManager am = context.getAssets();            //得到数据库的输入流            // InputStream is = am.open(Constant.DATABASE_NAME);            // InputStream is = am.open("info.db");            InputStream is = am.open(String.valueOf(R.raw.info));            Log.i("test", is+"");            //用输出流写到SDcard上面            FileOutputStream fos = new FileOutputStream(file);            Log.i("test", "fos="+fos);            Log.i("test", "file="+file);            //创建byte数组  用于1KB写一次            byte[] buffer = new byte[1024];            int count = 0;            while ((count = is.read(buffer))>0){                Log.i("test", "得到");                fos.write(buffer, 0, count);            }            fos.flush();            fos.close();            is.close();        }catch (IOException e){            e.printStackTrace();            return null;        }    }    return openDatabase(context);}

就是代码,就是如何打开sqlite的步骤。数据的分页操作就需要根据数据表名称获取数据总条目:

  /*  *  id 数据库对象 *   tableName 数据表名称 *   数据总条目 */public static int getDataCount(SQLiteDatabase db, String tableName){    int count = 0;    if (db != null){        Cursor cursor = db.rawQuery("select * from "+tableName, null);        count = cursor.getCount(); // 获取cursor中的数据总数    }    return count;

另外需要根据当前页码查询获取该页码的聚合数据.

 /** @param db  数据库对象 * @param tableName  数据表名称 * @param currentPage  当前页码 * @return  当前页对应的集合 * *  select * from person ?,?  如何根据当前页码获取该页数据 */public static List<Person> getListByCurrentPage(SQLiteDatabase db, String tableName, int currentPage, int pageSize){    int index = (currentPage-1)*pageSize; // 获取当前页码第一条数据的下标    Cursor cursor = null;    if (db != null){        String sql = "select * from "+tableName+" limit ?,?";        cursor = db.rawQuery(sql, new String[]{index+"", pageSize+""});    }    return cursorToList(cursor);   //将查询的cursor对象转换成list集合}

需要更多的知识可以关注本人的代码库:

https://git.oschina.net/huchun/sqliteexpert

这些就是数据库的高级技巧,当然了还有更多的使用技巧没有介绍出,本人能力有限嘛,还在继续学习中,如有好什么疑问,我们再继续交流,探讨技术,一起提高!

原创粉丝点击