Android中的存储详解


当前第2页 返回上一页

首先是Constants类,是常量类,其中有我们的数据库名、版本号、表名

public class Constants {
    public static final String DATABASE_NAME = "woodwhale.db";
    public static final int VERSION_CODE = 1;
    public static final String TABLE_NAME = "user";
}

其次是DatabaseHelper类,继承SQLiteOpenHelper类,用来开启数据库,其中的onCreate方法是数据库创建时的回调,onUpgrade方法时升级数据时的回调,我们在Constans类中写了一个版本号,爸爸那边每次升级可以加入新的功能,可以写在onUpgrade方法中,通过switch实现。不过需要注意,升级只能让版本号上升,不能降级,否则会报错

package top.woodwhale.qqlogin.SQLite.utils;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DatabaseHelper extends SQLiteOpenHelper {
    public static String TAG = "DatabaseHelper";
    /**
     * @param context   上下文
     */
    public DatabaseHelper( Context context) {
        super(context, Constants.DATABASE_NAME, null, Constants.VERSION_CODE);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        // 创建时的回调
        Log.d(TAG, "创建数据库");
        String sql = "create table " + Constants.TABLE_NAME + " (id integer,name varchar,age integer)";
        sqLiteDatabase.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        // 升级数据库的回调
        Log.d(TAG, "升级数据库!");
        String sql = null;
        switch (i) {
            case 1:
                sql = "alter table "+ Constants.TABLE_NAME + " add phone integer";
                sqLiteDatabase.execSQL(sql);
                break;
            case 2:
                sql = "alter table "+ Constants.TABLE_NAME + " add address varchar";
                sqLiteDatabase.execSQL(sql);
                break;
        }
    }
}

最后就是我们封装好的数据库BaseDao类,通过语句实现了增删改查

package top.woodwhale.qqlogin.SQLite.dao;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import top.woodwhale.qqlogin.SQLite.utils.Constants;
import top.woodwhale.qqlogin.SQLite.utils.DatabaseHelper;

// BaseDao类
public class BaseDao {

    private final DatabaseHelper dbh;
    private SQLiteDatabase db;
    public static String TAG = "BaseDao";

    public BaseDao(Context context) {
        dbh = new DatabaseHelper(context);
    }

    // 增
    public void add(int id, String name, int age) {
        db = dbh.getWritableDatabase();
        String sql = "insert into " + Constants.TABLE_NAME + "(id,name,age) values(?,?,?)";
        Object[] params = new Object[]{id,name,age};
        db.execSQL(sql,params);
        db.close();
    }

    // 删
    public void free(int id) {
        db = dbh.getWritableDatabase();
        String sql = "delete from " + Constants.TABLE_NAME + " where id=?";
        Object[] params = new Object[]{id};
        db.execSQL(sql,params);
        db.close();
    }

    // 改
    public void edit(int id, int age) {
        db = dbh.getWritableDatabase();
        String sql = "update " + Constants.TABLE_NAME +" set age = ? where id = ?";
        Object[] params = new Object[]{age,id};
        db.execSQL(sql,params);
        db.close();
    }

    // 查
    @SuppressLint("Range")
    public void show(int id) {
        db = dbh.getReadableDatabase();
        String sql = "select * from  " + Constants.TABLE_NAME +" where id = ?";
        String[] params = new String[]{String.valueOf(id)};
        Cursor cursor =  db.rawQuery(sql, params);
        while (cursor.moveToNext()) {
            String name = cursor.getString(cursor.getColumnIndex("name"));
            Log.d(TAG,"name == "+name);
            int age = cursor.getInt(cursor.getColumnIndex("age"));
            Log.d(TAG,"age == "+age);
        }
        cursor.close();
        db.close();
    }
}

接着我们在AndroidTest包下进行测试

package top.woodwhale.qqlogin;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

import top.woodwhale.qqlogin.SQLite.dao.BaseDao;
import top.woodwhale.qqlogin.SQLite.utils.DatabaseHelper;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a  rel="external nofollow" >Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    public static final String TAG = "ExampleInstrumentedTest";
    public static final Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();;
    public static final BaseDao dao = new BaseDao(appContext);;

    @Test
    public void useAppContext() {
        // Context of the app under test.
        assertEquals("top.woodwhale.qqlogin", appContext.getPackageName());
    }

    @Test
    public void testCreate() {
        DatabaseHelper dbh = new DatabaseHelper(appContext);
        SQLiteDatabase writableDatabase = dbh.getWritableDatabase();
        Log.d(TAG, writableDatabase.getPath());
    }

    @Test
    public void testAdd() {
        dao.add(1,"woodwhale",19);
        dao.add(2,"sheepbotany",21);
    }
    @Test
    public void testFree() {
        dao.free(1);
    }
    @Test
    public void testEdit() {
        dao.edit(1,3);
    }
    @Test
    public void testShow() {
        dao.show(1);
    }

}

