Android知识

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

2016-10-03  本文已影响0人  Dddddw

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

SQLite数据库

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

以上都是些废话。

在android中使用数据库比在java中要简单,最起码过程简单。先来介绍一下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

        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,就有刚刚创建的数据库:


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

数据库操作

       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条数据,对表进行拆表,比如可以先进行排序,再存入

对数据库进行增删改查

事务

对象关系映射ORM

上一篇下一篇

猜你喜欢

热点阅读