Android关于SqList数据库的使用和封装

对于开发者来说肯定都对于数据库不会陌生,今天就来分享一篇关于android的数据库的一些操作和简单封装 ,好,废话不多说,直接上代码(大部分解释都注释在代码中了)

MySQLiteOpenHelper.java

public class MySQLiteOpenHelper extends SQLiteOpenHelper {
    private static MySQLiteOpenHelper helper;
    public static final String DB_NAME = "Topeasy.db";// 数据库名称
    public static final int VERSION = 1;
    /**
     * 支持创建持数据表时判断是否存在,存在则不创建,不存在则创建,相应语句如下:
     * create table if not exists
     * MySQL官方对CREATE TABLE IF NOT EXISTS SELECT给出的解释是:
     * CREATE TABLE IF NOT EXIST… SELECT的行为,先判断表是否存在,
     * 如果存在,语句就相当于执行insert into select;
     * 如果不存在,则相当于create table … select。
     * 解析: 1)integer 表示整型, 2)real 表示浮点型, 3)text 表示文本类型, 4)blob
     * 表示二进制类型。
     * 为了确保数据的完整性和一致性,在创建表时指定字段名称,字段类型和字段属性外,还需要使用约束(constraint),
     * 索引 (index),主键(primary key)和外键(foregin key)等。
     * 约束条件:
     *   not null 非空约束
     *   unique 唯一性约束
     *   primary key 主键约束
     *   foreign key 外键约束
     *   check 检查约束
     *   auto_increment 自动标识列(值会自动增1)
     */
    public static final String CREATE_CUSTOMER = "create table " + TableConfig.TABLE_CUSTOMER + " ("
            + "id integer not null primary key autoincrement,"
            + TableConfig.Customer.CUSTOMER_NAME + " verchar(20),"
            + TableConfig.Customer.DELIVERY_PHONE + " verchar(20),"
            + TableConfig.Customer.ADDR + " verchar(20) ,"
            + TableConfig.Customer.ACCESS_TYPE + " verchar(20),"
            + TableConfig.Customer.CUSTOMER_RATING + " verchar(20), "
            + TableConfig.Customer.LAYERS + " verchar(20),"
            + TableConfig.Customer.CONTACTS + " verchar(20),"
            + TableConfig.Customer.REMARK + " verchar(20))";

    //构造器,传入四个参数Context对象,数据库名字name,操作数据库的Cursor对象,版本号version。
    private MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    //为了简化构造器的使用,我们自定义一个构造器
    private MySQLiteOpenHelper(Context context, String name) {
        this(context, name, null, VERSION);//传入Context和数据库的名称,调用上面那个构造器
    }

    //将自定义的数据库创建类单例。 synchronize单例 防止多线程同时那啥  双重锁定
    public static MySQLiteOpenHelper getInstance(Context context) {
        if (helper == null) {
            synchronized (MySQLiteOpenHelper.class) {
                if (helper == null)
                    helper = new MySQLiteOpenHelper(context, DB_NAME);//数据库名称为create_db。
            }
        }
        return helper;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //在创建数据库时,初始化创建数据库中包含的数据库表。这里以一个“客户”的数据表为例
        /*
         customer   创建 "客户"数据表
         */
        db.execSQL(CREATE_CUSTOMER);// 执行sql语句
    }

