LitePal是郭神写的一个框架,这里再次致敬下郭神,真大神也。
这篇主要讲的是LitePal的一些简单使用方式并提供源码。
具体的机制方面还是要到郭神的博客中去了解。
地址在这:http://blog.csdn.net/guolin_blog/article/details/38083103
由于Android内置了轻量级关系型数据库SQLite,所以有一定MySQL或者SQLite使用经验的人会感觉到轻车熟路。但对于此前没接触过SQL的人来说,还是会有点困难的,但基本的建表命令以及增删改查还是要熟练掌握的。
这是要说一下ADB(Android Debug Bridge),顾名思义就是一个桥梁作用,使用linux的ls命令去查看Android系统的根目录,会发现目录下的一些表。用adb shell命令可以向手机写入文件或者是从手机中获取文件,一般开发者可以用Linux下的Grep来过滤结果查看Log,输出已安装的应用,模拟键盘输入或滑动输入等等。而这些ADB命令的来源在哪呢。这里提供一个源代码网站:
http://www.androidxref.com
adb命令和shell命令就是来源于\system\core\toolbox和\frameworks\base\cmds中。
扯远了,回归正题。为什么会使用LitePal呢,因为它很简单,使用方便,用郭神的话说就是:
LitePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平时开发时最常用到的一些数据库功能进行了封装,使得不用编写一行SQL语句就可以完成各种建表、増删改查的操作。并且LitePal很“轻”,jar包只有100k不到,而且近乎零配置,这一点和Hibernate这类的框架有很大区别。目前LitePal的源码已经托管到了GitHub上,地址是 https://github.com/LitePalFramework/LitePal 。
现在我们就来看看它怎么个简单法,因为它使用了ORM的思想,将面向对象的操作方式来操作数据库,就是这样的。
配置的东西就不多说了,现在来了解下主要的操作:
(一)建表
public class News {
private int id;
//private的才会映射到数据库表中,如果某个字段不想被映射,就需要改成public或者protected或default修饰符。比如title不想被映射就像下面这个定义。
public String title;
private String content;
private Date publishDate;
private int commentCount;
// 自动生成get、set方法
...
}
此时只要对数据库有任何操作,News表就会自动建立。
(二)升级表
有News表后,需要再添加一个评论Comment表进行升级怎么办呢,在配置文件中搞定,原来的Version是1,每次升级只要把版本号+1就可以了,并在list中加入这张表。
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="demo" ></dbname>
<version value="2" ></version>
<list>
<mapping class="com.example.databasetest.model.News"></mapping>
<mapping class="com.example.databasetest.model.Comment"></mapping>
</list>
</litepal>
(三)表的关联
表的关联主要是有几种形式: 一对一,一对多,多对多。主要处理的就是外键的关系。
一对一比较简单,外键放在哪张表上都可以。数据库表中多对一的关系仍然是通过外键来建立的,多对一的时候关键必须要加在多方的表中。
多对多的情况比较特殊,不是通过外键来实现的,而是通过中间表来实现 。中间表存放两方的外键建立关联。
在LitePal中一切的关联都变得更简单,一对一就在相应的类中增加对方的字段,一对多就增加一个List,多对多也是增加List。
public class News {
...
private Introduction introduction;
private List<Comment> commentList = new ArrayList<Comment>();
private List<Category> categoryList = new ArrayList<Category>();
// 自动生成get、set方法
}
public class Comment {
...
private News news;
// 自动生成get、set方法
}
public class Category {
...
private List<News> newsList = new ArrayList<News>();
// 自动生成get、set方法
}
这里郭神举了几个例子,一条新闻对应一个介绍,对应多个评论,新闻与分类是多对多关系,是不是特别直观呢?
(四)存储操作
每个实体类,如果要进行CRUD操作,LitePal要求所有的实体类都要继承自DataSupport这个类。
public class News extends DataSupport{
......
// 自动生成get、set方法
}
具体使用就是几个重要的方法 save( ),saveAll( )等等
Comment comment1 = new Comment();
comment1.setContent("好评!");
comment1.setPublishDate(new Date());
comment1.save();
Comment comment2 = new Comment();
comment2.setContent("赞一个");
comment2.setPublishDate(new Date());
comment2.save();
News news = new News();
news.getCommentList().add(comment1);
news.getCommentList().add(comment2);
news.setTitle("第二条新闻标题");
news.setContent("第二条新闻内容");
news.setPublishDate(new Date());
news.setCommentCount(news.getCommentList().size());
news.save();
这里添加了两个评论,一个新闻,多对一关系。set,get方法,最后就save保存就可以了。
(五)修改和删除操作
修改的话还是比较简单的
ContentValues values = new ContentValues();
values.put("title", "今日iPhone6发布");
DataSupport.update(News.class, values, 2);
如果是要修改条件下多个id,就可以这么写:
ContentValues values = new ContentValues();
values.put("title", "今日iPhone6 Plus发布");
DataSupport.updateAll(News.class, values, "title = ? and commentcount > ?", "今日iPhone6发布", "0");
其中的updateAll的定义是这样的
public static int updateAll(Class<?> modelClass, ContentValues values, String... conditions)
都是传入一个class,然后写ContentValue,最后是根据条件去查询行数据。
如果不想写ContentValue的话,也可以考虑另外一种实现方式:
News updateNews = new News();
updateNews.setTitle("今日iPhone6发布");
updateNews.updateAll("title = ? and commentcount > ?", "今日iPhone6发布", "0");
直接new出一个对象,调用set方法,并updateAll或update(id)
关于删除操作,也是比较简洁的:
DataSupport.delete(News.class, id);
DataSupport.deleteAll(News.class, "title = ? and commentcount = ?", "今日iPhone6发布", "0");
注意删除某个id,会同时删除以这个id为外键的其它表中的数据。
另外一种方式则是实例通过delete方法来实现,但这个实例一定要是持久化过的,比如save以后的。
News news = new News();
news.setTitle("这是一条新闻标题");
news.setContent("这是一条新闻内容");
news.save();
...
news.delete();
(六)查询操作
查询某个id
News news = DataSupport.find(News.class, 1);
查询第一条和最后一条数据
News firstNews = DataSupport.findFirst(News.class);
News lastNews = DataSupport.findLast(News.class);
同时也支持数组传入数组
long[] ids = new long[] { 1, 3, 5, 7 };
List<News> newsList = DataSupport.findAll(News.class, ids);
最有特色的应该是连缀查询了
如查询一整个表
List<News> newsList = DataSupport.where("commentcount > ?", "0").find(News.class);
查询表中符合条件的两列数据
List<News> newsList = DataSupport.select("title", "content")
.where("commentcount > ?", "0").find(News.class);
查询前10条数据,按发布日期降序
List<News> newsList = DataSupport.select("title", "content")
.where("commentcount > ?", "0")
.order("publishdate desc").limit(10).find(News.class);
到这里数据库所有的操作基本上都包含了,这里只是做一个复习,郭神的博客有更多更详细的用法。
接下来,就要开始去写一个实例,来使用这个框架和上述操作了。