美文网首页干货区数据库Android开发经验谈
不会点SQLite,都不好意思说自己是开发的

不会点SQLite,都不好意思说自己是开发的

作者: silencezwm | 来源:发表于2016-07-23 10:49 被阅读1141次

    原文链接:
    https://juejin.im/post/5a055a9d5188251c114016c2

    一、为什么要会点SQLite?

    SQLite作为一款轻量级的关系型数据库,占用的资源特别少,所以其应用场景也是特别的多。在移动开发中,我们经常会有将数据存储在本地的需求,此时SQLite将是我们最佳的选择。
    可喜的是,SQLite已经被完美的集成在Android系统中,所以对于开发者而言,上手SQLite的难度又降低了不少。

    二、开始玩玩SQLite

    首先来说说在Android中操作SQLite数据库的整体思路:

    1、自定义数据库操作辅助类,并继承自SQLiteOpenHelper类;
    2、在Application中初始化SQLiteOpenHelper对象,并公开一个方法供其他类调用获取该对象;
    3、根据SQLiteOpenHelper对象实例化SQLiteDatabase对象;
    4、最后,我们拿SQLiteDatabase对象即可进行SQLite数据库的常规操作了。
    

    其实整个流程并不复杂,稍微来点耐心,动动手指头,再回头瞧瞧SQLite,“哇哦,操作你如此简单!”

    1、自定义数据库操作辅助类,并继承自SQLiteOpenHelper类

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    /**
      * author:silencezwm on 16/6/20 06:43
      * email:silencezwm@gmail.com
      * description:数据库操作辅助类
      */
    public class DBHelper extends SQLiteOpenHelper {
    
        //数据库名称
        private static final String DBName = "study.db";
        //数据库版本号
        private static final int DBVersion = 1;
    
        //构造方法
        public DBHelper(Context context) {
            super(context, DBName, null, DBVersion);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            //创建表---study
            db.execSQL("CREATE TABLE study ( _id integer PRIMARY KEY AUTOINCREMENT NOT NULL, bookName varchar, bookDesc varchar)");
        }
    
        /**
          * 数据库版本更新
          * @param db            数据库实例
          * @param oldVersion    旧版本号
          * @param newVersion    新版本号
          */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS study");
            onCreate(db);
        }
    }
    

    该类继承了SQLiteOpenHelper,并实现了三个方法,其中onCreate()在数据库初始化时会调用,onUpgrade()方法只有在数据库新版本号大于旧版本号时才会调用,即进行数据库的更新操作。其中涉及到了常用SQL语句的书写,看不懂的童鞋得抽空脑补一下这方面的知识哦。

    SQLiteOpenHelper有什么用?

    该SQLiteOpenHelper是Android平台提供给我们的数据库辅助类,用于创建或打开数据库。
    

    2、在Application中初始化SQLiteOpenHelper对象,并公开一个方法供其他类调用获取该对象

    考虑到整个应用中的不同地方都有可能涉及到数据库的操作,所以我们有必要将该类的初始化放在我们自定义的Application类中。就像该下:

    public class MyApp extends Application {
    
        //数据库辅助类实例
        private static DBHelper mDBHelper;
    
        @Override
        public void onCreate() {
            super.onCreate();
            mDBHelper = new DBHelper(getApplicationContext());
        }
    
        //返回DBHelper实例,
        public static DBHelper getmDBHelper(){
            return mDBHelper;
        }
    }
    

    我们来看看初始化SQLiteOpenHelper类源码的实现方式

    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
        this(context, name, factory, version, null);
    }
    

    参数含义解析:

    context:上下文对象,这里我们传入了ApplicationContext;
    name:数据库名称,这里我们定义为"study.db";
    factory:操作数据库后返回的默认Cursor对象,这里我们默认为null,后续需要保存返回的Cursor对象时,自己再进行构造;
    version:数据库的版本号,初始版本号必须大于1,否则系统会抛IllegalArgumentException("Version must be >= 1, was " + version)异常。
    

    3、根据SQLiteOpenHelper对象实例化SQLiteDatabase对象

    该操作将会让我们得到SQLiteDatabase对象,而一旦有了该对象,我们就可以进行数据库的增删改查操作了。该操作我们可以单独封装在某个类,同样也可以直接在某个Activity中实现。
    核心代码如下:

    //获取的数据库对象
    //其中 getWritableDatabase() 和 getReadableDatabase() 区别???
    SQLiteDatabase db = MyApp.getmDBHelper().getWritableDatabase();
    //SQLiteDatabase db = MyApp.getmDBHelper(). getReadableDatabase();
    

    得到SQLiteDatabase实例有以上两种方法,两种方法的主要区别在于:

    在数据库仅开放只读权限或磁盘已满时,getReadableDatabase只会返回一个只读的数据库对象。
    

    另外在我们每次初始化SQLiteDatabase对象时,系统都会进行数据库版本号的判断,该判断的核心代码如下(有兴趣的童鞋可以研究下getWritableDatabase()、getReadableDatabase()的源码实现):

    //获取数据库版本号,默认为0
    final int version = db.getVersion();
            //如果老版本号与新版本号不同
            if (version != mNewVersion) {
                //如果数据库为只读,系统则会抛出"SQLiteException"异常
                if (db.isReadOnly()) {
                    throw new SQLiteException("Can't upgrade read-only database from version " +
                            db.getVersion() + " to " + mNewVersion + ": " + mName);
            }
    
            //数据库开启事务
            db.beginTransaction();
            try {
                //表示数据库第一次创建,则会进入我们文章最上面自定义DBHelper类的onCreate()方法
                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();
            }
        }
    

    4、拿SQLiteDatabase对象进行SQLite数据库的常规操作

    该下简略介绍两种操作方法:

    1、使用SQL语句
    2、使用Android封装好的方法
    

    我们在初始化SQLiteDatabase对象的时候,创建了一个数据库:study.db,并在数据库中创建了一个表:study,表中包含主键自增 _id , 还有两个字段:bookName、bookDesc。
    该下代码实现了往数据库中插入、更新、查询、删除四种常用操作,此时你应该亲自动手试试...

        //插入数据
        case R.id.btn_insert:
            //使用SQL语句
            if (useSQL) {
                db.execSQL("insert into study values(null, ?, ?)",
                        new Object[]{et_insert_book_name.getText().toString(), et_insert_book_desc.getText().toString()});
    
            //使用Android封装的方法
            } else {
                //其中cv为ContentValues的实例
                cv.put("bookName", et_insert_book_name.getText().toString());
                cv.put("bookDesc", et_insert_book_desc.getText().toString());
    
                long isOK = db.insert("study", null, cv);
    
                //-1代表操作失败
                if (isOK == -1) {
                    Toast.makeText(DBDemoActivity.this, "插入失败", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(DBDemoActivity.this, "插入成功", Toast.LENGTH_SHORT).show();
                }
            }
            break;
    
        //更新数据
        case R.id.btn_update:
    
            if (useSQL) {
                db.execSQL("update study set bookName = ? where bookName = ?", new String[]{et_update_new_book_name.getText().toString(), et_update_book_name.getText().toString()});
            } else {
                cv.put("bookName", et_update_new_book_name.getText().toString());
    
                int updateCount = db.update("study", cv, "bookName = ?", new String[]{et_update_book_name.getText().toString()});
    
                //更新后更新的个数,"0"表示更新失败
                if (updateCount != 0) {
                    Toast.makeText(DBDemoActivity.this, "更新成功,共更新个数:" + updateCount, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(DBDemoActivity.this, "更新失败", Toast.LENGTH_SHORT).show();
                }
            }
            break;
    
        //查询操作
        case R.id.btn_query:
    
            if (useSQL) {
                Cursor cursor = db.rawQuery("select * from study", null);
                StringBuilder sb = new StringBuilder();
                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                    sb.append("总数:" + cursor.getCount() + "\\\\n" + "书名:" + cursor.getString(cursor.getColumnIndex("bookName"))
                            + "----该书简介:" + cursor.getString(cursor.getColumnIndex("bookDesc")));
                    text_query_result.setText(sb.toString());
                }
                //记得进行关闭哦
                cursor.close();
            } else {
                //查询该表中所有数据
                Cursor c = db.query("study", null, null, null, null, null, null);
    
                StringBuffer sb = new StringBuffer();
                for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
                    sb.append("总数:" + c.getCount() + "\\\\n" + "书名:" + c.getString(c.getColumnIndex("bookName"))
                            + "----该书简介:" + c.getString(c.getColumnIndex("bookDesc")));
                    text_query_result.setText(sb.toString());
                }
                //记得进行关闭哦
                c.close();
    
            }
            break;
    
        //删除操作
        case R.id.btn_del:
    
            if (useSQL) {
                db.execSQL("delete from study where bookName = ?", new String[]{et_del_book_name.getText().toString()});
            } else {
                db.delete("study", "bookName = ?", new String[]{et_del_book_name.getText().toString()});
            }
    
            break;
    

    三、SQLite说

    ”555...又被你看穿了“

    相关文章

      网友评论

      本文标题:不会点SQLite,都不好意思说自己是开发的

      本文链接:https://www.haomeiwen.com/subject/kqqwjttx.html