前言

对于Android开发开说数据库应该很熟悉了,但是要从实际操作的角度来说,可能未必能够熟练的使用。当然,不是所有的APP都需要使用数据库,因为这个东西确实比较重。但是如果碰到一些特别大的项目尤其是包含即时通讯,消息,频繁的大数据的存储和操作,基本上都会使用数据库,比如:银行类APP,聊天类APP,大型官网的APP。此类型的项目中需要对数据库进行统一封装:数据库的创建,表格创建,数据库的增,删,改,查,以及更新数据库等操作。话不多说,直接从代码的角度去从头开始撸起来!

 

一、数据库的创建:

1.创建数据库需要借助SQLiteOpenHelper,代码如下:

 

public class MySqliteOpenHelper extends SQLiteOpenHelper {
    private String mName="";//数据库名字创建数据库表的语句,一般写在会放在对应的数据库中(StudentDao)
public static final String TBL_FRIEND_CREATE_SQL =
        "CREATE TABLE IF NOT EXISTS " + STUDENT_TABLE + " (" +
                STUDENT_ID + " INT64 PRIMARY KEY," +
                STUDENT_NAME + " TEXT," +
                STUDENT_CHINESE + " TEXT," +
                STUDENT_MATH + " TEXT," +
                STUDENT_ENGLISH + " TEXT," +
                STUDENT_AGE + " TEXT" + ");";public static final String[] INIT_ALL_TABLE={
            UserDao.TBL_USERDAO_CREATE_SQL,
            FriendDao.TBL_FRIEND_CREATE_SQL,
            StudentDao.TBL_FRIEND_CREATE_SQL
    };


    public MySqliteOpenHelper(@Nullable Context context, @Nullable String name, int version) {
        super(context, name, null, version);
        mName=name;
    }


/**
  *在当第一次执行数据库操作的时候会通过SqliteOpenHelper去创建数据库,对应的走onCreate方法。
  *如果需要新增一个表格,需要将创建表格的语句在onCreate方法里面去执行,如下所示。这个for循环会将需要的表一次性全部创建完毕
/
    @Override
    public void onCreate(SQLiteDatabase db) {
        if (INIT_ALL_TABLE!=null&&INIT_ALL_TABLE.length>0)
        for (int i = 0; i <INIT_ALL_TABLE.length ; i++) {
            db.execSQL(INIT_ALL_TABLE[i]);
        }
    }

/*
*这个方法是当数据库中的某个表格需要升级的时候(比如,新增一些字段)
*此时需要将数据库的版本号增加一个,通过获取本地数据库的oldVersion和APP中的数据库版本号进行比较
*如果小于当前的版本号,则会走对应的方法,对应的去执行一些语句,插入一些新的字段。如下:
*/
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (oldVersion==newVersion){
            return;
        }

        if (oldVersion<4){
            //数据库升级版本为4,此时有表格结构变动,需要更新对应的表格
            updateDbVersion4(db);
        }
        if (oldVersion<5){
            //数据库升级版本为5,此时有表格结构变动,需要更新对应的表格
            updateDbVersion5(db);
        }private void updateDbVersion4(SQLiteDatabase db) {
    ArrayList<String> list = updateDbVersionSqlArray4(db);
    db.beginTransaction();
    if (list!=null&&list.size()>0){
        for (int i = 0; i < list.size(); i++) {
            String sql = list.get(i);
            db.execSQL(sql);
        }
    }
    db.setTransactionSuccessful();
    db.endTransaction();
}


/**
 * 数据库版本4.0,user_info_table  表格新增字段 student_chinese 和  student_math
 */
private ArrayList<String> updateDbVersionSqlArray4(SQLiteDatabase db) {
    ArrayList<String> sqlList = new ArrayList<>();
    try {
        Cursor cursor = db.query(String.valueOf("sqlite_master"), null, null, null, null, null, null);
        try {
            while (cursor.moveToNext()) {
                if ("table".equals(cursor.getString(cursor.getColumnIndex("type")))) {
                    String tableName = cursor.getString(cursor.getColumnIndex(String.valueOf("name")));
                    if (tableName.equals(StudentDao.STUDENT_TABLE)) {
                        if (!checkColumnExists(db,StudentDao.STUDENT_TABLE,StudentDao.STUDENT_CHINESE)) {
                            String str1 = "ALTER TABLE " + tableName + " ADD COLUMN " + "student_chinese" + " TEXT;";
                            sqlList.add(str1);
                        }
                        if (!checkColumnExists(db,StudentDao.STUDENT_TABLE,StudentDao.STUDENT_MATH)) {
                            String str2 = "ALTER TABLE " + tableName + " ADD COLUMN " + "student_math" + " TEXT;";
                            sqlList.add(str2);
                        }

                    }
                }
            }
        } finally {
            cursor.close();
        }

    } catch (Exception e) {
        return new ArrayList<String>();
    }
    return sqlList;
}
    }
