Android数据库知识回顾

    xiaoxiao2025-05-27  91

     

    一、前言

    二、效果预览

    ​三、数据库与框架的基础使用

    (1)第一道:原生数据库

    (2)第二道:LitePal框架 

    (3)第三道:GreenDao框架 

    四、总结

    五、Demo地址

    六、内容推荐


    一、前言

    1.菜鸟作者为什么要写这篇呢?——随GitHub上Android数据库框架日新月异,我们应该如何选择一个适合我们的数据库。

    当然一个好的数据库框架不仅可以提高我们的开发效率外,还可以提高项目的性能。

    2.为什么GitHub上有那么多的开源框架?——不言而喻,应该是原生的开发效率与性能上没有开源来的优秀(哈哈 个人观点)

    3.这篇主要写什么?——主要回顾数据库的用法。对比一些开源数据库的使用方法(最基础的使用方式)。因性能弄起来比较麻烦,而且相关博客也很多大家自己百度即可。

    二、效果预览

    随便给自己写的一个简单Demo,看完UI有没有一种想捏死作者的冲动...

    这里只涉及简单的存储操作,复杂的多对多关系这里没有。不瞒大家,想深入理解数据库的同学可以止步了,这里算基础回顾

    ​三、数据库与框架的基础使用

    什么是数据库?什么是SQLite?...就解释到这里。开始上菜了

    先说明一下数据库使用基础步骤我把他们分为:1.创建数据库  2.创建表  3.数据库操作(增删改查)  4.更新数据库

    (1)第一道:原生数据库

    1.首先我们需要创建一个属于自己的数据库管理类来继承SQLiteOpenHelper数据库帮助类实现数据库的创建与更新。

    public class MySQLiteHelper extends SQLiteOpenHelper { private static final String TAG = "MySQLiteHelper"; //数据库建表语句 public static final String sql = "create table SqliteDemo (id integer primary key autoincrement, name text(4),address text(5))"; public static final String sql1 = "create table test1 (id integer primary key autoincrement, name text(4),address text(5))"; public MySQLiteHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version);//创建数据库调用方法 } /** * 第一次创建数据库时调用 在这方法里面可以进行建表 */ @Override public void onCreate(SQLiteDatabase db) { Log.i(TAG, "onCreate: " ); db.execSQL(sql); } /** * 版本更新的时候调用 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i(TAG, "onUpgrade: " ); switch (oldVersion){ case 1: db.execSQL(sql1); break; } } } 创建一个数据库:名称Blcs 版本号 1 MySQLiteHelper blcs = new MySQLiteHelper(context, "Blcs", null, 1);

    2.基本操作

    //(1)打开数据库并进行写入操作 SQLiteDatabase db= blcs.getWritableDatabase();

    注:Android提供了两种操作方式:1.执行数据库语句  2.调用封装好的Api方法

    增:插入一条语句 

    //方式一: String insert = new StringBuilder() .append("insert into SqliteDemo (name,address) values ('") .append(name).append("','").append(address).append("')") .toString(); //或是 //String insert = "insert into SqlteDemo (name,address) values ('"+name+"','"+address+"')"; db.execSQL(insert); //方式二: ContentValues contentValues = new ContentValues(); contentValues.put("name", name); contentValues.put("address", address); db.insert("SqliteDemo", null, contentValues);

    删:删除一条语句 

    //方式一 String delete = new StringBuilder().append("delete from SqliteDemo where name = '").append(Name).append("' or address = '").append(Address).append("'").toString(); db.execSQL(delete); //方式二 db.delete("SqliteDemo", "name = ? or address = ?", new String[]{Name, Address});

    改:修改一条语句 

    //根据指定ID修改name 与 address //方式一 String update = new StringBuilder().append("update SqliteDemo set name = '").append(Name) .append("' , address = '").append(Address) .append("' where id = ").append(Id) .toString(); db.execSQL(update); //方式二 ContentValues contentValues = new ContentValues(); contentValues.put("name", Name); contentValues.put("address", Address); db.update("SqliteDemo", contentValues, "id = ?", new String[]{String.valueOf(Id)});

    查:查询语句

    //方式一 //查询整张表 String query = "select * from SqliteDemo"; //获取表中存在这个地址的数据 String query = new StringBuilder().append("select * from SqliteDemo where address = '") .append(Address).append("'").toString(); //获取表中存在这个地址和姓名的数据 String query = new StringBuilder().append("select * from SqliteDemo where name = '") .append(Name).append("' and address = '").append(Address).append("'").toString(); //执行数据库语句 Cursor cursor = db.rawQuery(query, null); //方式二 //查询整张表 String selection = null; String str = null; //获取表中存在这个地址的数据 String selection = "address = ?"; String str = new String[]{Address}; //获取表中存在这个地址和姓名的数据 String selection = "name = ? and address = ?"; String str = new String[]{Name, Address}; //执行相应的Api Cursor cursor = db.query("SqliteDemo", null, selection, str, null, null, null);

    还没结束 ,当我们拿到Cursor对象后还要进行最后的数据获取

    ArrayList<SqliteDemo> dats = new ArrayList<>(); while (cursor.moveToNext()) { SqliteDemo sqliteDemo = new SqliteDemo(); long id = cursor.getLong(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); String address = cursor.getString(cursor.getColumnIndex("address")); sqliteDemo.setId(id); sqliteDemo.setName(name); sqliteDemo.setAddress(address); dats.add(sqliteDemo); } return dats;

    3.数据库更新

    当我们数据库有变化,并且要发布新版本的时候别忘了升级一下数据库版本号。并且还需要在MySQLiteHelper 的 onUpgrade方法中进行处理。

    (2)第二道:LitePal框架 

    简单描述:这是郭神早期对原生数据库封装的一个数据库框架

    优点嘛:......用了就知道了哈

    GitHub:https://github.com/LitePalFramework/LitePal

    guolin:https://blog.csdn.net/sinyu890807/column/info/android-database-pro

    1.基本配置

    1.添加依赖 dependencies { implementation 'org.litepal.android:java:3.0.0' } or dependencies { implementation 'org.litepal.android:kotlin:3.0.0' }

    2,创建数据库:在assets 添加litepal.xml  //还有另外一种创建数据库的方式   具体可以到GitHub或博客上了解

    <?xml version="1.0" encoding="utf-8"?> <litepal> //数据库昵称 <dbname value="Blcs1" /> //版本号 <version value="1" /> //数据库表 <list> <mapping class="blcs.lwb.utils.bean.SqliteDemo" /> </list> </litepal>

     

    3.初始化 AndroidManifest.xml 

    <manifest> <application android:name="com.example.MyOwnApplication" ... > ... </application> </manifest> public class MyOwnApplication extends Application { @Override public void onCreate() { super.onCreate(); LitePal.initialize(this); } ... }

     

    4.数据库的操作

    这里对象需要继承LitePalSupport,调用里面的api执行相应的数据库处理,可以给属性相应的注解,相对简单,这里就不贴了。一切从简

    public class SqliteDemo extends LitePalSupport { private Long id; private String name; private String address; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }

    //创建要保存的对象,调用save方法直接保存 因为继承了LitePalSupport 里面提供了许多保存的APi ,可以根据需求选择合适的方法 SqliteDemo sqliteDemo = new SqliteDemo(); sqliteDemo.setName(name); sqliteDemo.setAddress(address); sqliteDemo.save(); //例:异步保存:开个线程进行保存,处理完监听回调是否保存成功 sqliteDemo.saveAsync().listen(new SaveCallback() { @Override public void onFinish(boolean success) { List<SqliteDemo> all = LitePal.findAll(SqliteDemo.class); mAdapter.setNewData(all); } });

    //LitePal.delete(); //LitePal.deleteAll(); //LitePal.deleteAsync() LitePal.deleteAllAsync(SqliteDemo.class,"name = ? or address = ?",Name,Address).listen(new UpdateOrDeleteCallback() { @Override public void onFinish(int rowsAffected) { List<SqliteDemo> all = LitePal.findAll(SqliteDemo.class); mAdapter.setNewData(all); } });

    //LitePal.update(); //LitePal.updateAll(); //LitePal.updateAsync(); //LitePal.updateAllAsync(); ContentValues contentValues = new ContentValues(); contentValues.put("name", Name); contentValues.put("address", Address); LitePal.updateAsync(SqliteDemo.class,contentValues,Id).listen(new UpdateOrDeleteCallback() { @Override public void onFinish(int rowsAffected) { List<SqliteDemo> all = LitePal.findAll(SqliteDemo.class); mAdapter.setNewData(all); } });

    //查询全部 List<SqliteDemo> all = LitePal.findAll(SqliteDemo.class); //获取名字和地址对应的数据 String selection = "name = ? and address = ?"; List<SqliteDemo> all = LitePal.where(selection, Name, Address).find(SqliteDemo.class); //查询里面隐藏着许多有用的Api,有兴趣的同学可以继续深究.这里不解释。否则导致篇幅太长

    5.数据库的更新

    使用这个框架最大的优点是,我们已经不需要自己去写数据库的更新方法了。只需要提高一下版本号即可,剩下的框架已经都帮我们处理好了。

    6.混淆

    -keep class org.litepal.** { *; } -keep class * extends org.litepal.crud.DataSupport { *; } -keep class * extends org.litepal.crud.LitePalSupport { *; }

    (3)第三道:GreenDao框架 

    greendao :https://github.com/greenrobot/greenDAO

    介绍:http://greenrobot.org/greendao/documentation/

    参考博客:https://www.jianshu.com/p/53083f782ea2

    简单描述:目前GitHub上最热门的数据库框架之一,相对其他数据库框架star也是最多的一个。

    1.基本配置

    // In your root build.gradle file: buildscript { repositories { jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:3.1.1' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin } } // In your app projects build.gradle file: apply plugin: 'com.android.application' apply plugin: 'org.greenrobot.greendao' // apply plugin dependencies { implementation 'org.greenrobot:greendao:3.2.2' // add library }

    混淆

    -keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { public static java.lang.String TABLENAME; } -keep class **$Properties -dontwarn org.greenrobot.greendao.database.** -dontwarn rx.** ### greenDAO 2 -keepclassmembers class * extends de.greenrobot.dao.AbstractDao { public static java.lang.String TABLENAME; } -keep class **$Properties

    配置数据库信息:

    greendao { schemaVersion 1 //数据库版本号 // 设置DaoMaster、DaoSession、Dao 包名 daoPackage 'blcs.lwb.utils.greendao' targetGenDir 'src/main/java' }

    2.创建持久化对象

    主要:给持久化对象添加@Entity 注解 ,然后Build -- Make Project 重新编译一下 会自动生成DaoMaster、DaoSession、GreenDaoDao

    @Entity public class GreenDao { @Id private Long id; private String name; private String address; @Generated(hash = 534050545) public GreenDao(Long id, String name, String address) { this.id = id; this.name = name; this.address = address; } @Generated(hash = 766040118) public GreenDao() { } public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getAddress() { return this.address; } public void setAddress(String address) { this.address = address; } }

    3.创建数据库

    public class MyApplication extends BaseApplication { @Override public void onCreate() { super.onCreate(); //GreenDao initGreenDao(); } private void initGreenDao() { DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "Blcs2.db"); SQLiteDatabase db = helper.getWritableDatabase(); DaoMaster daoMaster = new DaoMaster(db); daoSession = daoMaster.newSession(); } private static DaoSession daoSession; public static DaoSession getDaoSession() { return daoSession; } }

    4.基本操作

    //获取GreenDao数据库操作对象 DaoSession daoSession = MyApplication.getDaoSession(); //获取指定的操作对象 GreenDaoDao greenDaoDao = daoSession.getGreenDaoDao();

    GreenDao demo = new GreenDao(); demo.setName(name); demo.setAddress(address); daoSession.insert(demo); //或 greenDaoDao.insert(demo);

    //查出需要删除的对象 ,然后进行删除 daoSession.delete(bean); //或 greenDaoDao.delete(bean);

    //根据ID查找某个对象进行更改 List<GreenDao> demos = daoSession.queryRaw(GreenDao.class, "where _id = ?", "" + Id); GreenDao demo = demos.get(0); demo.setName(Name); demo.setAddress(Address); daoSession.update(demo); //或 greenDaoDao.update(demo);

    //查询全部 List<GreenDao> greenDaoBeans = daoSession.loadAll(GreenDao.class); //根据条件查询 List<GreenDao> greenDaoBeans = daoSession.queryRaw(GreenDao.class, "where NAME = ? and ADDRESS = ?", Name,Address); 大部分daoSession操作方法 ,greenDaoDao也会有

    4.数据库更新

    GreenDao的OpenHelper下有个 onUpgrade(Database db, int oldVersion, int newVersion)方法,当设置的数据库版本改变时,在数据库初始化的时候就会回调到这个方法,我们可以通过继承OpenHelper重写onUpgrade方法来实现数据库更新操作。

    注:如果没有重写更新方法只升级版本号的话:会导致数据丢失。

    四、总结

    使用原生数据库容易出现语句错误,使用繁琐,提供的Api也比较少。相对于原生数据库,我们可以采用郭神的LitePal框架,主要是基于原生数据库封装的。提供的Api比较丰富,而且使用也方便。

    但是从性能方面上来看可能没有GreenDdao框架高,具体可以查看GreenDdao文档。里面有进行详细的描述。

    当然还有许多不错的数据框架:DBFlow、ActiveAndroid、ORMLite、Realm、Afinal ....

    最后在推荐一个性能更好的数据库框架objectbox

    官网:https://objectbox.io/

    GitHub:https://github.com/objectbox/objectbox-java

    为什么菜鸟作者不写呢?——还在学习中..

    注:AS中并不能直接打开.db文件  所以一般要查看数据库文件需要借助工具

    不过那样会很麻烦,需要先找到文件导出后再工具中查看。

    所以这里可以引用Android-Debug-Database,在不借助工具的情况下查看数据库。

    五、Demo地址

    Github:https://github.com/DayorNight/BLCS

    码云:https://gitee.com/blcs/BLCS

    apk下载体验地址:https://www.pgyer.com/BLCS

    六、内容推荐

    简书:《Android  数据库知识回顾》

    《Android 下载安装应用APK封装(适配8.0)》

    《Android Notification通知简单封装(适配8.0)》

    《Android 仿RxDialog自定义DialogFragment》

    《Android 获取App应用、缓存、数据等大小适配8.0(仿微信存储空间)》

    如果你觉得写的不错或者对您有所帮助的话

    不妨顶一个【微笑】,别忘了点赞、收藏、加关注哈

    看在花了这么多时间整理写成文章分享给大家的份上,记得手下留情哈

    您的每个举动都是对我莫大的支持

     

    最新回复(0)