找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5967|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

商城開發(fā)筆記-12-購物車數(shù)據(jù)存儲(chǔ)開發(fā)中使用開源ORM框架操作數(shù)據(jù)庫

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:109770 發(fā)表于 2016-3-22 17:29 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
一、前言


       好吧,在正式記錄今天的開發(fā)筆記之前,先說一些題外話吧。今天(201623日)本來是個(gè)不錯(cuò)的天氣,但是由于昨天晚上亂吃東西,今天起來又嘔又吐,肚子疼,拉肚子。。。。(好恐怖有木有。┍绢惛鷦e人約好去打球的結(jié)果沒打成,心中真是一萬只草泥馬在崩騰啊~
       由于直接把Word文檔中的文章復(fù)制到QQ空間日志不能顯示圖片,因此我以后盡量減少使用圖片吧,大家也可以到我的網(wǎng)盤去下載源word文件。


二、商城應(yīng)用中購物車數(shù)據(jù)的存儲(chǔ)
       商城APP中,我們需要把用戶的添加到購物車的商品信息保存起來,其中每一條數(shù)據(jù)包含商品的基本信息(ID,圖片,名字,介紹,價(jià)格等)以及用戶添加的該商品的數(shù)量。

       購物車數(shù)據(jù)存儲(chǔ)在哪里?對(duì)于這個(gè)問題,解答有兩個(gè):

1、保存在云端(服務(wù)器)。如果我們的客戶端有Android版本,IOS版本,Web版本等多版本的時(shí)候,這種方式可以進(jìn)行不同版本的數(shù)據(jù)同步。因此,多版本下,必須使用這種方式存儲(chǔ)購物車數(shù)據(jù)。

2、保存在客戶端的系統(tǒng)的本地。

由于我們的APP開發(fā)只有Android版本,因此使用本地的方式存儲(chǔ)購物車數(shù)據(jù)。

那么問題又來了,如果保存在本地,應(yīng)該如何保存?
Android中常用的數(shù)據(jù)存儲(chǔ)方式有:
1、使用數(shù)據(jù)庫。
2、使用文件來存儲(chǔ)。
3、使用SharePreference保存。

       至于三種方式的區(qū)別這里不贅述,詳細(xì)請(qǐng)去百度Android中常用的數(shù)據(jù)存儲(chǔ)方式以及區(qū)別和使用。

       我們的視頻教程中使用SharePreference存儲(chǔ)購物車數(shù)據(jù):通過把List中的Bean對(duì)象轉(zhuǎn)換為JSON字符串?dāng)?shù)據(jù)來存起來,取出來的時(shí)候通過Gson重新把JSON轉(zhuǎn)換為Bean對(duì)象。在內(nèi)存中維護(hù)了兩個(gè)數(shù)組,一個(gè)是我們常用的ArrayList,一個(gè)是稀疏數(shù)組SparseArray,ArrayList用于Adapter的展示,SparseArray主要用于存儲(chǔ)(與JSON對(duì)象之間的轉(zhuǎn)換)。由于我們每一條Bean都是通過ID來區(qū)分的,因此一開始使用Map<int id , Bean b>的方式來存儲(chǔ),但是Android Studio只能地提示我們使用SparseArray,因?yàn)?/font>SparseArray對(duì)鍵是int類型的Map做過優(yōu)化。
       但是,這種方式需要同時(shí)維護(hù)兩個(gè)數(shù)組,顯然比較麻煩。因此我個(gè)人考慮使用其他方法來存儲(chǔ)購物車數(shù)據(jù)--數(shù)據(jù)庫。但是眾所周知數(shù)據(jù)庫的操作以及配置比較麻煩,還得去學(xué)習(xí)數(shù)據(jù)庫的SQL語句。但是幸好我們有開源ORM框架。下一節(jié)將開始介紹。


