一、首先,找到你下載的litepal。jar,將litepal-1.1.1-src.jar複製到你工程的libs目錄, 這還沒完, 配置LitePalApplication由於操作數據庫時需要用到Context,而我們顯然不希望在每個接口中都去傳一遍這個參數,那樣操作數據庫就顯得太繁瑣了。因此,LitePal使用了一個方法來簡化掉Context這個參數,只需要在AndroidManifest.xml中配置一下LitePalApplication,所有的數據庫操作就都不用再傳Context了,如下所示:
<manifest>
<application
android:name="org.litepal.LitePalApplication"
...
>
...
</application>
</manifest>
有時候有些程序可能會有自己的Application,並在這裏配置過了。比如說有一個MyApplication,如下所示:<manifest>
<application
android:name="com.example.MyApplication"
...
>
...
</application>
</manifest>
這時只需要修改一下MyApplication的繼承結構,讓它不要直接繼承Application類,而是繼承LitePalApplication類,就可以使用一切都能正常工作了,代碼如下所示:public class MyApplication extends LitePalApplication {
...
}
但是有些程序可能會遇到一些更加極端的情況,比如說MyApplication需要繼承另外一個AnotherApplication,並且這個AnotherApplication還是在jar包當中的,不能修改它的代碼。這種情況應該算是比較少見了,但是如果你遇到了的話也不用急,仍然是有解釋方案的。你可以把LitePal的源碼下載下來,然後把src目錄下的所有代碼直接拷貝到你項目的src目錄下面,接着打開LitePalApplication類,將它的繼承結構改成繼承自AnotherApplication,再讓MyApplication繼承自LitePalApplication,這樣所有的Application就都可以在一起正常工作了。二、既然是ORM框架,那肯定需要我們寫幾個實體類,實體類的類名對應數據庫的表的名稱,字段對應了數據庫中的字段,只有聲明爲private的纔會被映射到數據庫,public和protect的都不會被映射到數據庫:
Person實體類:
public class Person extends DataSupport {
private int id;
private String name;
private String gender;
private List<Phone> phones = new ArrayList<Phone>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public List<Phone> getPhones() {
return phones;
}
public void setPhones(List<Phone> phones) {
this.phones = phones;
}
}
Phone實體類:
public class Phone extends DataSupport {
private int id;
private String phoneNumber;
private Person person;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
兩個實體類, 說明一下: (1) Person中有個List<Phone>和Phone中有個Person表示Person和Phone是1:n的關係, 用litepal就是這麼簡單的,很輕鬆的就搞定了表之間的關係,廢話一句:我可以說我之前很少用關聯表嘛。。。
(2) 實體類繼承了DataSupport, 這個類是LitePal中的一個類, 後面它會給我們帶來驚喜。
很輕鬆的搞定了兩個實體類,而且註明了之間的關係,接下來還需要一個xml文件來聲明它們,要讓litepal知道這兩個類是要映射到數據中的。
1.創建表:
在assert目錄創建litepal.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="easydb" />
<version value="1" />
<list>
<mapping class="org.loader.litepaltest1.Phone" />
<mapping class="org.loader.litepaltest1.Person" />
</list>
</litepal>
在這裏簡單的說明一下:dbname是指定數據庫名稱,這裏不需要加.db哦。 version不用想也知道是指定數據庫的版本了(那是不是以後修改數據庫版本只要該這個值就可以了? 嘿嘿, 必須就是這麼簡單),還有個list,list節點下有兩個mapping仔細觀察原來是聲明的我們剛開始建立的那兩個實體類。好了,建表這一步就完成了, 只要你的代碼有數據庫操作, 建表就會自動完成。
2、插入數據
表建立完了, 下一步當然是插入數據了, 馬上就會就會使用到litepal。
Person p = new Person();
p.setName("person1");
p.setGender("male");
p.save();
Phone phone1 = new Phone();
phone1.setPerson(p);
phone1.setPhoneNumber("66666");
phone1.save();
Phone phone2 = new Phone();
phone2.setPerson(p);
phone2.setPhoneNumber("88888");
phone2.save();
現在我們已經向Person表中插入了一條數據, 向phone表中插入了2條數據,phone表中的2條數據和person表中那條數據是用對應關係的。如此簡單的操作,就是實現了insert操作,但還是要注意一下set完數據別忘了save()一把,save()方法就是來自於我們實體類繼承自DataSupport。
3、更新
更新也很簡單。
3.1 使用ContentValues更新特定id的數據:
ContentValues values = new ContentValues();
values.put("name", "zhangsan");
DataSupport.update(Person.class, values, 1);
這段代碼將id爲1的person的name修改爲zhangsan,注意update方法是DataSupport中的一個靜態方法。
3.2 使用ContentValues更新特定條件的數據:
ContentValues values = new ContentValues();
values.put("phoneNumber", "55555");
DataSupport.updateAll(Phone.class, values, "id>?", "1");
將id>1的phone的phonenumber修改爲55555。要修改全部數據:
DataSupport.updateAll(Phone.class, values);
Phone updatePhone = new Phone();
updatePhone.setPhoneNumber("11111");
updatePhone.update(1);
這裏調用對象上的update方法將id爲1的phone的phonenumber更新爲11111.
3.4 更新特定條件的數據
Phone updatePhone = new Phone();
updatePhone.setPhoneNumber("256333");
updatePhone.updateAll("id>?", "2");
此處更新id>2的所有數據。這裏調用了updateAll方法
Phone updatePhone = new Phone();
updatePhone.setPhoneNumber("77777");
updatePhone.updateAll();
int Count = DataSupport.delete(Person.class, 1);
System.out.println(Count);//獲得刪除的條數
刪除id爲1的person,刪除一條數據, litepal會把與該數據關聯的其他表中的數據全部刪除,比如現在刪除了id爲1的Person, 那Phone表中屬於Person的數據將全部被刪除。
DataSupport.deleteAll(Person.class, "id>?", "1");
DataSupport.deleteAll(Person.class);//刪除id>1的person信息
5、查詢
5.1 級聯操作
List<Phone> phones = DataSupport.select("name","gender").where("id>?", "1").order("id asc").limit(3).find(Phone.class);
for(Phone p : phones) {
System.out.println(p.getPhoneNumber());
}
查詢Phone類中id>1的name和gender並且按id來排列的,order()方法中接收一個字符串參數,用於指定查詢出的結果按照哪一列進行排序,asc表示正序排序,desc表示倒序排序,因此order()方法對應了一條SQL語句中的order by部分,limit()方法,這個方法接收一個整型參數,用於指定查詢前幾條數據.
剛纔我們查詢到的是所有匹配條件的前10條電話號碼,那麼現在我想對電話號碼進行分頁展示,翻到第二頁時,展示第11到第20條電話號碼,只需要再連綴一個偏移量就可以了,如下所示:
List<Phone> phoneList = DataSupport.select("name", "gender")
.where("phonecount > ?", "0")
.order("id desc").limit(10).offset(10)
.find(Person.class);
5.2 查詢特定id的數據
Phone p = DataSupport.find(Phone.class, 3);
//DataSupport.find(Phone.class, 3, true); // 關聯的表也會查詢出來
System.out.println(p.getPhoneNumber());
注意註釋了的那句話,第三個參數如果設爲true,則關聯的表的數據也會被查詢出來,通過p.getPerson().getName()獲得相關數據。
5.3 使用枚舉進行查詢
List<Phone> phones = DataSupport.findAll(Phone.class, 3, 4);
//DataSupport.findAll(Phone.class,, true, 3, 4); // 關聯的表也會查詢出來
for(Phone p : phones) {
System.out.println(p.getPhoneNumber());
}
或者:
long[] ids = new long[] { 1, 3, 5, 7 };
List<Phone> newsList = DataSupport.findAll(Phone.class, ids);
5.4 查詢第一條和最後一條數據
Phone phone = DataSupport.findFirst(Phone.class);
//DataSupport.findFirst(Phone.class, true); // 關聯的表也會查詢出來
System.out.println(phone.getPhoneNumber());
Phone phone = DataSupport.findLast(Phone.class, true);
//Phone p = DataSupport.findFirst(Phone.class, true);
System.out.println(phone.getPhoneNumber());
5.5使用sql語句進行查詢
Cursor cursor = DataSupport.findBySQL("select * from phone where id=?","3");
for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()) {
System.out.println(cursor.getString(cursor.getColumnIndex("phonenumber")));
}
cursor.close();
5.6激進查詢
查詢iPhones表中id爲1的人,並且把這個人對應的電話也一起查詢出來,就可以這樣寫:
Person persons = DataSupport.find(Person.class, 1, true);
List<Phone> phoneList = news.getPhoneList();
激進查詢只能查詢出指定表的關聯表數據,但是沒法繼續迭代查詢關聯表的關聯表數據。因此,這裏我們還是使用默認的懶加載更加合適,至於如何查詢出關聯表中的數據,其實只需要在模型類中做一點小修改就可以:
public class Person extends DataSupport{
...
public List<Phone> getPhones() {
return DataSupport.where("news_id = ?", String.valueOf(id)).find(Phone.class);
}
}
可以看到,我們在Person類中添加了一個getPhones()方法,而這個方法的內部就是使用了一句連綴查詢,查出了當前這個人對應的所有電話。改成這種寫法之後,我們就可以將關聯表數據的查詢延遲,當我們需要去獲取這個人對應的電話時,再去調用Person的getPhones()方法,這時纔會去查詢關聯數據。這種寫法會比激進查詢更加高效也更加合理。
LitePal聚合函數的使用:
LitePal中一共提供了count()、sum()、average()、max()和min()這五種聚合函數,下面我們 來學習一下這五種函數:
1.用來統計行數的count()函數:
int result = DataSupport.count(Phone.class);
count()方法接收一個Class參數,用於指定去統計哪張表當中的數據,然後返回值是一個整型數據,也就是統計出的結果了。LitePal中所有的聚合函數都是支持連綴的,也就是說我們可以在統計的時候加入條件語句。比如說想要統計id=0的人一共有多少個電話號碼,就可以這樣寫:
int result = DataSupport.where("id = ?", "0").count(Phone.class);
2.對數據進行求和的sum()函數:
int result = DataSupport.sum(Phone.class, "phonenumber", int.class);
第一個參數很簡單,還是傳入的Class,用於指定去統計哪張表當中的數據。第二個參數是列名,表示我們希望對哪一個列中的數據進行求合。第三個參數用於指定結果的類型,這裏我們指定成int型,因此返回結果也是int型。需要注意的是,sum()方法只能對具有運算能力的列進行求合,比如說整型列或者浮點型列,如果你傳入一個字符串類型的列去求合,肯定是得不到任何結果的,這時只會返回一個0作爲結果。
3.用於統計平均數的average()函數:
double result = DataSupport.average(Person.class, "Phonenumber");
求每一個Person平均有幾個電話號碼
average()方法接收兩個參數,第一個參數不用說,仍然是Class。第二個參數用於指定列名的,表示我們想要統計哪一列的平均數。需要注意的是,這裏返回值的類型是double型,因爲平均數基本上都是會帶有小數的,用double類型可以最大程序保留小數位的精度。4.求最大值max()函數
<pre name="code" class="java">int result = DataSupport.max(Person.class, "Phonenumber", int.class);
求哪個人的電話號碼最多。5.求最小值min()函數
int result = DataSupport.min(Person.class, "Phonenumber", int.class);
求哪個人得到電話號碼最少。