    /**
     * 对数据库进行升级,注意: switch 中每一个 case的最后都是没有使用 break ,
     * 这是为了保证在跨版本升级的时候,每一次的数据库修改都能被全部执行到
     *    //当打开数据库时传入的版本号与当前的版本号不同时会调用该方法。
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //switch (oldVersion) {
        //   case 1:
        //        db.execSQL(CREATE_CUSTOMER);
        //       APP.mToast("更新数据库,旧版本是" + oldVersion);
        //   case 2:
        //       db.execSQL(CREATE_CUSTOMER);
        //        APP.mToast("更新数据库,旧版本是" + oldVersion);
        //    default:
        // }
        db.execSQL("drop table if exists "+TableConfig.TABLE_CUSTOMER); // 如果存在表Book,则删除该表
        onCreate(db); // 重新调用onCreate(),创建表
    }

代码中注释已经解释的好清楚了,就不多bb了好吧


DbManager.java

import android.database.sqlite.SQLiteDatabase;

import com.my_movingbricks.app.APP;

/**
 * TP0826   创建数据库类
 * Created by 搬砖小能手 on 2017/4/6.
 * E-mail:[email protected].
 * Signature:当你的才华满足不了你的野心的时候,那么你应该静下心来学习.
 * Alert:语言的巨人,行动的矮子!
 */
public class DbManager {
    private static DbManager manager;
    private MySQLiteOpenHelper mySQLiteOpenHelper;
    private SQLiteDatabase db;

    /**
     * 私有化构造器
     *
     */
    private DbManager() {
        //创建数据库
        mySQLiteOpenHelper = MySQLiteOpenHelper.getInstance(APP.getInstance());
        if (db == null) {
            db = mySQLiteOpenHelper.getWritableDatabase();
        }
    }

    /**
     * 单例DbManager类
     *
     * @return 返回DbManager对象
     */
    public static DbManager newInstances() {
        if (manager == null) {
            synchronized (DbManager.class) {
                if (manager == null) {
                    manager = new DbManager();
                }
            }
        }
        return manager;
    }

    /**
     * 获取数据库的对象
     *
     * @return 返回SQLiteDatabase数据库的对象
     */
    public SQLiteDatabase getDataBase() {
        return db;
    }

    /**
     * 关闭数据库
     */
    public void close() {
        mySQLiteOpenHelper.close();
        mySQLiteOpenHelper = null;
        db.close();
        db = null;
        manager = null;
    }

}

初始化数据库,关闭等等。。


ChannelDaoInface.java


import java.util.ArrayList;

public interface ChannelDaoInface<T> {
    /**
     * 插入一条数据
     *
     * @param item 传进来的item
     * @return 是否插入成功
     */
    public boolean addCache(String tableName, T item);

    /**
     * 删除一条数据
     *
     * @param tableName   删除数据库的表名
     * @param whereClause "url=?"; 删除的字段名
     * @param whereArgs   {name} 删除的字段的值
     * @return
     */
    public boolean deleteCache(String tableName, String whereClause, String whereArgs);

    /**
     * 更新
     *
     * @param tableName   更改数据的数据表
     * @param columnName  "url=?" 更改的数据的字段名
     * @param columnValue {name}; 更改的数据的字段值
     * @param object      更改的数据
     * @return
     */
    public boolean updateCache(String tableName, String columnName, String columnValue, Object object);

    /**
     *
     * @param tableName  查询的数据库的名字
     * @param entityType 查询的数据库所对应的module
     * @param fieldName  查询的字段名
     * @param value      查询的字段值
     * @return
     */
    public <T> ArrayList<T> queryCache(String tableName, Class<T> entityType, String fieldName, String value);

    public void clearFeedTable();
}

一些数据库操作


ChannelDao.java

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.my_movingbricks.dbinit.db.DbManager;
import com.my_movingbricks.dbinit.db.MySQLiteOpenHelper;
import com.my_movingbricks.dbinit.dbinterface.ChannelDaoInface;

import java.lang.reflect.Field;
import java.util.ArrayList;

/**
 * TP0826 操作数据库的封装类
 * Created by 搬砖小能手 on 2017/4/6.
 * E-mail:40492459@qq.com.
 * Signature:当你的才华满足不了你的野心的时候,那么你应该静下心来学习.
 * Alert:语言的巨人,行动的矮子!
 */
public class ChannelDao<T> implements ChannelDaoInface<T> {
    private DbManager manager;
    private SQLiteDatabase db;

    public ChannelDao() {
        //创建数据库
        manager = DbManager.newInstances();
        db = manager.getDataBase();
    }

