sqlite学习及封装

编程是一种快乐,这种快乐让我更加热爱生活!

昨天花了点时间整理下sqlite的学习及封装,今天把代码上传,供大家一起进步。

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.util.Log;

import java.util.concurrent.CancellationException;

/**
 * Created by GM on 2017/4/5 0005
 * Version V1.0.0
 * Description: 《SQLite学习及封装》
 *
 * 特点:
 * (1)轻量级
 * (2)零配置、无服务器
 * (3)单一文件、简单的访问
 * (4)跨平台/可移植
 * (5)弱类型的字段
 * (6)开源
 * (7)可变长度的记录
 * (8)内存数据库
 *
 * 数据类型:
 *      NULL:这个值为空值
 *      VARCHAR:长度不固定且其最大长度为 n 的字串,n不能超过 4000
 *      CHAR:长度固定为n的字串,n不能超过 254
 *      INTEGER:值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,5,6,7,8
 *      REAL:所有值都是浮动的数值,被存储为8字节的IEEE浮动标记序号
 *      TEXT:值为文本字符串,使用数据库编码存储(TUTF-8, UTF-16BE or UTF-16-LE)
 *      BLOB:值是BLOB数据块,以输入的数据格式进行存储。如何输入就如何存储,不改  变格式
 *      DATA:包含了 年份、月份、日期
 *      TIME:包含了 小时、分钟、秒
 *
 * 1、getWritableDatabase跟getReadableDatabase的区别:
 *      getWritableDatabase取得的实例不是仅仅具有写的功能,而是同时具有读和写的功能;
 *      getReadableDatabase取得的实例也是具对数据库进行读和写的功能
 *
 *      getWritableDatabase:取得的实例是以读写的方式打开数据库,如果打开的数据库磁盘满了,此时只能读不能写,
 *                         此时调用了getWritableDatabase的实例,那么将会发生错误(异常)
 *      getReadableDatabase:取得的实例是先调用getWritableDatabase以读写的方式打开数据库,如果数据库的磁盘满了,
 *                          此时返回打开失败,继而用getReadableDatabase的实例以只读的方式去打开数据库
 *
 * 2、rawQuery与query的区别:
 *      eg:Cursor cursor = db.rawQuery("select name from *** where id=?", new String[]{"1"});
 *         Cursor cursor = db.query("***", new String[]{"name"}, "id=?", new String[]{"1"}, null, null, null);
 *         那么最后都执行rawQueryWithFactory,query相对于rawQuery出错的机率小(有时候语句写错),query是android自己封装的API
 *
 *
 */

public class DBUtils {

    //. 数据库名称
    private static final String DB_NAME = "fengzhuan.db";
    //. 数据库版本
    private static final int DB_VERSION = 1;
    //. 旧版本号
    private static final int OLD_VERSION = DB_VERSION;
    //. 新版本号
    private static final int NEW_VERSION = 2;

    private SQLiteDatabase mDb;
    private DBHelper mDbHelper;
    private Context mContext;