2.SqliteOpenHelper辅助类写好之后,需要使用ContentProvider来创建数据库。
此类是用来存储数据库信息配置的类:

public class DBConstants {
 /**
 * 数据库的名字,LK+“用户的账号”+DB 拼接成的,如果切换账号则会生成新的数据库。不同的账号之间的数据绝对隔离,故称之为私库。
 */
    public static final String DB_NAME = "LK%sDB.db";
    /**
     * 数据库升级为版本4  StudentDao新增语文Chinese 数学Math字段
     */
    public static final int DB_VERSION=4;


}/**
 * 1.核心:此类继承ContentProvider,在此类中进行数据库的创建,以及实现数据库的  增,删,改,查,替换,批量操作。
 * 2.此处实现的数据库表格的 增,删,改,查,批量操作等方法并非直接使用。而是通过contentRelsover去操作,
 *   内部会进一步的调用此类中对应的方法。
 * 3."com.example.mydbproject.liukang"是MyContentProvider唯一标识(这个类对应的唯一数据库),不允许重复,并且需要注册才能使用。
 * <provider
 *             android:authorities="com.example.mydbproject.liukang"
 *             android:name=".help.MyContentProvider"
 *             android:enabled="true"
 *             android:exported="false"/>
 *
 */
public class MyContentProvider extends ContentProvider {

    public static final String AUTHORITY = "content://com.example.mydbproject.liukang/";
    public static final String AUTHORITY_APPLY = "com.example.mydbproject.liukang";//这个是唯一标识,注册的时候需要使用
    public static final String URI_RAWQUERY = "content://com.example.mydbproject.liukang/defined/action/rawQuery";
    public static final String URI_EXECSQL = "content://com.example.mydbproject.liukang/defined/action/execSql";

    Object mLock = new Object();
    MySqliteOpenHelper mySqliteOpenHelper;
    String mUserId = "";

    @Override
    public boolean onCreate() {
        return initHelper();
    }

    private boolean initHelper() {
        synchronized (mLock) {
            if (mySqliteOpenHelper != null) {
                mySqliteOpenHelper.close();
            }
            mUserId = getUserId();
            String name = String.format(DBConstants.DB_NAME, mUserId);
            mySqliteOpenHelper = new MySqliteOpenHelper(getContext(),
                    name,
                    DBConstants.DB_VERSION);
            return true;
        }

    }

    public SQLiteDatabase getWritableDatabase() {
        if (mySqliteOpenHelper != null) {
            if (!mUserId.equals(getUserId())) {
                initHelper();
            }
            SQLiteDatabase writableDatabase = mySqliteOpenHelper.getWritableDatabase();
            return writableDatabase;
        }
        return null;
    }

