LitePal详解

来源:互联网 发布:走近科学 知乎 编辑:程序博客网 时间:2024/05/29 08:15

一、首先,找到你下载的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);


3.3 更新特定id的数据

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方法


3.5 更新所有数据
Phone updatePhone = new Phone();updatePhone.setPhoneNumber("77777");updatePhone.updateAll();


4、删除

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); 
求哪个人得到电话号码最少。




LitePal.jar下载。















0 0
原创粉丝点击