Android 数据库知识回顾
?
一、前言
二、效果預(yù)覽
?三、數(shù)據(jù)庫(kù)與框架的基礎(chǔ)使用
(1)第一道:原生數(shù)據(jù)庫(kù)
(2)第二道:LitePal框架?
(3)第三道:GreenDao框架?
四、總結(jié)
五、Demo地址
六、內(nèi)容推薦
一、前言
1.菜鳥(niǎo)作者為什么要寫(xiě)這篇呢?——隨GitHub上Android數(shù)據(jù)庫(kù)框架日新月異,我們應(yīng)該如何選擇一個(gè)適合我們的數(shù)據(jù)庫(kù)。
當(dāng)然一個(gè)好的數(shù)據(jù)庫(kù)框架不僅可以提高我們的開(kāi)發(fā)效率外,還可以提高項(xiàng)目的性能。
2.為什么GitHub上有那么多的開(kāi)源框架?——不言而喻,應(yīng)該是原生的開(kāi)發(fā)效率與性能上沒(méi)有開(kāi)源來(lái)的優(yōu)秀(哈哈 個(gè)人觀點(diǎn))
3.這篇主要寫(xiě)什么?——主要回顧數(shù)據(jù)庫(kù)的用法。對(duì)比一些開(kāi)源數(shù)據(jù)庫(kù)的使用方法(最基礎(chǔ)的使用方式)。因性能弄起來(lái)比較麻煩,而且相關(guān)博客也很多大家自己百度即可。
二、效果預(yù)覽
隨便給自己寫(xiě)的一個(gè)簡(jiǎn)單Demo,看完UI有沒(méi)有一種想捏死作者的沖動(dòng)...
這里只涉及簡(jiǎn)單的存儲(chǔ)操作,復(fù)雜的多對(duì)多關(guān)系這里沒(méi)有。不瞞大家,想深入理解數(shù)據(jù)庫(kù)的同學(xué)可以止步了,這里算基礎(chǔ)回顧
?三、數(shù)據(jù)庫(kù)與框架的基礎(chǔ)使用
什么是數(shù)據(jù)庫(kù)?什么是SQLite?...就解釋到這里。開(kāi)始上菜了
先說(shuō)明一下數(shù)據(jù)庫(kù)使用基礎(chǔ)步驟我把他們分為:1.創(chuàng)建數(shù)據(jù)庫(kù)? 2.創(chuàng)建表? 3.數(shù)據(jù)庫(kù)操作(增刪改查)? 4.更新數(shù)據(jù)庫(kù)
(1)第一道:原生數(shù)據(jù)庫(kù)
1.首先我們需要?jiǎng)?chuàng)建一個(gè)屬于自己的數(shù)據(jù)庫(kù)管理類(lèi)來(lái)繼承SQLiteOpenHelper數(shù)據(jù)庫(kù)幫助類(lèi)實(shí)現(xiàn)數(shù)據(jù)庫(kù)的創(chuàng)建與更新。
public class MySQLiteHelper extends SQLiteOpenHelper {private static final String TAG = "MySQLiteHelper";//數(shù)據(jù)庫(kù)建表語(yǔ)句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);//創(chuàng)建數(shù)據(jù)庫(kù)調(diào)用方法}/*** 第一次創(chuàng)建數(shù)據(jù)庫(kù)時(shí)調(diào)用 在這方法里面可以進(jìn)行建表*/@Overridepublic void onCreate(SQLiteDatabase db) {Log.i(TAG, "onCreate: " );db.execSQL(sql);}/*** 版本更新的時(shí)候調(diào)用*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.i(TAG, "onUpgrade: " );switch (oldVersion){case 1:db.execSQL(sql1);break;}} } 創(chuàng)建一個(gè)數(shù)據(jù)庫(kù):名稱(chēng)Blcs 版本號(hào) 1 MySQLiteHelper blcs = new MySQLiteHelper(context, "Blcs", null, 1);2.基本操作
//(1)打開(kāi)數(shù)據(jù)庫(kù)并進(jìn)行寫(xiě)入操作 SQLiteDatabase db= blcs.getWritableDatabase();注:Android提供了兩種操作方式:1.執(zhí)行數(shù)據(jù)庫(kù)語(yǔ)句 ?2.調(diào)用封裝好的Api方法
增:插入一條語(yǔ)句?
//方式一: 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);刪:刪除一條語(yǔ)句?
//方式一 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});改:修改一條語(yǔ)句?
//根據(jù)指定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)});查:查詢語(yǔ)句
//方式一 //查詢整張表 String query = "select * from SqliteDemo"; //獲取表中存在這個(gè)地址的數(shù)據(jù) String query = new StringBuilder().append("select * from SqliteDemo where address = '").append(Address).append("'").toString(); //獲取表中存在這個(gè)地址和姓名的數(shù)據(jù) String query = new StringBuilder().append("select * from SqliteDemo where name = '").append(Name).append("' and address = '").append(Address).append("'").toString();//執(zhí)行數(shù)據(jù)庫(kù)語(yǔ)句 Cursor cursor = db.rawQuery(query, null);//方式二 //查詢整張表 String selection = null; String str = null; //獲取表中存在這個(gè)地址的數(shù)據(jù) String selection = "address = ?"; String str = new String[]{Address}; //獲取表中存在這個(gè)地址和姓名的數(shù)據(jù) String selection = "name = ? and address = ?"; String str = new String[]{Name, Address}; //執(zhí)行相應(yīng)的Api Cursor cursor = db.query("SqliteDemo", null, selection, str, null, null, null);還沒(méi)結(jié)束 ,當(dāng)我們拿到Cursor對(duì)象后還要進(jìn)行最后的數(shù)據(jù)獲取
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.數(shù)據(jù)庫(kù)更新
當(dāng)我們數(shù)據(jù)庫(kù)有變化,并且要發(fā)布新版本的時(shí)候別忘了升級(jí)一下數(shù)據(jù)庫(kù)版本號(hào)。并且還需要在MySQLiteHelper 的 onUpgrade方法中進(jìn)行處理。
(2)第二道:LitePal框架?
簡(jiǎn)單描述:這是郭神早期對(duì)原生數(shù)據(jù)庫(kù)封裝的一個(gè)數(shù)據(jù)庫(kù)框架
優(yōu)點(diǎn)嘛:......用了就知道了哈
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,創(chuàng)建數(shù)據(jù)庫(kù):在assets?添加litepal.xml? //還有另外一種創(chuàng)建數(shù)據(jù)庫(kù)的方式? ?具體可以到GitHub或博客上了解
<?xml version="1.0" encoding="utf-8"?> <litepal>//數(shù)據(jù)庫(kù)昵稱(chēng)<dbname value="Blcs1" />//版本號(hào)<version value="1" />//數(shù)據(jù)庫(kù)表<list><mapping class="blcs.lwb.utils.bean.SqliteDemo" /></list></litepal>?
3.初始化?AndroidManifest.xml?
<manifest><applicationandroid:name="com.example.MyOwnApplication"...>...</application> </manifest>public class MyOwnApplication extends Application {@Overridepublic void onCreate() {super.onCreate();LitePal.initialize(this);}... }?
4.數(shù)據(jù)庫(kù)的操作
這里對(duì)象需要繼承LitePalSupport,調(diào)用里面的api執(zhí)行相應(yīng)的數(shù)據(jù)庫(kù)處理,可以給屬性相應(yīng)的注解,相對(duì)簡(jiǎn)單,這里就不貼了。一切從簡(jiǎn)
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;} }增
//創(chuàng)建要保存的對(duì)象,調(diào)用save方法直接保存 因?yàn)槔^承了LitePalSupport 里面提供了許多保存的APi ,可以根據(jù)需求選擇合適的方法 SqliteDemo sqliteDemo = new SqliteDemo();sqliteDemo.setName(name);sqliteDemo.setAddress(address);sqliteDemo.save(); //例:異步保存:開(kāi)個(gè)線程進(jìn)行保存,處理完監(jiān)聽(tīng)回調(diào)是否保存成功 sqliteDemo.saveAsync().listen(new SaveCallback() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onFinish(int rowsAffected) {List<SqliteDemo> all = LitePal.findAll(SqliteDemo.class);mAdapter.setNewData(all);}});查
//查詢?nèi)? List<SqliteDemo> all = LitePal.findAll(SqliteDemo.class);//獲取名字和地址對(duì)應(yīng)的數(shù)據(jù) String selection = "name = ? and address = ?"; List<SqliteDemo> all = LitePal.where(selection, Name, Address).find(SqliteDemo.class);//查詢里面隱藏著許多有用的Api,有興趣的同學(xué)可以繼續(xù)深究.這里不解釋。否則導(dǎo)致篇幅太長(zhǎng)5.數(shù)據(jù)庫(kù)的更新
使用這個(gè)框架最大的優(yōu)點(diǎn)是,我們已經(jīng)不需要自己去寫(xiě)數(shù)據(jù)庫(kù)的更新方法了。只需要提高一下版本號(hào)即可,剩下的框架已經(jīng)都幫我們處理好了。
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
簡(jiǎn)單描述:目前GitHub上最熱門(mén)的數(shù)據(jù)庫(kù)框架之一,相對(duì)其他數(shù)據(jù)庫(kù)框架star也是最多的一個(gè)。
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 plugindependencies {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配置數(shù)據(jù)庫(kù)信息:
greendao {schemaVersion 1 //數(shù)據(jù)庫(kù)版本號(hào)// 設(shè)置DaoMaster、DaoSession、Dao 包名daoPackage 'blcs.lwb.utils.greendao'targetGenDir 'src/main/java'}2.創(chuàng)建持久化對(duì)象
主要:給持久化對(duì)象添加@Entity 注解 ,然后Build -- Make Project 重新編譯一下 會(huì)自動(dòng)生成DaoMaster、DaoSession、GreenDaoDao
@Entity public class GreenDao {@Idprivate 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.創(chuàng)建數(shù)據(jù)庫(kù)
public class MyApplication extends BaseApplication {@Overridepublic void onCreate() {super.onCreate();//GreenDaoinitGreenDao();}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數(shù)據(jù)庫(kù)操作對(duì)象DaoSession daoSession = MyApplication.getDaoSession(); //獲取指定的操作對(duì)象 GreenDaoDao greenDaoDao = daoSession.getGreenDaoDao();增
GreenDao demo = new GreenDao();demo.setName(name);demo.setAddress(address);daoSession.insert(demo); //或greenDaoDao.insert(demo);刪
//查出需要?jiǎng)h除的對(duì)象 ,然后進(jìn)行刪除 daoSession.delete(bean); //或 greenDaoDao.delete(bean);改
//根據(jù)ID查找某個(gè)對(duì)象進(jìn)行更改 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);查
//查詢?nèi)?List<GreenDao> greenDaoBeans = daoSession.loadAll(GreenDao.class); //根據(jù)條件查詢 List<GreenDao> greenDaoBeans = daoSession.queryRaw(GreenDao.class, "where NAME = ? and ADDRESS = ?", Name,Address);大部分daoSession操作方法 ,greenDaoDao也會(huì)有4.數(shù)據(jù)庫(kù)更新
GreenDao的OpenHelper下有個(gè) onUpgrade(Database db, int oldVersion, int newVersion)方法,當(dāng)設(shè)置的數(shù)據(jù)庫(kù)版本改變時(shí),在數(shù)據(jù)庫(kù)初始化的時(shí)候就會(huì)回調(diào)到這個(gè)方法,我們可以通過(guò)繼承OpenHelper重寫(xiě)onUpgrade方法來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)更新操作。
注:如果沒(méi)有重寫(xiě)更新方法只升級(jí)版本號(hào)的話:會(huì)導(dǎo)致數(shù)據(jù)丟失。
四、總結(jié)
使用原生數(shù)據(jù)庫(kù)容易出現(xiàn)語(yǔ)句錯(cuò)誤,使用繁瑣,提供的Api也比較少。相對(duì)于原生數(shù)據(jù)庫(kù),我們可以采用郭神的LitePal框架,主要是基于原生數(shù)據(jù)庫(kù)封裝的。提供的Api比較豐富,而且使用也方便。
但是從性能方面上來(lái)看可能沒(méi)有GreenDdao框架高,具體可以查看GreenDdao文檔。里面有進(jìn)行詳細(xì)的描述。
當(dāng)然還有許多不錯(cuò)的數(shù)據(jù)框架:DBFlow、ActiveAndroid、ORMLite、Realm、Afinal?....
最后在推薦一個(gè)性能更好的數(shù)據(jù)庫(kù)框架objectbox
官網(wǎng):https://objectbox.io/
GitHub:https://github.com/objectbox/objectbox-java
為什么菜鳥(niǎo)作者不寫(xiě)呢?——還在學(xué)習(xí)中..
注:AS中并不能直接打開(kāi).db文件? 所以一般要查看數(shù)據(jù)庫(kù)文件需要借助工具
不過(guò)那樣會(huì)很麻煩,需要先找到文件導(dǎo)出后再工具中查看。
所以這里可以引用Android-Debug-Database,在不借助工具的情況下查看數(shù)據(jù)庫(kù)。
五、Demo地址
Github:https://github.com/DayorNight/BLCS
碼云:https://gitee.com/blcs/BLCS
apk下載體驗(yàn)地址:https://www.pgyer.com/BLCS
六、內(nèi)容推薦
簡(jiǎn)書(shū):《Android ?數(shù)據(jù)庫(kù)知識(shí)回顧》
《Android 下載安裝應(yīng)用APK封裝(適配8.0)》
《Android Notification通知簡(jiǎn)單封裝(適配8.0)》
《Android 仿RxDialog自定義DialogFragment》
《Android 獲取App應(yīng)用、緩存、數(shù)據(jù)等大小適配8.0(仿微信存儲(chǔ)空間)》
如果你覺(jué)得寫(xiě)的不錯(cuò)或者對(duì)您有所幫助的話
不妨頂一個(gè)【微笑】,別忘了點(diǎn)贊、收藏、加關(guān)注哈
看在花了這么多時(shí)間整理寫(xiě)成文章分享給大家的份上,記得手下留情哈
您的每個(gè)舉動(dòng)都是對(duì)我莫大的支持
?
?
總結(jié)
以上是生活随笔為你收集整理的Android 数据库知识回顾的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何更改QQ截图的快捷键
- 下一篇: 建筑工程图上的尺寸数字