    /**
     * 查询操作
     * @param uri  1:URI_RAWQUERY则直接用db执行查询的sql语句 (sql语句已经包含了条件)
     *             2:AUTHORITY+“table_name”此时直接根据条件查询
     * @param projection
     * @param selection
     * @param selectionArgs
     * @param sortOrder
     * @return
     */
    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        String tableName = getTableName(uri);
        SQLiteDatabase db = getWritableDatabase();
        if (db == null) {
            return null;
        }
        if (uri.equals(Uri.parse(URI_RAWQUERY))) {
            //URI_RAWQUERY则直接用db执行查询的sql语句
            Cursor cursor = db.rawQuery(selection, selectionArgs);
            return cursor;
        }
        if (TextUtils.isEmpty(tableName)) {
            return null;
        }
        //直接根据条件查询
        Cursor cursor = db.query(tableName, projection, selection, selectionArgs, null, null, sortOrder, null);
        return cursor;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    /**
     * 插入新数据操作
     * @param uri
     * @param values
     * @return
     */
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        String tableName = getTableName(uri);
        SQLiteDatabase db = getWritableDatabase();
        if (db == null || TextUtils.isEmpty(tableName)) {
            return null;
        }
        long insertId = db.insert(tableName, null, values);
        if (insertId == -1) {
            //失败
            Log.e("TAGS", tableName + ":" + "insert:" + insertId);
            return null;
        }
        //成功是一个大于0的数===size    失败是-1
        Log.e("TAGS", tableName + ":" + "insert:" + insertId);
        return ContentUris.withAppendedId(uri, insertId);
    }

    /**
     * 删除一条新数据     1:如果uri为  MyContentProvider.URI_EXECSQL则执行sql语句即可(可以是增,删,改)
     *                   2:如果不是则根据表格以及条件进行某条数据的删除
     * @param uri
     * @param selection
     * @param selectionArgs
     * @return
     */
    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        SQLiteDatabase db = getWritableDatabase();
        if (db == null) {
            return 0;
        }
        if (uri.equals(Uri.parse(MyContentProvider.URI_EXECSQL))) {
            db.execSQL(selection);
            return 1;
        } else {
            String tableName = getTableName(uri);
            if (TextUtils.isEmpty(tableName)) {
                return 0;
            }
            int delete = db.delete(tableName, selection, selectionArgs);
            //失败是0    成功是1
            Log.e("TAGS", tableName + ":" + "delete:" + delete);
            return delete;
        }
    }

    /**
     * 更新操作:   1.如果uri是包含replace,对应的操作是  存在则更新,不存在则新增
     *             2.如果不包含replace,则执行更新操作
     * @param uri
     * @param values
     * @param selection
     * @param selectionArgs
     * @return
     */
    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        String tableName = getTableName(uri);
        SQLiteDatabase db = getWritableDatabase();
        if (db == null || TextUtils.isEmpty(tableName)) {
            return 0;
        }
        //成功是1  失败是0
        int update = db.update(tableName, values, selection, selectionArgs);
        if (update == 0) {
            if (getReplace(uri)) {
                long insertId = db.insert(tableName, null, values);
                Log.e("TAGS", tableName + ":" + "update:__insert:" + insertId);
                return 1;
            } else {
                return 0;
            }
        }
        Log.e("TAGS", tableName + ":" + "update:" + update);
        return update;
    }

    /**
     * 获取当前账号的唯一标识,userId。
     * @return
     */
    public String getUserId() {
        String user_id = AccountManager.getAccountId(getContext());
        return user_id;
    }

    /**
     * 根据uri操作表示来获取表格名称
     *MyContentProvider.AUTHORITY+ “student_table”
     * MyContentProvider.AUTHORITY+  “place/student_table”  替换操作
     * @param uri
     * @return
     */
    public String getTableName(Uri uri) {
        List<String> pathSegments = uri.getPathSegments();
        if (pathSegments != null && pathSegments.size() == 1) {
            return pathSegments.get(0);
        } else if (pathSegments != null && pathSegments.size() == 2) {
            return pathSegments.get(1);
        } else {
            return "";
        }
    }

    /**
     * 判断是不是替换的操作
     * @param uri
     * @return
     */
    public boolean getReplace(Uri uri) {
        List<String> pathSegments = uri.getPathSegments();
        if (pathSegments != null && pathSegments.size() == 2) {
            String placeStr = pathSegments.get(0);
            if (!TextUtils.isEmpty(placeStr) && placeStr.equals("place")) {
                return true;
            }
            return false;
        } else {
            return false;
        }
    }

    /**
     * 批量操作
     * 如果一次性插入或者查询多条数据可以使用此方法,性能好
     * @param operations
     * @return
     * @throws OperationApplicationException
     */
    @NonNull
    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
            throws OperationApplicationException {
        SQLiteDatabase db = getWritableDatabase();
        if (db == null) {
            return null;
        }
        ContentProviderResult[] results = new ContentProviderResult[operations.size()];
        db.beginTransaction();
        try {
            results = super.applyBatch(operations);
            db.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace(); //NOSONAR
            results = null;
        } finally {
            db.endTransaction();
        }
        return results;
    }
}

二.创建数据表:

1.的基类操作方法

/**
 * 所有数据库表格的基类,
 * 1:通过ContentValues,进行增,删,改,查
 * 2:通过sql语句进行增,删,改,查
 * 3.当新增某个数据库操作可以继承该类。如果需要执行某个操作,只需要对应的调用对应方法并传入相关参数即可。
 * (可参考StudentDao)
 */
public abstract class BaseDao {


    /**
     * 单个插入一条数据
     * @param tableName  表名称
     * @param contentValues 将插入的数据封装为ContentValues进行插入(key,value)
     */
    public void insertValue(String tableName, ContentValues contentValues) {
        MyApplication.getContext().getContentResolver().insert(getUri(tableName), contentValues);
    }



    /**
     * 删除单个数据
     * @param tableName  表名称
     * @param selection  查找的条件字段
     * @param selectionArgs  字段条件字段对应的值
     */
    public void deleteValue(String tableName, String selection, String[] selectionArgs) {
        MyApplication.getContext().getContentResolver().delete(getUri(tableName), selection, selectionArgs);
    }

    /**
     * 更新一条数据
     * @param tableName   表名称
     * @param values  插入的ContentValues
     * @param selection  查找的条件字段
     *  @param selectionArgs  字段条件字段对应的值
     */
    public void updateValue(String tableName, ContentValues values, String selection, String[] selectionArgs) {
        MyApplication.getContext().getContentResolver().update(getUri(tableName), values, selection, selectionArgs);
    }

    /**
     * 查询数据
     * @param tableName  表名称
     * @param cloum  想要查询的哪个字段    null则是所有
     * @param selection  查找的条件字段
     *  @param selectionArgs  字段条件字段对应的值
     * @param sortOrder   排序
     */
    public Cursor queryValue(String tableName, String[] cloum, String selection, String[] selectionArgs, String sortOrder) {
        return MyApplication.getContext().getContentResolver().query(getUri(tableName), cloum,selection,selectionArgs,sortOrder);
    }

