Database 笔记

  • SQLiteOpenHelper
  • SQLitDatabase
  • SQLitCursor

虽然很久以前就用上 SQLite,但是一直没有整理,在这里做下笔记
不过最后发现来来去去还是同样的东西,在这篇写完之后研究一下用文件来做对数据的持久化
参考并强力推荐 Android SQLite详解

建库建表

SQLiteOpenHelper 类主要用于帮助建数据库和建表

  • 继承 SQLiteOpenHelper
public class DatabaseHelper extends SQLiteOpenHelper {

    /**
     * 数据库的版本,upgrade 可以实现版本的变更
     */
    private static final int VERSION = 1;

    /**
     * 数据库的名字
     */
    private static final String DATABASE_NAME = "App";

    public DatabaseHelper(Context context){
        super(context,DATABASE_NAME,null,VERSION);
    }
    //数据的类型
    private static final String TEXT = "TEXT";
    private static final String INTEFER = "INTEFER";
    private static final String REAL = "REAL";

    //建表语句
    private static final String CREATE_NEWS_TABLE
            = String.format(Locale.getDefault(),
            "create table if not exists %s (" +
                    "%s %s, "+
                    "%s %s)",
            LocalDatabaseContract.News.NEWS_TABLE_NAME_T,
            LocalDatabaseContract.News.NEWS_TITLE,TEXT,
            LocalDatabaseContract.News.NEWS_IMGURL,TEXT);

    @Override
    public void onCreate(SQLiteDatabase db) {
        //执行建表语句
        db.execSQL(CREATE_NEWS_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //在升级数据库的时候重写该方法

    }
}

上面的 LocalDataBaseContract 以枚举的方式来用来保存表的字段 :

public class LocalDatabaseContract {
    public enum News{
        NEWS_TABLE_NAME,
        NEWS_TITLE,
        NEWS_IMGURL
    }
}

对于数据库的操作

借助 SQLiteOpenHelper 的实例来获取 SQLiteDatabase 类的实例,

mDatabaseHelper = new DatabaseHelper(mContext);
mDatabase = mDatabaseHelper.getWritableDatabase();

一个比较特殊的方法就是

//void execSQL (String sql);
//Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.

mDatabase.execSQL("");

参数里的字符串必须是完整的、标准的 SQL 语句,才可以返回正确的数据。
比如一个插入数据的操作可以这样写:

//往 person 表插入一条 name:UserName,age:18 的数据
mDatabase.execSQL("insert into person(name, age) values('UserName', 18)");
mDatabase.execSQL("insert into person(name, age) values(?,?)", new Object[]{"UserName", 18}); 

但这种方法比较麻烦,一般还是会使用 SQLiteDatabase 封装好的方法

  • 插入数据:
String title = "";
String ImgUrl = "";
//ContentValues 对象,类似一个 map 通过键值对的形式存储值
ContentValues contentValues = new ContentValues();
contentValues.put(LocalDatabaseContract
                        .News.NEWS_TITLE.toString(),title);
contentValues.put(LocalDatabaseContract
                        .News.NEWS_IMGURL.toString(),ImgUrl);
//执行插入操作,如果返回值小于 0 代表操作失败
long rowId = mDatabase.insert(
               LocalDatabaseContract.News.NEWS_TABLE_NAME.toString()
               ,null,contentValues);
if (rowId < 0){
     //数据库存储失败
}

insert 第一个参数是表名;第二个参数表示如果插入的数据每一个值都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;第三个数据就是插入的数据。

  • 删除数据
//开启事务
mDatabase.beginTransaction();
//删除表内 id 为 7 的数据
mDatabase.delete(LocalDatabaseContract.News.NEWS_TABLE_NAME
                      , "Id = ?", new String[]{String.valueOf(7)});
//设置事务执行成功
mDatabase.setTransactionSuccessful();
  • 更新数据
mDatabase.beginTransaction();
//将 id 为 6 的那条数据的 Long 数据更新为 800
ContentValues contentValues = new ContentValues();
contentValues.put("Long ", 800);
mDatabase.update(LocalDatabaseContract.News.NEWS_TABLE_NAME,
        contentValues,
        "Id = ?",
        new String[]{String.valueOf(6)});
mDatabase.setTransactionSuccessful();
  • 查询数据
    在数据库的操作中,查询语句向来是最难的,用 SQLite 也不例外。
    查询的方法有两个:
public Cursor query(String table,String[] columns,String selection
,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);

另一个其实和 execSQL 差不多

//第二个参数照例是对应 sql 语句里的参数集合
public Cursor rawQuery(String sql, String[] selectionArgs)

在 query 中

table:表名称
columns : 列名称数组
selection : 条件字句,相当于 where
selectionArgs : 条件字句,参数数组
groupBy : 分组列
having : 分组条件
orderBy : 排序列
limit : 分页查询限制
Cursor : 返回值,相当于结果集ResultSet

例如,查询 age 为 18 的用户的数据

mDatabase = ordersDBHelper.getReadableDatabase();
cursor = mDatabase.query(LocalDatabaseContract.News.NEWS_TABLE_NAME,
        ORDER_COLUMNS,
        "age = ?",
        new String[] {"18"},
        null, null, null);
if (cursor.getCount() > 0) {
    List userList = new ArrayList(cursor.getCount());
    while (cursor.moveToNext()) {
        User user= parseOrder(cursor);
        UserList.add(user);
    }
    return userList;
}

而这里的返回值是一个 Cursor 类型的数据,这个类是一个游标的作用,可以借助它的方法来遍历查询的结果

getCount();//获取返回结果的总数
isFirst();//是否在第一个
isLast();//是否到了最后
moveToFirst();//移动到第一个
moveToLast();//移动到最后
move(int i);//移动到指定
moveToNext();//移动到下一个
moveToPrevious();//移动到上一个

基本上就这些东西,也不是说很简单,相反查询操作还是很讲究的,但实际上 App 可能更多时候使用文件来缓存数据,只有少数的数据会使用数据库来存储,所以很多时候简单的操作就可以满足要求了。

你可能感兴趣的:(Database 笔记)