美文网首页
Database 笔记

Database 笔记

作者: chauI | 来源:发表于2017-03-25 16:54 被阅读30次
    • 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<User> userList = new ArrayList<User>(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 笔记

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