    /**
     * 替换一条数据(有则更新,无则插入)使用的是这个Uri:getReplaceUri(tableName)
     * getContentResolver().update() ==> MyContentProvider.update() 根据Uri区分:update or replace
     * @param tableName
     * @param values
     * @param selection
     * @param selectionArgs
     */
    public void replaceValue(String tableName, ContentValues values, String selection, String[] selectionArgs) {
        MyApplication.getContext().getContentResolver().update(getReplaceUri(tableName), values, selection, selectionArgs);
    }


    /**
     * 批量操作数据(增,删,改)
     * @param authority
     * @param operations:此集合中包含ContentProviderOperation类
     *         ContentProviderOperation可以理解为封装的sql语句
     *         一个集合里面可以是(增 删 改)共同组成的集合
     * @return
     */
    public ContentProviderResult[] applyBatch(String authority, ArrayList<ContentProviderOperation> operations) {
        try {
            return  MyApplication.getContext().getContentResolver().applyBatch(authority, operations);
        } catch (Exception e) {
            e.printStackTrace(); //NOSONAR
        }
        return null;
    }


    /**
     * 直接sql语句执行查询  注意Uri是这个哦:getRawQueryUri()
     * getContentResolver().query()===>对应的MyContentProvider.query()
     * ==>对应的MyContentProvider会根据Uri区分是直接执行sql语句,还是使用传过来的条件
     * @param sql
     * @param selectionArgs
     * @return
     */
    public Cursor querySql(String sql,String[] selectionArgs){
        return MyApplication.getContext().getContentResolver().query(getRawQueryUri(),null,sql,selectionArgs,null);
    }

    /**
     * 直接执行sql语句进行 增 删 改操作 ( 注意使用的是uri:getExecSqlUri())
     * getContentResolver().delete()===>对应的MyContentProvider.delete()
     *      * ==>对应的MyContentProvider会根据Uri区分是直接执行sql语句(增 删 改)
     *      ,还是使用传过来的条件进行删除操作
     * @param sql
     */
    public void execSql(String sql){
        MyApplication.getContext().getContentResolver().delete(getExecSqlUri(),sql,null);
    }


    /**
     * AUTHORITY+表名称,MyContentProvider会使用传过来的条件进行 增 删 改 查 操作
     * @param tableName
     * @return
     */
    public Uri getUri(String tableName) {
        return Uri.parse(MyContentProvider.AUTHORITY + tableName);
    }

    /**
     *含有replace: MyContentProvider会使用传过来的条件进行替换操作(无则插入,有则替换)
     * @param tableName
     * @return
     */
    public Uri getReplaceUri(String tableName) {
        return Uri.parse(MyContentProvider.AUTHORITY +"replace/"+ tableName);
    }

    /**
     * 获取getRawQueryUri():直接执行sql查询的Uri表示
     * @return
     */
    public Uri getRawQueryUri(){
        return Uri.parse(MyContentProvider.URI_RAWQUERY);
    }

    /**
     * getExecSqlUri():直接执行sql语句的表示:增 删 改
     * @return
     */
    public Uri getExecSqlUri(){
        return Uri.parse(MyContentProvider.URI_EXECSQL);
    }

}
2.举个例子:学生表:StudentDao   主键为:student_id(唯一)
/**
 * 增删改查替换,只要对应的调用方法即可
 * sql:如果是直接执行相关的sql语句则需要对一些表达式有所了解才行
 * newInsertMessageOperation:批量插入,删除,替换返回的ContentProviderOperation,实际上就
 * 是对增 删 改 替的语句的封装,然后组成集合,调用applyBatch()方法开启数据库事务进行遍历操作
 * 进一步的实际上还是调用 增 删 改
 */
public class StudentDao extends BaseDao {

    StudentBean studentBean = null;
    private static StudentDao mInstance;
    public static String STUDENT_TABLE = "student_table";
    public static String STUDENT_ID = "student_id";
    public static String STUDENT_NAME = "student_name";
    public static String STUDENT_AGE = "student_age";
    public static String STUDENT_CHINESE = "student_chinese";
    public static String STUDENT_MATH = "student_math";
    public static String STUDENT_ENGLISH = "student_english";
    public static final String TBL_FRIEND_CREATE_SQL =
            "CREATE TABLE IF NOT EXISTS " + STUDENT_TABLE + " (" +
                    STUDENT_ID + " INT64 PRIMARY KEY," +
                    STUDENT_NAME + " TEXT," +
                    STUDENT_CHINESE + " TEXT," +
                    STUDENT_MATH + " TEXT," +
                    STUDENT_ENGLISH + " TEXT," +
                    STUDENT_AGE + " TEXT" + ");";


    public static StudentDao getInstance() {
        if (mInstance == null) {
            mInstance = new StudentDao();
        }
        return mInstance;
    }