    private static class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context) {
            //. 第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
            super(context, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            //. 表第一次不存在时创建
            db.execSQL("create table message(id integer primary key autoincrement, mid VARCHAR(20), user VARCHAR(20)," +
                    " title VARCHAR(255), msg VARCHAR(255), state int(1), type int(2), time VARCHAR(20));");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (oldVersion==OLD_VERSION && newVersion==NEW_VERSION) {
                //. 版本升级后,可以实现新操作
                //. eg:这里就往原来的phone表中插入age字段
                db.execSQL("alter table phone add age text;");
            }
        }
        //. 判断表是否存在后,再创建表
        public boolean tableIsExist(String tableName){
            boolean isTableExist = true;
            SQLiteDatabase db = getReadableDatabase();
            Cursor cursor = db.rawQuery("select count(*) from sqlite_master where type='table' and name='"+tableName+"';", null);
            while (cursor.moveToNext()) {
                if (cursor.getInt(0)==0) {
                    isTableExist=false;
                }
            }
            cursor.close();
            db.close();
            return isTableExist;
        }
    }

    public DBUtils(Context context) {
        this.mContext = context;
    }

    /**
     *. 打开数据库(使用getWritableDatabase不能再写入则会出现异常,因此在此做异常处理)
     * */
    public DBUtils openDB(){
        mDbHelper = new DBUtils.DBHelper(mContext);
        try {
            mDb = mDbHelper.getWritableDatabase();
        }catch (SQLException e) {
            mDb = mDbHelper.getReadableDatabase();
            Log.d("数据库磁盘已经满了,", "进入getReadableDatabase模式!");
        }
        return this;
    }

    /**
     *. 关闭数据库
     * */
    public void closeDB(){
        if(mDbHelper != null){
            mDbHelper.close();
        }
    }

    /**
     *. 判断表是否存在
     * */
    public boolean tableExist(String tableName) {
        return mDbHelper.tableIsExist(tableName);
    }

    /**
     *. 创建新表
     * */
    public void createNewTable(String createTable) {
        mDb.execSQL(createTable);
    }

    /**
     *. 插入方法
     * table : 表名
     * nullColumnHack: 当values参数为空或者里面没有内容的时候,我们insert是会失败的(底层数据库不允许
     *                 插入一个空行),为了防止这种情况,我们要在这里指定一个列名,到时候如果发现将要
     *                 插入的行为空行时,就会将你指定的这个列名的值设为null,然后再向数据库中插入
     * values : 通过HashMap以键值对的方式存储列值
     *  */
    public void insert(String tableName, ContentValues values){
        mDb.insert(tableName, null, values);
    }

    /**
     *. 查询方法
     * 注解部分共学习参考,调用方法前请查看方法参数
     * param number : 8
     * table : 表名
     * columns : 返回哪一列,如果参数是null,则返回所有列(不鼓励设置为null,以免防止读出的数据没有用到)
     * selection : 查询条件子句
     * selectionArgs : 在selection字段中可能会用'?'的形式来加一些额外的参数,这个的selectionArgs字段就是把selection字段的条件填充好
     *                  用于为selection子句中占位符传入参数值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常
     * groupBy : 一个过滤器,如何来分组---设置为null则不分组
     * having : 分组后聚合的过滤条件
     * orderBy : 排序,格式是SQL的ORDER一样.设置null使用默认(无序unonder)排列
     * limit : 返回的行数,设置为null表示没有限制条款//用于进行分页
     * */
    public Cursor queryHaveLimit(String tableName, String[] columns, String selection, String[] selectionArgs,
                          String groupBy, String having, String orderBy, String limit){
        //. 除表名外,其余置空,默认返回全部记录
        Cursor cursor = mDb.query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
        //. 那么就返回前面三条记录
        //Cursor cursor = db.query(tableName, null, null, null, null, null, null, "3");
        //. 返回指定范围内的记录
        //Cursor cursor = db.query(tableName, null, null, null, null, null, null, "2,5");
        //. 返回指定列记录
        //Cursor cursor = db.query(tableName, new String[]{"name,number,desc"}, null, null, null, null, null, null);
        //. 子条件 + 子条件的具体值
        //Cursor cursor = db.query(tableName, null, "_id=?", new String[]{"2"}, null, null, null, null);
        //. 通过列名分组,并且默认从最后一条显示到最前面
        //Cursor cursor = db.query(tableName, null, null, null, "desc", null, null, null);
        //. 分组后,判断以sex分组后的记录数大于3的是哪些记录
        //Cursor cursor = db.query(tableName, null, null, null, "sex", "count(sex)>3", null, null);
        //. 通过某一个列从小到大排序显示出来
        //Cursor cursor = db.query(tableName, null, null, null, null, null, "number", null);
        return cursor;
    }
    /**
     * param(7)
     * 这里少个limit参数,其他与queryHaveLimit一样
     * */
    public Cursor queryNoneLimit(String tableName, String[] columns, String selection, String[] selectionArgs,
                                 String groupBy, String having, String orderBy) {
        Cursor cursor = mDb.query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy);
        return cursor;
    }

    /**
     *. distinct : 指定是否去除重复记录
     * 其他参数与queryHaveLimit一样
     * */
    public Cursor queryHavaDistinctLimit(boolean distinct, String tableName, String[] columns, String selection,
                                     String[] selectionArgs, String groupBy, String having, String orderBy, String limit) {
        Cursor cursor = mDb.query(distinct, tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
        return cursor;
    }

    /**
     *. distinct : 指定是否去除重复记录
     * cancellationSignal : 取消操作信号,或者置空。如果取消了操作,那么执行查询时将抛出OperationCanceledException
     * */
    public Cursor queryDistinctNoneLimit(boolean distinct, String tableName, String[] columns, String selection,
                                         String[] selectionArgs, String groupBy, String having, String orderBy,
                                         String limit, CancellationSignal cancellationSignal) {
        Cursor cursor = null;
        try {
            cursor = mDb.query(distinct, tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit, cancellationSignal);
        }catch (OperationCanceledException e) {
            e.printStackTrace();
        }
        return cursor;
    }

    /**
     *. sql : 查询语句
     * selectionArgs :
     * */
    public Cursor rawQueryNormal(String sql, String[] selecttionArgs) {
        Cursor cursor = mDb.rawQuery(sql, selecttionArgs);
        //. 如下:第二个参数是具体来指定_id值是多少;若没有条件,则第二个参数为空
        //Cursor cursor = db.rawQuery("select * from phone where _id=?;", new String[]{"3"});
        return cursor;
    }

    /**
     *. sql : 查询语句
     * selectionArgs :
     * cancellationSignal :
     * */
    public Cursor rawQueryWithCancellationSignal(String sql, String[] selectionArgs, CancellationSignal cancellationSignal) {
        Cursor cursor = null;
        try {
            cursor = mDb.rawQuery(sql, selectionArgs, cancellationSignal);
        }catch (CancellationException e) {
            e.printStackTrace();
        }
        return cursor;
    }

    /**
     *. 根据唯一标识_id  来删除数据
     * */
    public int delete(String tableName, String whereClause, String[] whereArgs){
        //. 方式一
        //String sql = "delete from phone where _id = 1";
        //int returnValue = db.execSQL(sql);
        return mDb.delete(tableName, whereClause, whereArgs);
    }

    /**
     *. 删除表的所有数据
     * */
    public void deleteAllData(String tableName) {
        //. 方式一
        //String sql = "delete from phone;";
        //db.execSQL(sql);
        //. 方式二
        mDb.delete(tableName, null, null);
    }

    /**
     *. 删除表
     * */
    public void dropTable(String sql) {
        //. String sql = "drop table phone;";
        mDb.execSQL(sql);
    }

    /**
     *. 删除数据库
     * */
    public void deleteDB(String sql) {
        //. 方式1
        //context.deleteDatabase(DB_NAME);
        //. 方式2
        //. String sql = "drop database gm.db;";
        mDb.execSQL(sql);
    }

    /**
     *. 更新数据库的内容
     * table:表名
     * contentValues:键值对数据
     * whereClause:条件字段
     * whereArgs:具体条件字段值
     * */
    public void update(String tableName, ContentValues values, String whereClause, String[]whereArgs){
        //eg: db.update("phone", updateValues, "_id=?", new String[]{"16"});
        mDb.update(tableName, values, whereClause, whereArgs);
    }

}

