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

来源:互联网 发布:微信网络诈骗投诉电话 编辑:程序博客网 时间:2024/06/03 13:00

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

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

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