    /**
     * 插入一条数据
     */
    public void insert(StudentBean student) {
        ContentValues contentValues = getContentValues(student);
        super.insertValue(STUDENT_TABLE, contentValues);
    }

    /**
     * 删除一条数据
     */
    public void delete(String studentId) {
        if (TextUtils.isEmpty(studentId)) {
            return;
        }
        String selection = STUDENT_ID + " = ?";
        super.deleteValue(STUDENT_TABLE, selection, new String[]{studentId});
    }

    /**
     * 删除一条数据
     */
    public void deleteAll() {
        super.deleteValue(STUDENT_TABLE, null, null);
    }


    /**
     * 更新一条数据
     */
    public void update(StudentBean studentBean) {
        ContentValues contentValues = getContentValues(studentBean);
        String selection = STUDENT_ID + " = ?";
        super.updateValue(STUDENT_TABLE, contentValues, selection, new String[]{String.valueOf(studentBean.getStudentId())});
    }


    /**
     * 根据studentId查询单条数据
     *
     * @param studentId
     * @return
     */
    public StudentBean queryItem(String studentId) {
        String selection = STUDENT_ID + " = ?";
        Cursor cursor = super.queryValue(STUDENT_TABLE, null, selection, new String[]{studentId}, null);
        try {
            while (cursor != null && cursor.moveToNext()) {
                StudentBean studentBean = initStudentBean(cursor);
                return studentBean;
            }
            return null;
        } catch (Exception e) {
            return null;
        } finally {
            cursor.close();
        }
    }

    /**
     * 更新一条数据
     */
    public void replace(StudentBean studentBean) {
        ContentValues contentValues = getContentValues(studentBean);
        String selection = STUDENT_ID + " = ?";
        super.replaceValue(STUDENT_TABLE, contentValues, selection, new String[]{String.valueOf(studentBean.getStudentId())});
    }


    /**
     * 根据表中所有的学生信息
     *
     * @param
     * @return
     */
    public List<StudentBean> queryAll() {
        List<StudentBean> list = new ArrayList<>();
        Cursor cursor = super.queryValue(STUDENT_TABLE, null, null, null, null);
        try {
            while (cursor != null && cursor.moveToNext()) {
                StudentBean studentBean = initStudentBean(cursor);
                list.add(studentBean);
            }
            return list;
        } catch (Exception e) {
            return null;
        } finally {
            cursor.close();
        }
    }

    /**
     * 统一修改,对于英语成绩超过95分的学生,语文成绩和数学分别扣除1分
     */
    public void updateStudentChinese() {
        String sql = " update " + STUDENT_TABLE + " set student_chinese = student_chinese -1 , student_math = student_math -1 where " + STUDENT_ENGLISH + " >=95";
        super.execSql(sql);
    }


    /**
     * 查询
     * 英语成绩由高到低,查询所有的数据
     * limit 3:查询前三条数据
     * limit 2,10   查询从index=2(第三条数据开始的算起,共10条数据:【3,12】)
     */
    public List<StudentBean> querySql1() {
        String querySql = "select * from " + STUDENT_TABLE + "  order by student_english desc limit 3";
        Cursor cursor = super.querySql(querySql, null);
        List<StudentBean> list = new ArrayList<>();
        try {
            while (cursor != null && cursor.moveToNext()) {
                StudentBean studentBean = initStudentBean(cursor);
                list.add(studentBean);
            }
            return list;
        } catch (Exception e) {
            return null;
        } finally {
            cursor.close();
        }
    }


    /**
     * 插入语句
     * 创建ContentProviderOperation对象
     */
    public ContentProviderOperation newInsertMessageOperation(StudentBean studentBean) {
        ContentValues contentValues = getContentValues(studentBean);
        ContentProviderOperation operation = ContentProviderOperation.newInsert(getUri(STUDENT_TABLE))
                .withValues(contentValues)
                .build();
        return operation;
    }

    /**
     * 删除语句
     * 创建ContentProviderOperation对象
     */
    public ContentProviderOperation newDeleteMessageOperation(String studentId) {
        String selection = STUDENT_ID + " = ?";
        String[] selectionValue = new String[]{studentId};
        ContentProviderOperation operation = ContentProviderOperation.newDelete(getUri(STUDENT_TABLE))
                .withSelection(selection, selectionValue)
                .build();
        return operation;
    }

    /**
     * 更新语句
     * 创建ContentProviderOperation对象
     */
    public ContentProviderOperation newUpdateMessageOperation(String studentId, StudentBean studentBean) {
        String selection = STUDENT_ID + " = ?";
        String[] selectionValue = new String[]{studentId};
        ContentValues contentValues = getContentValues(studentBean);
        ContentProviderOperation operation = ContentProviderOperation.newUpdate(getUri(STUDENT_TABLE))
                .withSelection(selection, selectionValue)
                .withValues(contentValues)
                .build();
        return operation;
    }

