Android 数据库初窥

作者: mymdeep | 来源:发表于2017-05-24 17:32 被阅读67次

    在Android中使用最多的就是SQLiteOpenHelper,这篇文章会从SQLiteOpenHelper入手,讲述一下SQLiteOpenHelper的用法,以及相关的调试。

    建立数据库

    首先需要建立一个类继承SQLiteOpenHelper

    public class MySql extends SQLiteOpenHelper {
        /**当数据库不存在时,就会创建数据库,然后打开数据库,再调用onCreate 方法来执行创建表之类的操作。
         * 当数据库存在时,SQLiteOpenHelper 就不会调用onCreate方法了,
         * 若传入的版本号高于当前的,就会执行onUpgrade()方法来更新数据库和版本号。
         * @param context
         * @param name 表示数据库文件名(不包括文件路径,默认路径是/data/data/包名/databases),SQLiteOpenHelper类会根据这个文件名来创建数据库文件。
         * @param factory 数据库进行查询的时候会返回一个cursor,这个cursor就是actory中产生的,factory可以进行自定义
         * @param version 表示数据库的版本号。如果当前传入的数据库版本号比上一次创建的版本高,SQLiteOpenHelper就会调用onUpgrade()方法。
         */
        public MySql(Context context, String name,
                     CursorFactory factory, int version) {
            super(context, name, factory, version);
    
    
        }
    
        /**当数据库首次创建时执行该方法,一般将创建表等初始化操作放在该方法中执行.
         *
         * @param sqLiteDatabase
         */
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.execSQL("create table if not exists person("
                + "id integer primary key,"
                + "name text,"
                + "sex text)");
        }
    
        /**当打开数据库时传入的版本号与当前的版本号不同时会调用该方法
         * @param sqLiteDatabase
         * @param oldVersion
         * @param newVersion
         */
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
    
        }
    }
    

    每一个参数的含义,可以参照我写的注释。
    我在这里通过执行sql语句"create table if not exists person(id integer primary key,name text,sex text)"创建了一个表。表名是person。
    我们写一个Activity,用来创建这个表:

     MySql mySql ;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mySql = new MySql(this,"test.db",null,1);
        }
    

    表名是test.db 版本号为1。

    查看表的结构

    如何查看表的结构呢?有以下几种办法(如果是真机,都需要是一个root的手机):

    SQLiteStudio

    我们可以借助一些pc上的工具查看数据库的表结构。例如SQLiteStudio,当然还有其它软件,这里不再做介绍。
    首先需要先将.db文件从手机中取出来,首先可以用adb pull命令进入到手机存储中,切换到指定的文件夹(上面提到过在/data/data/包名/databases),然后将上面建立的test.db文件pull出来。
    我一般使用的是Android monitor,点击一个按钮即可pull出来:


    然后倒入到SQLiteStudio中进行查看,如下图所示


    SQLScout

    与上面的方法不同的是,这是一个AndroidStudio的插件,首先需要安装这个插件。然后修改一下工程配置:
    首先是在工程的build.gradle中修改如下:

     allprojects {
          repositories {
              jcenter()
              maven {
                  url 'http://www.idescout.com/maven/repo/'
              }
          }
      }
    

    然后在module的build.gradle中添加:

    compile 'com.idescout.sql:sqlscout-server:2.1'
    

    或者去http://www.idescout.com/maven/repo/上直接把jar下载下来进行依赖也可以。
    然后修改你使用的Activity:

    SqlScoutServer.create(this, getPackageName());
    

    重新运行即可。
    在你安装完Android Studio插件后,IDE的右边会多一个:


    点开,选择你的app:

    操作

    插入数据

    首先需要获取SQLiteDatabase对象

      SQLiteDatabase db = mySql.getWritableDatabase();
    

    有两种方式可以进行数据插入,一种是执行原生的sql语句:

     db.execSQL("insert into person(name,sex) values('deep','man')");
    

    或者使用SQLiteDatabase提供的插入方法:

     ContentValues values = new ContentValues();
                    values.put("name", "deep");
                    values.put("sex",  "man");
                    db.insert("person", "id", values);
    

    很多时候我们需要批量的向数据库中插入大量数据时,单独的使用添加方法导致应用响应缓慢, 因为sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。
    我们可以用beginTransaction()的方式用来标志开启事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。
    同时可以配合insertOrThrow方法使用,判断是否插入成功。

      db.beginTransaction();
                    try {
                        ContentValues cv = new ContentValues();
                        values.put("name", "deep");
                        values.put("sex",  "man");
                        db.insertOrThrow("savedreports", null, cv);
                        db.setTransactionSuccessful();
                    } catch (SQLiteConstraintException e) {
                        return false;
                    } finally {
                        db.endTransaction();
                    }
    

    选取数据

    与上面的插入数据相同,也有如下几种方法
    首先就是利用rawQuery方法:

      SQLiteDatabase dbselect = mySql.getReadableDatabase();
                    Cursor cursor = dbselect.rawQuery("select * from "+"person", null);
                    while (cursor.moveToNext()) {
                        int id  = cursor.getInt(0);
                        String name = cursor.getString(1);
                        String sex = cursor.getString(2);
                        Log.e("deep","id = "+id+"  name= "+name+" sex="+sex);
                    }
    

    查看log可以得到:


    如果想指定id可以使用:

      Cursor cursor = dbselect.rawQuery("select * from person where id=?", new String[]{"1"});
    

    再有就是利用query方法:

      Cursor cursor = dbselect.query("person",new String[]{"name,sex"}, "id=?", new String[]{"1"},null,null,null);
                    while (cursor.moveToNext()) {
    
                        String name = cursor.getString(0);
                        String sex = cursor.getString(1);
                        Log.e("deep","  name= "+name+" sex="+sex);
                    }
    

    这个执行的意思是找到id = 1的一行,取出其中的name,和sex字段的值。
    query(table,columns, selection, selectionArgs, groupBy, having, orderBy)方法各参数的含义:

    • table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。
    • columns:要查询出来的列名。相当于select语句select关键字后面的部分。
    • selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
    • selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
    • groupBy:相当于select语句group by关键字后面的部分
    • having:相当于select语句having关键字后面的部分
    • orderBy:相当于select语句order by关键字后面的部分,如:personid desc, age asc;

    删除数据

    删除数据也是有两种,一种是使用原生的sql语句:

     SQLiteDatabase dbdelete = mySql.getWritableDatabase();
    dbdelete.execSQL("delete from person where id=1");
    

    或者使用delete方法:

     dbdelete.delete("person", "id=?",  new String[]{"2"});
    

    这个的意思是删除id = 2的一行。这里要注意,不是 new String[]{"2","3"}就是删除id等于2和3的两行,String数组的长度,要与前面的条件的数量对应。这里前面的条件是id=?这一个条件,所以String数组的长度只能为1。

    dbdelete.delete("person", "1", null);如果调用这个方法,表示删除所有行。

    更新字段

    更新字段也是有两种方式进行更新,第一种仍然是原生SQL:

     SQLiteDatabase updatedb = mySql.getWritableDatabase();
    updatedb.execSQL("update person set sex='woman' where id=4");
    

    或者使用update方法:

    ContentValues aaa = new ContentValues();
    aaa.put("name", "deep");
    aaa.put("sex",  "woman");
    updatedb.update("person",aaa,"id=?",new String[]{"6"});
    

    有疑问的朋友欢迎给我留言指正,或者关注我的公众号留言:


    相关文章

      网友评论

        本文标题:Android 数据库初窥

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