关于litepal本来是不想看的, android本身对SQLite的封装已经很好了,感觉没必要在引入另外一个包来完成数据库操作。
可是,今天看了郭神的博客后,狠狠的鄙视了自己一把! 真是太容易满足了。。也庆幸自己今天看了看。这玩意有什么好的? 这么说吧, 看了litepal后我觉得我以后肯定很少用android原生的了。
首先献上litepal的下载地址(哈,我自己fork的):https://github.com/qibin0506/LitePal
下面分段开始我们的litepal之旅吧。
1、建表
数据库操作,上来肯定是要建表啊。虽然android原生的SQLiteOpenHelper很强大, 但还是得自己去写sql语句, 看看litepal是怎么搞定的:
找到你下载的litepal的downloads目录,将litepal-1.1.1-src.jar复制到你工程的libs目录, 这还没完,还需要小小的配置一下: 打开manifest文件给application节点配置“android:name="org.litepal.LitePalApplication"”。
既然是ORM框架,那肯定需要我们写几个实体类,实体类的类名对应数据库的表的名称,字段对应了数据库中的字段:
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;
}
}
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知道这两个类是要映射到数据中的。
在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("123456");
phone1.save();
Phone phone2 = new Phone();
phone2.setPerson(p);
phone2.setPhoneNumber("456789");
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", "newname");
DataSupport.update(Person.class, values, 1);
这段代码将id为1的person的name修改为newname,注意update方法是DataSupport中的一个静态方法。
3.2 使用ContentValues更新特定条件的数据:
ContentValues values = new ContentValues();
values.put("phoneNumber", "11111");
DataSupport.updateAll(Phone.class, values, "id>?", "1");
将id>1的phone的phonenumber修改为11111。
要修改全部数据:
DataSupport.updateAll(Phone.class, values);
不多说了, 一目了然。
如果不习惯使用ContentValues呢? 好办litepal还提供了更加方便的更新操作
3.3 优雅的更新特定id的数据
Phone updatePhone = new Phone();
updatePhone.setPhoneNumber("147852");
updatePhone.update(1);
这里调用对象上的update方法将id为1的phone的phonenumber更新为147852,这种方式是不是有一次震撼到你了? 我是在课堂上看到litepal, 反正当时我是笑出声来了。
3.4 优雅的更新特定条件的数据
Phone updatePhone = new Phone();
updatePhone.setPhoneNumber("256333");
updatePhone.updateAll("id>?", "2");
不多说了, 更新id>2的所有数据。注意一点是这里调用了updateAll方法
3.5 优雅的更新所有数据
Phone updatePhone = new Phone();
updatePhone.setPhoneNumber("111111");
updatePhone.updateAll();
额, 不想多说了, 肯定很清晰。
4、删除
现在你肯定也想到了删除操作是如何简单了吧, 不过我们还是贴一下吧。
int deleteCount = DataSupport.delete(Person.class, 1);
System.out.println(deleteCount);
删除id为1的person, 这里要多说几句了, 不就删除id是1的person么? 肯定就是1条啊, 获取count是多余的吧? 嘿嘿, 再次证明一下litepal的强大吧, 删除一条数据, litepal会把与该数据关联的其他表中的数据一并删除了,比如现在删除了id为1的Person, 那Phone表中属于Person的数据将全部被删除!! 毕竟那些成为垃圾数据了。
DataSupport.deleteAll(Person.class, "id>?", "1");
DataSupport.deleteAll(Person.class);
这是按条件删除,没什么好说的。
5、查询
sql语句中最复杂的就是查询了,尤其是多表联合查询(我可以说我现在都不会吗?),但是litepal做其他确是如此简单!!
5.1 震撼的级联操作
List<Phone> phones = DataSupport.where("id>?", "1").order("id").limit(3).find(Phone.class);
for(Phone p : phones) {
System.out.println(p.getPhoneNumber());
}
!!!!! 这不就在thinkphp中的级联吗!!!我曾经因为做了一个java的这种级联操作类而感到自豪。
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 震撼的枚举查询(枚举查询是我给它起的名,可能不太确切,说白了就是sql语句的in)
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());
}
同样注意注释了的那句话, 功能和前面的是一样的, 所有查询操作都会有这么一个重载的方法。
5.4 震撼的查询第一条数据
Phone phone = DataSupport.findFirst(Phone.class);
//DataSupport.findFirst(Phone.class, true); // 关联的表也会查询出来
System.out.println(phone.getPhoneNumber());
查询第一条数据,妈妈再也不用担心我写错order by limit了。
Phone phone = DataSupport.findLast(Phone.class, true);
//Phone p = DataSupport.findFirst(Phone.class, true);
System.out.println(phone.getPhoneNumber());
查询最后一条数据, 不说了, 和上面一样。
5.5 除此之外litepal还给我们提供了一个可以“自由发挥”的方法,也就是自己书写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();
好了,至此litepal的所有基本操作都说的差不多了, 应该很容易上手吧! 还得感谢郭神的博客,要么还真很难了解这么优秀的一款ORM框架。