    /**
     * 替换语句
     * 创建ContentProviderOperation对象
     */
    public ContentProviderOperation newReplaceMessageOperation(String studentId, StudentBean studentBean) {
        String selection = STUDENT_ID + " = ?";
        String[] selectionValue = new String[]{studentId};
        ContentValues contentValues = getContentValues(studentBean);
        ContentProviderOperation operation = ContentProviderOperation.newUpdate(getReplaceUri(STUDENT_TABLE))
                .withSelection(selection, selectionValue)
                .withValues(contentValues)
                .build();
        return operation;
    }


    private StudentBean initStudentBean(Cursor cursor) {
        studentBean = new StudentBean();
        studentBean.setStudentId(cursor.getInt(cursor.getColumnIndex(STUDENT_ID)));
        studentBean.setName(cursor.getString(cursor.getColumnIndex(STUDENT_NAME)));
        studentBean.setAge(cursor.getString(cursor.getColumnIndex(STUDENT_AGE)));
        studentBean.setChinese(cursor.getString(cursor.getColumnIndex(STUDENT_CHINESE)));
        studentBean.setMath(cursor.getString(cursor.getColumnIndex(STUDENT_MATH)));
        studentBean.setEnglish(cursor.getString(cursor.getColumnIndex(STUDENT_ENGLISH)));
        return studentBean;
    }


    public ContentValues getContentValues(StudentBean student) {
        if (student == null) {
            return null;
        }
        ContentValues contentValues = new ContentValues();
        contentValues.put(STUDENT_ID, student.getStudentId());
        contentValues.put(STUDENT_NAME, student.getName());
        contentValues.put(STUDENT_AGE, student.getAge());
        contentValues.put(STUDENT_CHINESE, student.getChinese());
        contentValues.put(STUDENT_MATH, student.getMath());
        contentValues.put(STUDENT_ENGLISH, student.getEnglish());
        return contentValues;
    }


}

三:Demo使用StudentDao

1.模拟登录账号,主要是创建数据库用到userId

Android 使用数据库 android 数据库管理_Android 使用数据库

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:text="登录,请输入账号密码"
        android:background="#E0EBF0"
        android:textSize="30sp"
        />
    <EditText
        android:id="@+id/user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:background="#EBCCD6"
        android:layout_marginTop="100dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:textSize="20sp"
        android:inputType="number"
        android:hint="请输入账号"
        />
    <EditText
        android:layout_marginTop="30dp"
        android:id="@+id/user_psw"
        android:layout_width="match_parent"
        android:layout_margin="20dp"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:textSize="20sp"
        android:background="#EBCCD6"
        android:hint="请输入密码"
        />
    <TextView
        android:id="@+id/bt_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="登录"
        android:background="#C2F8C4"
        android:gravity="center"
        android:layout_marginTop="20dp"
        android:textSize="22sp"
        />

</LinearLayout>

对应的java:

public class MainActivity extends AppCompatActivity {

    private EditText et_userName;
    private EditText et_userPsw;
    private TextView tv_login;
    Activity activity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity = this;
        et_userName = findViewById(R.id.user_name);
        et_userPsw = findViewById(R.id.user_psw);
        tv_login = findViewById(R.id.bt_login);
        tv_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String userName = et_userName.getText().toString().trim();
                String userPsw = et_userPsw.getText().toString().trim();
                if (TextUtils.isEmpty(userName) || userName.length() != 11) {
                    MyToast.showToast(activity, "请输入正确的账号");
                    return;
                }
                if (TextUtils.isEmpty(userPsw) || !userPsw.equals("1111")) {
                    MyToast.showToast(activity, "请输入正确的密码");
                    return;
                }
                AccountManager.setAccountId(activity, userName);
                activity.startActivity(new Intent(activity, StudentActivity.class));
            }
        });
    }


}

2.学生表格的操作

