litepal为何物? 看github上的说明:
LitePal is an Open Source Android library that allows developers to use SQLite database extremely easy. You can finish most of the database operations without writing even a SQL statement, including create or upgrade tables, crud operations, aggregate functions, etc. The setup of LitePal is quite simple as well, you can integrate it into your project in less than 5 minutes.
关于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();
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());
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();