在Activity中调用如下:

//. 插入
DBUtils dbUtilsAdd = new DBUtils(this);
dbUtilsAdd.openDB();
ContentValues insertValues = new ContentValues();
insertValues.put("name", "person");
insertValues.put("sex", "man");
insertValues.put("number", "120");
insertValues.put("desc", "java编程");
dbUtilsAdd.insert("phone", insertValues);
dbUtilsAdd.closeDB();

//. 查询
DBUtils dbUtilsSelect = new DBUtils(this);
dbUtilsSelect.openDB();
Cursor selectValues = dbUtilsSelect.queryHaveLimit("message", null, null, null, null, null, null, null);
while (selectValues.moveToNext()) {
    //. 用封装类保存读取数据
    Message message = new Message(
            selectValues.getInt(selectValues.getColumnIndex("id")),
            selectValues.getString(selectValues.getColumnIndex("user")),
            selectValues.getString(selectValues.getColumnIndex("mid")),
            selectValues.getString(selectValues.getColumnIndex("title")),
            selectValues.getString(selectValues.getColumnIndex("msg")),
            selectValues.getInt(selectValues.getColumnIndex("state")),
            selectValues.getInt(selectValues.getColumnIndex("type")),
            selectValues.getString(selectValues.getColumnIndex("time")));
    Log.d("输出查询结果:", message.getId()+"="+message.getMid()+"="+message.getUser()+"="+
            message.getTitle()+"="+message.getMsg()+"="+message.getState()+"="+message.getType()+"="+message.getTime());
}
selectValues.close();
dbUtilsSelect.closeDB();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值