Android 使用数据库 android 数据库管理_Android 使用数据库_02

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:text="学生表数据库"
    android:textSize="22sp"
    android:textStyle="bold"
    android:gravity="center"
    />
    <EditText
        android:layout_marginTop="20dp"
        android:id="@+id/et_student_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:hint="请输入学生编号"
        android:textSize="20sp"
        android:background="#F5D1D1"
        />
    <EditText
        android:id="@+id/et_student_name"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:hint="请输入学生姓名"
        android:textSize="20sp"
        android:background="#E0ECF5"
        />
    <EditText
        android:id="@+id/et_student_age"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:hint="请输入学生年龄"
        android:textSize="20sp"
        android:background="#F0D6CD"
        />
    <EditText
        android:id="@+id/et_student_chinese"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:hint="请输入学生语文成绩"
        android:textSize="20sp"
        android:background="#D8ECEE"
        />
    <EditText
        android:id="@+id/et_student_math"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:hint="请输入数学成绩"
        android:textSize="20sp"
        android:background="#F5E4EA"
        />
        <EditText
            android:layout_marginTop="20dp"
            android:id="@+id/et_student_english"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:hint="请输入英语成绩"
            android:textSize="20sp"
            android:background="#F5D1D1"
            />
    <TextView
        android:id="@+id/insert"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="新增一条数据"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#4056D3"
        android:gravity="center"
        android:background="#BFD8DB"
        />
    <TextView
        android:id="@+id/delete"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="删除一条数据"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#4056D3"
        android:gravity="center"
        android:background="#BFD8DB"
        />
    <TextView
        android:id="@+id/update"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="更新一条数据"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#4056D3"
        android:gravity="center"
        android:background="#BFD8DB"
        />
    <TextView
        android:id="@+id/query"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="查询一条数据"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#4056D3"
        android:gravity="center"
        android:background="#BFD8DB"
        />
    <TextView
        android:id="@+id/query_all"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="查询所有数据"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#4056D3"
        android:gravity="center"
        android:background="#F8D0DE"
        />
        <TextView
            android:id="@+id/replace"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="替换一条数据"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="#4056D3"
            android:gravity="center"
            android:background="#E7DECF"
            />
        <TextView
            android:id="@+id/apply_replace"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="批量替换"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="#4056D3"
            android:gravity="center"
            android:background="#E7DECF"
            />
        <TextView
            android:id="@+id/delete_all"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="批量删除"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="#4056D3"
            android:gravity="center"
            android:background="#E7DECF"
            />
        <TextView
            android:id="@+id/tv_update_sql"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="sql语句更新"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="#4056D3"
            android:gravity="center"
            android:background="#E7DECF"
            />
        <TextView
            android:id="@+id/tv_query_sql_1"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="sql语句查询"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="#4056D3"
            android:gravity="center"
            android:background="#E7DECF"
            />
    </LinearLayout>
</ScrollView>

Java代码:

public class StudentActivity extends Activity {
    EditText etStudentId;
    EditText etStudentName;
    EditText etStudentAge;
    EditText etStudentChinese;
    EditText etStudentMath;
    EditText etStudentEnglish;
    TextView tvInsert;
    TextView tvDelete;
    TextView tvUpdate;
    TextView tvQuery;
    TextView tvQueryAll;
    TextView tvPlace;
    TextView tvapplyReplace;
    TextView tvDeleteAll;
    TextView tvUpdateSql;
    TextView tvQuerySql1;