增删改查都成功,成功就如图所示:

由于只有查询有log回显,在logcat中之后show方法出现了log

4.2 使用Google写的API处理

那么使用Google写好的增删改查api可以避免我们sql语句的格式问题和语法错误

经过测试,如下代码没有问题(在BaseDao类中)

// 使用API的添加
    public void addByAPI(int id, String name, int age) {
        ContentValues contentValues = new ContentValues();
        contentValues.put("id",id);
        contentValues.put("name",name);
        contentValues.put("age",age);
        db = dbh.getWritableDatabase();
        db.insert(Constants.TABLE_NAME,null,contentValues);
        db.close();
    }
    // 删除
    public void freeByAPI(int id) {
        db = dbh.getWritableDatabase();
        db.delete(Constants.TABLE_NAME,"id = ?",new String[]{String.valueOf(id)});
        db.close();
        Log.d(TAG,"API删除成功!");
    }
    // 修改
    public void editByAPI(int id, String name, Integer age) {
        ContentValues contentValues = new ContentValues();
        if (name != null) {
            contentValues.put("name",name);
        }
        if (age != null) {
            contentValues.put("age",age);
        }
        db = dbh.getWritableDatabase();
        db.update(Constants.TABLE_NAME,contentValues,"id = ?", new String[]{String.valueOf(id)});
        db.close();
    }
    // 查询
    public void showByAPI(int id) {
        db = dbh.getReadableDatabase();
        Cursor cursor = db.query(false, Constants.TABLE_NAME, new String[]{"id", "name", "age"}, "id = ?", new String[]{String.valueOf(id)}, "id", null, null, null);
        while (cursor.moveToNext()) {
            int ID = cursor.getInt(0);
            Log.d(TAG,"ID == "+ID);
            String name = cursor.getString(1);
            Log.d(TAG,"name == "+name);
            int age = cursor.getInt(2);
            Log.d(TAG,"age == "+age);
        }
        cursor.close();
        db.close();

    }

4.3 事务使用

使用db.beginTransaction(); db.setTransactionSuccessful(); db.endTransaction();三个方法来进行事务的处理。

简单的一个测试类

// 测试一个数据库事物
    @Test
    public void testTransaction() {
        DatabaseHelper dbh = new DatabaseHelper(appContext);
        SQLiteDatabase db = dbh.getWritableDatabase();
        db.beginTransaction();
        Log.d(TAG,"事物开启!");
        try {
            db.execSQL("update " + Constants.TABLE_NAME +" set age = 114 where id = 1");
            int i = 10 / 0;
            db.execSQL("update " + Constants.TABLE_NAME +" set age = 114 where id = 2");
            db.setTransactionSuccessful();
            Log.d(TAG,"事物成功!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.endTransaction();
            db.close();
            Log.d(TAG,"事物关闭!");
        }
        dao.showByAPI(1);
        dao.showByAPI(2);
    }

看看logcat,首先是进入了 事物开启,然后程序进入了try中,因为除以了一个0所以报错,捕获异常了之后就是进入到finally中关闭了事务,可以发现我们sql中的信息都回滚了,没有改变。

我们把int i = 10 / 0;删了试一试,可以看到成功执行事物。

值得注意的是,事物开启之后,仅有当前的db对象可以执行sql语句,使用Dao类中的方法是无法进行增删改查的,因为对这些得到的db对象上了锁!

总结

到此这篇关于Android中的存储详解的文章就介绍到这了,更多相关Android存储内容请搜索


标签:SQLite

返回前面的内容

相关阅读 >>

Sqlite数据库安装及基本操作指南

android调试工具adb命令大全

python sqlalchemy库的使用方法

c#使用dataset datatable更新数据库的三种实现方法

Sqlite不支持right join的解决办法group by

python实现读写Sqlite3数据库并将统计数据写入excel的方法示例

android开发中的数据库事务用法分析

android数据存储之Sqlite使用

android基于Sqlite实现注册和登录功能

android如何获取qq与微信的聊天记录并保存到数据库详解

更多相关阅读请进入《Sqlite》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...