三、Android中開源ORM框架LitePal介紹
   本次筆記介紹GitHub上面非常著名的一個(gè)數(shù)據(jù)庫操作依賴庫,LitePalLitePal是一款開源的Android數(shù)據(jù)庫操作映射框架,它采用了對(duì)象關(guān)系映射(ORM)的模式,并將我們平時(shí)開發(fā)時(shí)最常用到的一些數(shù)據(jù)庫功能進(jìn)行了封裝,使得不用編寫一行SQL語句就可以完成各種建表、増刪改查的操作。并且LitePal,jar包只有100k不到,而且近乎零配置,這一點(diǎn)和Hibernate這類的框架有很大區(qū)別。目前LitePal的源碼已經(jīng)托管到了GitHub上,地址是 https://github.com/LitePalFramework/LitePal

       實(shí)為了方便我們對(duì)數(shù)據(jù)庫表進(jìn)行管理,其實(shí)Android本身就提供了一個(gè)幫助類:SQLiteOpenHelper。這個(gè)類集創(chuàng)建和升級(jí)數(shù)據(jù)庫于一身,并且自動(dòng)管理了數(shù)據(jù)庫版本,算是一個(gè)非常好用的工具。SQLiteOpenHelper是一個(gè)抽象類,這意味著如果我們想要使用它的話,就需要?jiǎng)?chuàng)建一個(gè)自己的幫助類去繼承它。SQLiteOpenHelper中有兩個(gè)抽象方法,分別是onCreate()onUpgrade(),我們必須在自己的幫助類里面重寫這兩個(gè)方法,然后分別在這兩個(gè)方法中去實(shí)現(xiàn)創(chuàng)建、升級(jí)數(shù)據(jù)庫的邏輯。

       上文提到過,與傳統(tǒng)的數(shù)據(jù)庫使用不同,LitePal框架采取的是對(duì)象關(guān)系映射(ORM)的模式,那么什么是對(duì)象關(guān)系映射呢?簡單點(diǎn)說,我們使用的編程語言是面向?qū)ο笳Z言,而我們使用的數(shù)據(jù)庫則是關(guān)系型數(shù)據(jù)庫,那么將面向?qū)ο蟮恼Z言和面向關(guān)系的數(shù)據(jù)庫之間建立一種映射關(guān)系,這就是對(duì)象關(guān)系映射了。但是為什么要使用對(duì)象關(guān)系映射模式呢?這主要是因?yàn)榇蠖鄶?shù)的程序員都很擅長面向?qū)ο缶幊,但其中只有少部分的人才比較精通關(guān)系型數(shù)據(jù)庫。而且數(shù)據(jù)庫的SQL語言晦澀難懂,就算程序員很精通它,恐怕也不喜歡經(jīng)常在代碼中去寫。而對(duì)象關(guān)系映射模式則很好地解決了這個(gè)問題,它允許程序員使用面向?qū)ο蟮姆绞絹聿僮鲾?shù)據(jù)庫,從而可以從晦澀難懂的SQL語言中解脫出來。
四、LitePal的基本使用以及注意點(diǎn)
       1,LitePal的引入以及數(shù)據(jù)庫的創(chuàng)建

      LitePal來操作數(shù)據(jù)庫,首先應(yīng)該在Gradle的配置文件當(dāng)中把LitePal框架引入到項(xiàng)目中,代碼如下:
compile 'org.litepal.android:core:1.3.0'
       Application中配置LitePal,在自己的Application中的onCreate方法中進(jìn)行LitePal的初始化:
       由于操作數(shù)據(jù)庫時(shí)需要用到Context,而我們顯然不希望在每個(gè)接口中都去傳一遍這個(gè)參數(shù),那樣操作數(shù)據(jù)庫就顯得太繁瑣了。因此,LitePal使用了一個(gè)方法來簡化掉Context這個(gè)參數(shù),只需要繼承LitePalApplication,然后在AndroidManifest.xml中配置一下LitePalApplication,所有的數(shù)據(jù)庫操作就都不用再傳Context了。
public class MyApplication extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        LitePalApplication.initialize(this);
    }
}
將Application配置為自己的Application:
<application
        android:name=".MyApplication">
        .......
</application>
      
2,使用LitePal創(chuàng)建基本表
   根據(jù)對(duì)象關(guān)系映射模式的理念,每一張表都應(yīng)該對(duì)應(yīng)一個(gè)模型(Model),也就是說,如果我們想要建一張X表,就應(yīng)該有一個(gè)對(duì)應(yīng)的X模型類。所以應(yīng)該新建一個(gè)X類,并且繼承DataSupport類,寫上必須的字段。其中id這個(gè)字段可寫可不寫,因?yàn)榧词共粚戇@個(gè)字段,LitePal也會(huì)在表中自動(dòng)生成一個(gè)id列,但是最好寫上,畢竟每張表都一定要有主鍵的。最后需要在上述的XML代碼中配置一下。
       這里要特別說明一下,LitePal的映射規(guī)則是非常輕量級(jí)的,不像一些其它的數(shù)據(jù)庫框架,需要為每個(gè)模型類單獨(dú)配置一個(gè)映射關(guān)系的XML,LitePal的所有映射都是自動(dòng)完成的。根據(jù)LitePal的數(shù)據(jù)類型支持,可以進(jìn)行對(duì)象關(guān)系映射的數(shù)據(jù)類型一共有8種,int、short、long、float、double、boolean、String和Date。只要是聲明成這8種數(shù)據(jù)類型的字段都會(huì)被自動(dòng)映射到數(shù)據(jù)庫表中,并不需要進(jìn)行任何額外的配置。既然是自動(dòng)映射的話,如果X類中有一個(gè)字符串字段并不想讓它映射到數(shù)據(jù)庫表中,這時(shí)候LitePal同樣采用了一種極為輕量的解決方案:只有聲明成private修飾符的字段才會(huì)被映射到數(shù)據(jù)庫表中,如果你有某一個(gè)字段不想映射的話,只需要將它改成public、protected或default修飾符就可以了。
    接著開始動(dòng)手創(chuàng)建基本表,比如我的基本表需要存儲(chǔ)Bean對(duì)象的數(shù)據(jù),那么創(chuàng)建Bean的java類把,最好把成員longid加上,注意這個(gè)對(duì)象必須繼承DataSupport。例子:
import org.litepal.crud.DataSupport;
/**
* litepalbean對(duì)象
*/
public class Bean extends DataSupport {
    private long id;
    private String name;
    public Bean() {
    }
    public Bean(String name, long id) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
}
       接著在項(xiàng)目的assets目錄(AndroidStudio中,assets目錄創(chuàng)建方法:把當(dāng)前空間從“Android”轉(zhuǎn)到“Project”,打開工程下面的“APP”目錄,選中“main”右擊新建文件夾“assets”),下面新建一個(gè)litepal.xml文件,并將以下的XML配置代碼代碼拷貝進(jìn)去。其中ShoppingCart標(biāo)簽是數(shù)據(jù)庫名,version是數(shù)據(jù)庫版本。list標(biāo)簽底下的mapping標(biāo)簽是表,也就是我們創(chuàng)建好的用于存儲(chǔ)Bean對(duì)象數(shù)據(jù)的表。
<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value="ShoppingCart"/>
    <version value="1"/>
    <list>
        <mapping class="com.nan.recycleviewdemo.bean.Bean"/>
    </list>
</litepal>
3,使用LitePal對(duì)基本表進(jìn)行基本操作(增刪改查)
       插入:下面的代碼是在筆記表中插入一條數(shù)據(jù)。LitePal操作數(shù)據(jù)是通過使用面型對(duì)象編程的,因此通過創(chuàng)建對(duì)象并且設(shè)置各個(gè)鍵的值就可以非常方便地插入一條新數(shù)據(jù)最后只需要調(diào)用save()方法保存到本地?cái)?shù)據(jù)庫就可以了。
Bean b = new Bean("new data ", id);
//添加數(shù)據(jù)需要調(diào)用保存方法
b.save();
   刪除:先得到我們的bean對(duì)象,然后調(diào)用DataSupport的方法進(jìn)行刪除。
//先得到我們的bean對(duì)象,然后調(diào)用DataSupport的方法進(jìn)行刪除
Bean bean = mDatas.get(position);
DataSupport.delete(Bean.class, bean.getId());
   修改:以筆記表為例,需要先判斷數(shù)據(jù)是否已經(jīng)保存過,如果是,就可以修改數(shù)據(jù)了,具體操作就是調(diào)用set()方法。最后保存一下就可以了。
if(bean.isSaved()) {
    bean.setName(.....);
    bean.save();
}
   
   查詢:通過DataSupportfind方法,通過ID查找我們的bean對(duì)象。
Bean b = DataSupport.find(Bean.class, id));


四、DataSupport的的重要方法以及使用注意點(diǎn)
       由上面的介紹知道,LitePal的很多數(shù)據(jù)庫操作都是通過DataSupport來進(jìn)行的,因此我們有必要去了解DataSupport這個(gè)類的一些常用而且重要方法(參數(shù)省略)。

//查找某一個(gè)bean對(duì)象
DataSupport.find();
//找出所有bean對(duì)象,返回List<Bean>
DataSupport.findAll();
//刪除一個(gè)bean對(duì)象
DataSupport.delete();
//刪除所有bean對(duì)象
DataSupport.deleteAll();
//求某一列的平均值
DataSupport.average();
//求所有數(shù)據(jù)的數(shù)量
DataSupport.count();
//排序
DataSupport.order();
//求某一列的的最小值的對(duì)象
DataSupport.min();
//求某一列的的最大值的對(duì)象
DataSupport.max();
//保存所有bean對(duì)象
DataSupport.saveAll();

       其中,最值得注意的是findAll()方法,他返回的是List<Bean對(duì)象>,因此需要我們?nèi)?qiáng)制轉(zhuǎn)換為ArrayList,不然在add等操作的時(shí)候會(huì)報(bào)錯(cuò),因?yàn)槲覀兪褂玫亩际?/font>List的子類而不是List對(duì)象本身。強(qiáng)轉(zhuǎn)可能Android Studio會(huì)提示沒有類型檢查的警告,但是我們可以忽略。

       好了今天的筆記到這里了,再賤ヾ( ̄▽ ̄)Bye~Bye~。


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表