    String studentId;
    String studentName;
    String studentAge;
    String studentChinese;
    String studentMath;
    String studentEnglish;
    Activity activity;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = this;
        setContentView(R.layout.activity_student);
        etStudentId = findViewById(R.id.et_student_id);
        etStudentName = findViewById(R.id.et_student_name);
        etStudentAge = findViewById(R.id.et_student_age);
        etStudentChinese = findViewById(R.id.et_student_chinese);
        etStudentMath = findViewById(R.id.et_student_math);
        etStudentEnglish = findViewById(R.id.et_student_english);
        tvInsert = findViewById(R.id.insert);
        tvDelete = findViewById(R.id.delete);
        tvUpdate = findViewById(R.id.update);
        tvQuery = findViewById(R.id.query);
        tvQueryAll = findViewById(R.id.query_all);
        tvPlace = findViewById(R.id.replace);
        tvapplyReplace = findViewById(R.id.apply_replace);
        tvDeleteAll = findViewById(R.id.delete_all);
        tvUpdateSql = findViewById(R.id.tv_update_sql);
        tvQuerySql1 = findViewById(R.id.tv_query_sql_1);
        /**
         * 插入一个学生信息
         */
        tvInsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
                if (CheckId() && CheckStudentName() && CheckStudentAge()) {
                    StudentBean studentBean = new StudentBean();
                    studentBean.setStudentId(Integer.valueOf(studentId));
                    studentBean.setName(studentName);
                    studentBean.setAge(studentAge);
                    studentBean.setChinese(studentChinese);
                    studentBean.setMath(studentMath);
                    studentBean.setEnglish(studentEnglish);
                    StudentDao.getInstance().insert(studentBean);
                }

            }
        });

        /**
         * 根据UserId删除一个学生信息
         */
        tvDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
                StudentDao.getInstance().delete(studentId);
            }
        });

        /**
         * 根据UserId修改一条数据信息
         */
        tvUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
                StudentBean studentBean = new StudentBean();
                studentBean.setStudentId(Integer.valueOf(studentId));
                studentBean.setName(studentName);
                studentBean.setAge(studentAge);
                studentBean.setChinese(studentChinese);
                studentBean.setMath(studentMath);
                studentBean.setEnglish(studentEnglish);
                StudentDao.getInstance().update(studentBean);
            }
        });
        /**
         * 根据UserId查询一条数据信息
         */
        tvQuery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
                if (CheckId()) {
                    StudentBean studentBean = StudentDao.getInstance().queryItem(studentId);
                    Log.e("TAGS", "query:" + studentId + ":::" + getString(studentBean));
                } else {
                    MyToast.showToast(activity, "请输入学生证编号");
                }
            }
        });

        /**
         * 查询学生表的所有数据
         */
        tvQueryAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
                List<StudentBean> list = StudentDao.getInstance().queryAll();
                if (list != null && list.size() > 0) {
                    for (int i = 0; i < list.size(); i++) {
                        StudentBean studentBean = list.get(i);
                        Log.e("TAGS", "query_all:::" + getString(studentBean));
                    }
                }
            }
        });

        /**
         * 根据UserId去替换一条数据(如果不存在则直接插入)
         */
        tvPlace.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
                StudentBean studentBean = new StudentBean();
                studentBean.setStudentId(Integer.valueOf(studentId));
                studentBean.setName(studentName);
                studentBean.setAge(studentAge);
                studentBean.setChinese(studentChinese);
                studentBean.setMath(studentMath);
                studentBean.setEnglish(studentEnglish);
                StudentDao.getInstance().replace(studentBean);
            }
        });

        /**
         * 批量插入
         * 将newInsertMessageOperation换成newReplaceMessageOperation则是批量替换
         */
        tvapplyReplace.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Random random = new Random();
                ArrayList<ContentProviderOperation> operationList = new ArrayList<>();
                for (int i = 100; i < 110; i++) {
                    StudentBean studentBean = new StudentBean();
                    studentBean.setStudentId(i);
                    studentBean.setName("liukang" + i);
                    studentBean.setAge(random.nextInt(10) + 90 + "");
                    studentBean.setChinese(random.nextInt(10) + 90 + "");
                    studentBean.setMath(random.nextInt(10) + 90 + "");
                    studentBean.setEnglish(random.nextInt(10) + 90 + "");
                    operationList.add(StudentDao.getInstance().newInsertMessageOperation(studentBean));
                }
                StudentDao.getInstance().applyBatch(MyContentProvider.AUTHORITY_APPLY, operationList);
            }
        });

        /**
         * 删除表中所有的数据
         */
        tvDeleteAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                StudentDao.getInstance().deleteAll();
            }
        });

        /**
         * 编写sql语句进行更新操作
         */
        tvUpdateSql.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                StudentDao.getInstance().updateStudentChinese();
            }
        });

        /**
         *编写sql进行查询操作
         */
        tvQuerySql1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                StudentDao.getInstance().querySql1();
                List<StudentBean> list = StudentDao.getInstance().querySql1();
                if (list != null && list.size() > 0) {
                    for (int i = 0; i < list.size(); i++) {
                        StudentBean studentBean = list.get(i);
                        Log.e("TAGS", "query_all:::" + getString(studentBean));
                    }
                }
            }
        });

    }


    public void getData() {
        studentId = etStudentId.getText().toString().trim();
        studentName = etStudentName.getText().toString().trim();
        studentAge = etStudentAge.getText().toString().trim();
        studentChinese = etStudentChinese.getText().toString().trim();
        studentMath = etStudentMath.getText().toString().trim();
        studentEnglish = etStudentEnglish.getText().toString().trim();
    }

    public boolean CheckId() {
        if (!TextUtils.isEmpty(studentId)) {
            return true;
        }

        return false;
    }

    public boolean CheckStudentName() {
        if (!TextUtils.isEmpty(studentName)) {
            return true;
        }

        return false;
    }

    public boolean CheckStudentAge() {
        if (!TextUtils.isEmpty(studentAge)) {
            return true;
        }

        return false;
    }

    public String getString(StudentBean bean) {
        Gson gson = new Gson();
        String s = gson.toJson(bean);
        return s;
    }
}public class StudentBean {
    private int studentId;
    private String name;
    private String age;
    private String Chinese;
    private String Math;
    private String English;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getChinese() {
        return Chinese;
    }

    public void setChinese(String chinese) {
        Chinese = chinese;
    }

    public String getMath() {
        return Math;
    }

    public void setMath(String math) {
        Math = math;
    }

    public String getEnglish() {
        return English;
    }

    public void setEnglish(String english) {
        English = english;
    }
}

总结:

1.常用的存储:

sharePrefrence:一般存储简单的数据,比如开关,标识。以xml形式进行存储的,当清除缓存或者卸载时,会相应的清除掉。

数据库:一般存储在data\data\包名\db 目录下,清缓存或者卸载也会被清楚

文件存储:如果是手机内存则同上,如果是SD卡里面则不会跟随清除(Q涉及到沙箱)

网络缓存:上传,下载。

2.数据库知识点: a   数据库的创建,更新     b 基类封装 :增 删 改 查  替换  批量操作 以及sql语句    

3,内容太长了,复制下来直接运行,将这个几个操作捋一遍基本OK