    /**
     * 向数据库插入数据
     *
     * @param tableName 数据库插入数据的数据表
     * @param item    数据库插入的对象
     */
    @Override
    public boolean addCache(String tableName, T item) {
        boolean flag = false;
        long id = 0;
        Class clazz = item.getClass();
        Field[] fields = clazz.getDeclaredFields();//获取该类所有的属性
        ContentValues value = new ContentValues();
        for (Field field : fields) {
            try {
                field.setAccessible(true); //取消对age属性的修饰符的检查访问,以便为属性赋值
                String content = (String) field.get(item);//获取该属性的内容
                value.put(field.getName(), content);
                field.setAccessible(false);//恢复对age属性的修饰符的检查访问
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        id = db.insert(tableName, null, value);
        flag = (id != -1 ? true : false);
        return flag;
    }

    /**
     * 删除数据
     *
     * @param tableName 删除数据库的表名
     * @param whereClause 删除的字段名
     * @param whereArgs     删除的字段的值
     */
    @Override
    public boolean deleteCache(String tableName, String whereClause, String whereArgs) {
        boolean flag = false;
        int count = 0;
        count =db.delete(tableName, whereClause + "=?", new String[]{whereArgs});
        flag = (count > 0 ? true : false);
        return flag;
    }

    /**
     * 更改数据库内容
     *
     * @param tableName   更改数据的数据表
     * @param columnName  更改的数据的字段名
     * @param columnValue 更改的数据的字段值
     * @param object      更改的数据
     */
    @Override
    public boolean updateCache(String tableName, String columnName, String columnValue, Object object) {
        boolean flag = false;
        int count = 0;
        try {
            Class clazz = object.getClass();
            Field[] fields = clazz.getDeclaredFields();//获取该类所有的属性
            ContentValues value = new ContentValues();
            for (Field field : fields) {
                field.setAccessible(true); //取消对age属性的修饰符的检查访问,以便为属性赋值
                String content = (String) field.get(object);//获取该属性的内容
                value.put(field.getName(), content);
                field.setAccessible(false);//恢复对age属性的修饰符的检查访问
            }
            count=db.update(tableName, value, columnName + "=?", new String[]{columnValue});
            flag = (count > 0 ? true : false);
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        }
        return flag;
    }
    /**
     *
     * @param tableName  查询的数据库的名字
     * @param entityType 查询的数据库所对应的module
     * @param fieldName  查询的字段名
     * @param value      查询的字段值
     * @param <T>        泛型代表AttendInformation,Customer,Order,User,WorkDaily类
     * @return 返回查询结果,结果为AttendInformation,Customer,Order,User,WorkDaily对象
     */
    @Override
    public <T> ArrayList<T> queryCache(String tableName, Class<T> entityType, String fieldName, String value) {

        ArrayList<T> list = new ArrayList();
        Cursor cursor = db.query(tableName, null, fieldName + " like ?", new String[]{value}, null, null, " id desc", null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {//返回游标是否指向第最后一行的位置
            try {
                T t = entityType.newInstance();
                for (int i = 0; i < cursor.getColumnCount(); i++) {
                    String columnName = cursor.getColumnName(i);// 获取数据记录第i条字段名的
                    String content = cursor.getString(i);//获得获取的数据记录第i条字段的内容
                    Field field = entityType.getDeclaredField(columnName);//获取该字段名的Field对象。
                    field.setAccessible(true);//取消对age属性的修饰符的检查访问,以便为属性赋值
                    field.set(t, content);
                    field.setAccessible(false);//恢复对age属性的修饰符的检查访问
                }
                list.add(t);
                cursor.moveToNext();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    /**
     * 删除表中的数据
     */
    @Override
    public void clearFeedTable() {
        String sql = "DELETE FROM " + MySQLiteOpenHelper.CREATE_CUSTOMER + ";";
        db.execSQL(sql);
        revertSeq();
    }


    /**
     * 以SQLHelper.TABLE_CHANNEL表作为条件,新建表sqlite_sequence,当name=表名的时候
     * 更新seq=0;
     */
    private void revertSeq() {
        String sql = "update sqlite_sequence set seq=0 where name='"
                + MySQLiteOpenHelper.CREATE_CUSTOMER + "'";
        db.execSQL(sql);
    }


    //关闭数据库
    private void OnCliar(ContentValues value) {
        value.clear();
    }
}

操作的实现


TableOperate.java


import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.my_movingbricks.dbinit.db.DbManager;

/**
 * abc
 * Created by 搬砖小能手 on 27/10/2017.
 * E-mail:[email protected].
 * Signature:当你的才华满足不了你的野心的时候,那么你应该静下心来学习.
 * Alert:语言的巨人,行动的矮子!
 */
public class TableOperate {
    private DbManager manager;
    private SQLiteDatabase db;

    public TableOperate() {
        //创建数据库
        manager = DbManager.newInstances();
        db = manager.getDataBase();
    }

    /**
     * 添加数据
     */
    public void insertData(String tableName, ContentValues values) {
        db.insert(tableName, null, values);// 插入一条数据
    }

    public ContentValues initContentValues(String[] key, String[] values) {
        if (key.length != values.length) return null;
        ContentValues cv = new ContentValues();
        for (int i = 0; i < key.length; i++) {
            cv.put(key[i], values[i]);
        }
        return cv;
    }

    public void insertData(String tableName, String[] key, String[] values) {
        db.insert(tableName, null, initContentValues(key, values));// 插入一条数据
    }

    /**
     * 更新数据
     *
     * @param values
     * @param whereClause "url=?"
     * @param whereArgs   {name};
     */
    public void updateData(String tableName, ContentValues values, String whereClause, String[] whereArgs) {
        db.update(tableName, values, whereClause,
                whereArgs);
    }

    public void updateData(String tableName, String[] key, String[] values, String whereClause, String[] whereArgs) {
        db.update(tableName, initContentValues(key, values), whereClause, whereArgs);
    }

    /**
     * 删除数据
     *
     * @param whereClause "url=?"
     * @param whereArgs   {name};
     */
    public void deleteData(String tableName, String whereClause, String[] whereArgs) {
        db.delete(tableName, whereClause, whereArgs);
    }

    /**
     * 查询数据
     *
     * @param tableName     表名,不能为null
     * @param columns       要查询的列名,可以是多个,可以为null,表示查询所有列
     * @param selection     查询条件,比如id=? and name=? 可以为null
     * @param selectionArgs 对查询条件赋值,一个问号对应一个值,按顺序 可以为null
     * @param groupBy
     * @param having        语法have,可以为null
     * @param orderBy       语法,按xx排序,可以为null
     * @return
     */

    public Cursor selectData(String tableName, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
        Cursor cursor = db.query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy);
        return cursor;
    }

    public void selectData(Cursor cursor, String... key) {
        if (cursor.moveToFirst()) { // 返回假时 那就为空   移动光标到第一行
            do {
                for (int i = 0; i < key.length; i++) {
                    String name=cursor.getString(cursor.getColumnIndex(key[i]));
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
    }
    /**
     if (cursor.moveToFirst()) {// 返回假时 那就为空   移动光标到第一行
     do {
     // 遍历cursor对象,取出数据 对比搜索到的数据,如果有则为已收藏收藏
     String url = cursor.getString(cursor.getColumnIndex("url"));
     String theme = cursor.getString(cursor.getColumnIndex("theme"));
     String content = cursor.getString(cursor
     .getColumnIndex("content"));
     }
     } while (cursor.moveToNext());
     */
}

另一个实现类,以便满足多种需求

好了 就这么愉快的分享完了,总体来说比较简单,当然大家可以去使用目前比较成熟的框架greenDAO或者是xutlis的db模块,也是比较通俗易懂的,这里就不做介绍了哈, 如果文章有错误希望小伙伴们告知一下哈 。

文章末尾附上设计的几个类的下载地址:点击传送

这里写图片描述

发布了11 篇原创文章 · 获赞 24 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/feng40492459/article/details/78362416