美文网首页Android知识
第六章--绕不开的数据库SQLite

第六章--绕不开的数据库SQLite

作者: Dddddw | 来源:发表于2016-10-03 13:39 被阅读0次

    两周就和群里的人有了好大的差距,在绵阳的日子真不好熬,也想把它当作一种磨练,但一边每天去实习,心里总是挂着学习这个的事,心里焦灼,也想向辅导员请假回学校,但是好像在老师眼中,考研学习才是重要的事,其他学习就不重要。喝个鸡汤,加油你可以的。。。。

    SQLite数据库

    还记得大二时学的数据库,当初还想好好听课,坐在第一排,然而后面就开始在课堂上睡觉。期末考试的时候,复习了几天,记住了一些语句,然后就去参加考试。全学院要学的大课,安排了好多考场,不过是选修,后面去考的人寥寥无几。这样学知识的后果就是学完就忘,并且理解的太浅,或者说没有理解,和学过的数据结构一样。

    以上都是些废话。

    在android中使用数据库比在java中要简单,最起码过程简单。先来介绍一下SQLite,她是一个嵌入式的数据库引擎,专门适用于资源有限的设备上适量数据的存取。

    它有以下的优点:

    • 轻量级:使用SQLite数据库不需要向mysql一样安装,启动服务进程,它自己只是一个文件
    • 独立:SQLite的核心引擎本身不依赖第三方的软件,有点类似那种绿色软件,不需要软件
    • 隔离:我理解的就是它只是一个文件,不依赖其他存在,所以隔离性好
    • 跨平台:除了主流操作系统 windows,linux之后,SQLite还支持其它一些不常用的操作系统。
    • 多语言接口:SQLite 数据库支持多语言编程接口。
    • 安全:SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一个可以写入数据。

    SQLiteDatabase

    android提供了SQLiteDatabase代表一个数据库,一旦获得了这个对象就可以用来操作数据库了。首先SQLite有静态方法openDatabase(..)和openOrCreateDatabase(..)方法来打开和创建数据库,android提供了一种更加优雅的方式来创建和更新数据库,SQLiteOpenHelper这个类,所以以下就是从介绍它开始

    SQLiteOpenHelper类

    创建一个类继承SQLiteOpenHelper

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    /**
     *
     * Created by W on 2016/8/13.
     */
    public class DatabaseHelper extends SQLiteOpenHelper {
    
        public static final String USER_TABLE_NAME = "user";
        public static final String USERNAME = "username";
        public static final String AGE = "age";
        public static final String DATABASE_NAME = "text.db";
        public static final int VERSION = 1;
    
        public DatabaseHelper(Context context ) {
            //name:数据库的名字,factory:null,版本
            super(context, DATABASE_NAME, null,  VERSION);
        }
    
        //创建数据库
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("create table " + USER_TABLE_NAME + " (" + USERNAME + " varchar(20) not null, " + AGE + " varchar(60) not null);");
        }
    
        //升级数据库
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            //TODO:an database upgrade
    
        }
    }
    

    该类的构造器中传入上下文,数据库的名字后缀是.db,null,版本号。下面两个必须重写的方法。onCreate(),用于初次使用软件时生成数据库表,可以添加一些应用使用时的一些初始化数据。onUpgrade(),用于更新软件时升级数据库表结构。以上的代码就创建了一个text的数据库文件。里面有一个表user,有username,age两个字段。

    Activity

    • 新建一个活动,在onCreate方法中初始化。
            DatabaseHelper databaseHelper = new DatabaseHelper(this);
            //两种,可读的和可写的.磁盘满了之后,就只能读; 。
            mSqLiteDatabase = databaseHelper.getReadableDatabase();
    

    除了gerReadableDatabase(),还有getWriteableDatabase()。两者没有什么区别,只有当磁盘满了之后,就只能读不能写了。当DatabaseHelper对象调用这个方法的时候,如果数据库不存在,android系统会自动生成一个数据库,接着调用onCreate()方法。

    • 然后我们在布局文件中写入三个按钮,分别是增删更
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".DatabaseButtonActivity">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="add"
            android:textAllCaps="false"
            android:id="@+id/add_button"/>
        <Button
            android:id="@+id/delete_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="delete"
            android:textAllCaps="false"
            android:layout_below="@id/add_button"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/delete_button"
            android:text="update"
            android:textAllCaps="false"
            android:id="@+id/update_button"/>
    
    </RelativeLayout>
    
    

    在activity中初始化按钮绑定监听器。此时如果启动软件,在/data/data/<包名>/Databases文件下就有我们创建的数据库,如图:


    这里写图片描述

    点开text.db,就有刚刚创建的数据库:


    这里写图片描述
    这样就是创建好了一个表

    数据库操作

    • 首先是增,使用insert插入数据,先看代码
           ContentValues contentValues = new ContentValues();
                    contentValues.put(DatabaseHelper.USERNAME , "haha");
                    contentValues.put(DatabaseHelper.AGE, "12");
    
                    long rawNumber =  mSqLiteDatabase.insert(DatabaseHelper.USER_TABLE_NAME, null, contentValues);
                    if (rawNumber != -1){
                        Toast.makeText(DatabaseButtonActivity.this,"插入成功" ,Toast.LENGTH_LONG).show();
                    }
    

    insert()方法里面的参数:

    1. table:想插入数据库的表名
    2. nullColumsnHack:代表强行插入null值的数据列的列名。
    3. valus:代表一行记录的数据

    当插入有异常的时候会返回一个long类型的-1值。

    • 然后是删:
    String whereClauseString = "username=?";
                    String[] whereArgsString = {"haha"};
                    mSqLiteDatabase.delete(DatabaseHelper.USER_TABLE_NAME, whereClauseString, whereArgsString);
    

    里面参数的意思就是,在表中username=haha的数据都删除。

    • 更新数据:
    ContentValues contentValues1 = new ContentValues();
                    contentValues1.put(DatabaseHelper.AGE, "100");
                    String whereClauseString1 = "username=?";
                    String[] whereArgsString1 = {"haha"};
                    mSqLiteDatabase.update(DatabaseHelper.USER_TABLE_NAME,contentValues1, whereClauseString1, whereArgsString1);
    

    这个和insert有点像,都是先用ContentValus对象把存入的数据写好,然后传到updata的参数里,以上代码的意思就是把user表中username=haha的年纪改成100。

    • 最后数据库中的查询操作

    在SQLite中查询记录要依靠Cursor(游标),他有一些方法来移动查询结果的记录指针

    1. boolean moveToFirst():将记录指针移到第一行,成功返回true
    2. boolean moveToNext():移动到下一行,当只执行一次的时候,相当与moveToFirst
    3. boolean moveToPosition(int positon):移动到指定行,其实看到这里群里有人提出,moveToNext不是移到了下一个记录了吗?那第一个记录不是没有查询到?然后在这个方法里得到了解释,position默认的值并不是0,而是-1。所以刚开始的指针不是指着第一个记录,而是第一个记录的前面,所以用moveToNext也能查询到第一个记录。

    先看代码:

        private void QueryDatabase() {
            //游标
            //query:查询
            Cursor cursor = mSqLiteDatabase.query(DatabaseHelper.USER_TABLE_NAME, null, null, null, null, null, null);
            if (cursor.moveToFirst()){
                int count = cursor.getCount();
                for (int i = 0; i < count; i++) {
                    String userName = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.USERNAME));
                    String age = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.AGE));
                    Log.i(DatabaseButtonActivity.class.getSimpleName(), i + ":" + userName + ":" + age);
                    cursor.moveToNext();
                }
    
            }
            
    
        }
    

    query里面参数有3种形式,以最多那个来解释一下:

    1. boolean distinct:是否去掉重复的记录
    2. String table:查询数据的表名
    3. String[] columns:查询的列名。相当于select后面的关键字
    4. String whereClause:查询条件子句。where...
    5. String[] selectionArgs:用于为whereClause子句中的占位符传入参数值。
    6. String groupBy:控制分组
    7. String having:分组的过滤
    8. String orderBy:排序
    9. String limit:进行分页

    query返回的是Cursor对象,getString()取出某一列的数据。

    以上就是数据库的基本操作,但是除了创建表的时候,都没有使用过原始的sql语句,据说android为了考虑不太熟悉数据库语句的人,所以提供了这些方法。我看的这本书的作者一直在吐槽这种做法,说作为程序员,数据库操作应该是最基本的素养。其实我觉得吧,我现在用着挺好的哈哈。可以用execSQL()和rawSQL()方法来执行原始的sql语句,而且效率也要高。

    最后,相关的io操作还是不要和我一样放在主线程里,毕竟阻塞主线程是大忌。


    这些是老师讲的内容,也没怎么理解,比如什么时候使用事务可以达到效率最大化,先留在这。。

    如何设计数据库和表

    上万条数据如何建表,比如300个城市,每个城市600条数据,对表进行拆表,比如可以先进行排序,再存入

    对数据库进行增删改查

    • 原始SQL语句效率更高rawQuery,execSQL
    • 只检索有用的信息,有用的列,有用的行,越少越好
    • 是否排序
    • 是否创建索引

    事务

    • //开始事务,数据库会被锁定
      begainTransaction();
    • //操作
    • ...
    • setTransactionSuccessful();
      endTransaction()

    对象关系映射ORM

    • 关系数据库和实体对象进行映射。
    • 优点:方便的进行数据库操作
    • 缺点:效率比较低,不够灵活

    相关文章

      网友评论

        本文标题:第六章--绕不开的数据库SQLite

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