1、配置LitePal
导入LitePal的jar
dependencies { ... compile 'org.litepal.android:core:1.4.0' ... }
创建assets文件夹,并在文件夹下创建litepal.xml文件,此文件作为LitePal的配置文件。
litepal.xml的具体内容如下,其中bdname的Value为数据库名;version为数据库版本;表情中是需要创建的表名。
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="Teemo.db" ></dbname>
<version value="1" ></version>
<list>
</list>
</litepal>
- 配置Application,在项目中引用LitePalApplication或是创建自己的Application继承LitePalApplication.
2、建表
创建表所需要的Model
一张表对应一个模型(Model),例如:想创建一张User表,则有:
package com.teemo.example.database.model;
public class User extends org.litepal.crud.DataSupport {
...
}
表中的每个字段对应模型中的每个属性。例如:在User表中添加userName、id字段,则需要在User类中添加userName、id属性,两者是一一对应的。
package com.teemo.example.database.model;
public class User extends org.litepal.crud.DataSupport {
private int id;
private String name;
//自动生成get、set方法
...
}
- 在数据库配置文件中配置表
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="Teemo.db" ></dbname>
<version value="1" ></version>
<list>
<mapping class="com.teemo.example.database.model.User"/>
</list>
</litepal>
根据LitePal的数据类型支持,可以进行对象关系映射的数据类型一共有8种,int、short、long、float、double、boolean、String和Date。只要是声明成这8种数据类型的字段都会被自动映射到数据库表中,并不需要进行任何额外的配置。
3、使用LitePal升级数据库
添加新表 MessageInfo
创建MessageInfo的Model类
package com.teemo.example.database.model;
public class MessageInfo extends org.litepal.crud.DataSupport {
private int id;
private String userName;
private String msgContent;
//自动生成get、set方法
...
}
将MessageInfo配置到数据库配置文件中,并新增数据库版本号
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="Teemo.db" ></dbname>
<version value="2" ></version>
<list>
<mapping class="com.teemo.example.database.model.User"/>
<mapping class="com.teemo.example.database.model.MessageInfo"/>
</list>
</litepal>
- 修改表中的字段:
修改表中的字段只需要修改Model中的属性,并将数据库的版本号加1即可,例如:在MessageInfo表中添加字段senderNumber。
package com.teemo.example.database.model;
public class MessageInfo extends org.litepal.crud.DataSupport {
private int id;
private String userName;
private String msgContent;
private String senderNumber;
//自动生成get、set方法
...
}
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="Teemo.db" ></dbname>
<version value="3" ></version>
<list>
<mapping class="com.teemo.example.database.model.User"/>
<mapping class="com.teemo.example.database.model.MessageInfo"/>
</list>
</litepal>
>注: SQLite中是不支持表删除字段的,不过在LitePal中可以做到,原理是先将表重命名为temp表,然后根据新的配置文件创建新表,再将temp表中的数据移到新表中,同时删除temp表。
4、使用LitePal创建关联表
>创建关联表:一对一关联的实现方式是用外键,多对一关联的实现方式同样是外键,多对多关联的实现方式是用中间表。
- 创建一对多表,一个User会有多条MessageInfo,所以User和MessageInfo是多对一的形式;可以对上述User、MessageInfo类做如下修改:
package com.teemo.example.database.model;
public class User extends org.litepal.crud.DataSupport {
private List<MessageInfo> msgInfoList = new ArrayList<MessageInfo>();
//自动生成get、set方法
...
}
package com.teemo.example.database.model;
public class MessageInfo extends org.litepal.crud.DataSupport {
private User user;
//自动生成get、set方法
...
}
- 为了实现多对多的关系,建立Market表,一个Market可以在多个MessageInfo中出现,一个MessageInfo中可以包含多个Market,那么Market和MessageInfo就是多对多的方式。
package com.teemo.example.database.model;
public class Market extends org.litepal.crud.DataSupport {
private List<MessageInfo> msgInfoList = new ArrayList<MessageInfo>();
//自动生成get、set方法
...
}
package com.teemo.example.database.model;
public class MessageInfo extends org.litepal.crud.DataSupport {
private User user;
private List<Market> msgInfoList = new ArrayList<Market>();
//自动生成get、set方法
...
}
此时Market表和MessageInfo表就是多对多的关系。
5、使用LitePal进行插入数据:
litepal插入数据时需要Model继承了DataSupport接口才能使用LitePal的CRUD操作。
例如想插入一条User数据:
User user = new User();
user.setName("Teemo");
user.save();
save()方法有返回值,能够表明插入操作是否成:
if(user.save())
Toast.show(context, "存储成功", Toast.LENGTH_SHORT).show();
else
Toast.show(context, "存储失败", Toast.LENGTH_SHORT).show();
同时可以采用user.saveThrows();来为插入失败时抛出异常。和SQLite的Insert方法一样,save()同样可以得到返回的ID
User user = new User();
user.setName();
Log.d(TAG, "user's id is " + user.getId());
user.sava();
Log.d(TAG, "user's id is " + user.getId());
想在User表中插入多条MessageInfo,可以如下所示:
MessageInfo msgInfo1 = new MessageInfo();
msgInfo1.setUserName("Tom");
msgInfo1.serMsgContent("Hello Tom");
msgInfo.save();
MessageInfo msgInfo2 = new MessageInfo();
msgInfo2.setUserName("Peter");
msgInfo2.setMsgContent("Hello Peter");
msgInfo2.save();
User user = new User();
user.getMsgInfoList().add(msgInfo1);
user.getMsgInfoList().add(msgInfo2);
user.setName("Teemo");
user.save();
- 如果想插入一个User集合,可以有:
List<News> newsList;
...
DataSupport.saveAll(newsList);
6、使用LitePal修改数据
比如我们想将User表中的id为1的记录的名称改为Tom:
ContentValues values = new ContentValues();
values.put("name", "Tom");
DataSupport.update(User.class, values, 1);
如果想修改某条件下所有的数据,而不是单指的id,则可以使用如下的命令:
DataSupport.updateAll(Class<?> modelClass, ContentValues values, String conditions)
第三个参数是一个conditions数组,用于指定修改哪些行的约束条件,返回值表示此次修改影响了多少行数据。
比如我们想将User表中所有叫Teemo的name换成Tom,则有:
ContentValues value = new ContentValues();
value.put("name", "Tom");
DataSupport.updateAll(User.class, value, "name = ?", "Toom");
其中”Teemo”代表?占位符,一个占位符需要一个字符串对应。
如果我们想将User中所有项的name换成Tom,则有:
ContentValues value = new ContentValues();
value.put("name", "Tom");
DataSupport.updateAll(User.class, value);
如果想将User中的name换成默认名,则有:
ContentValues value = new ContentValues();
value.setToDefault("name");
DataSupport.updateAll();
7、使用LitePal删除表中的某一项
具体方法如下:
public static int delete(Class<?> modelClass, long id);
比如说想删除User的第一项:
DataSupport.delete(User.class, 1);
需要注意的是,这不仅仅会将User表中id为1的记录删除了,同时还会降其他表中以User id为1的这条记录作为外键的数据一起删掉,因为外键既然不存在了,那么这数据也就没有保留的必要。
除了删除制定id的数据之外,DataSupport中也提供了一个通过Where语句来批量删除数据的方法:
public static int deleteAll(Class<?> modelClass, String... conditions);
比如想将User中name为Teemo的删掉,则可这样写:
DataSupport.deleteAll(User.class, "name = ?", "Teemo");
如果想将User中所有记录删除,则可有:
DataSupport.deleteAll(User.class);
8、使用Litepal查找数据:
比如想查询User的第一条记录:
User user = DataSupport.find(User.class, 1);
同时,LitePal还支持findFirst、findLast操作,使用方法和find同样。
如果我们想找第1、3、5项记录:
List<User> users = DataSupport.findAll(User.class, 1, 3, 5);
也可以
long ids[] = new long[] {1, 3, 5};
List<User> users = DataSupport.findAll(User.class, ids);
- 连缀查询
如果我们想查询所有id > 5的记录:
List<User> userList = DataSupport.where("id > ?", "5").find(User.class);
这样我们将User中所有字段都查找出来了,如果我们只想要User中的name属性,则可以有:
List<User> userList = DataSupport.select("name")
.where("id > ?", "5")
.find(User.class);
如果我们想将查询的数据按照id的大小进行排名,则可以有:
List<User> userList = DataSupport.select("name")
.where("id > ?", "5")
.order("id desc")
.find(User.class);
在表中可能存在很多的User,我们并不想将其全部查出来,只想找出前面的10项,则有:
List<User> userList = DataSupport.select("name")
.where("id > ?", "5")
.order("id desc")
.limit(10)
.find(User.class);
上面我们查询的是所有匹配条件的前10条数据,现在我们想将User进行分页展示,翻到第二页时,展示第11到20的User,则有:
List<User> userList = DataSupport.select("name")
.where("id > ?", "5")
.order("id desc")
.limit(10)
.offset(10)
.find(User.class);
- 关键词查询
例如在搜索的时候,当输入关键字时,根据关键词进行查询
List<User> userList = DataSupport.select("*")
.where("name like ?", "%T%")
.find(User.class);
查出来的结果是name字段包含T的所有User。
SQL通配符
- 激进查询:
激进查询能够将表中关联的数据一起查找出来
在每个find方法中都有一个带isEager的重构方法,使用这种方法时,并传入true就代表激进查询。但是激进查询在LitePal中不推荐。
不推荐那么可以对表进行稍微修改就可以做到:
package com.teemo.example.database.model:
public class User extends org.litepal.DataSupport {
private List<MessageInfo> msgInfos;
public List<MessageInfo> getMsgInfos() {
return DataSupport.where("user_id = ?", String.valueOf(id)).find(MessageInfo.class);
}
}
9、Litepal的聚合函数
LitePal中一共提供了count()、sum()、average()、max()和min()这五种聚合函数,基本上已经将SQL语句当中最常用的几种聚合函数都覆盖了
- Count()
如果想统计User表中有多少记录:
int count = DataSupport.count(User.class);
聚合函数还支持连缀,也就是说我们在进行统计的时候还可以加入条件语句:
int count = DataSupport.where("name = ?", "Teemo").count(User.class);
- Sum()
sum()方法主要是用于对结果进行求合的,比如说我们想要统计User表中Message的总数量,就可以这样写:
int sum = DataSupport.sum(User.class, "msgCount", int.class);
sum()方法的参数要稍微多一点,我们来一一看下。第一个参数很简单,还是传入的Class,用于指定去统计哪张表当中的数据。第二个参数是列名,表示我们希望对哪一个列中的数据进行求合。第三个参数用于指定结果的类型,这里我们指定成int型,因此返回结果也是int型。
需要注意的是,sum()方法只能对具有运算能力的列进行求合,比如说整型列或者浮点型列,如果你传入一个字符串类型的列去求合,肯定是得不到任何结果的,这时只会返回一个0作为结果。
- average()
average()方法主要是用于统计平均数的,比如说我们想要统计User表中平均每个人有多少信息,就可以这样写:
double result = DataSupport.average(User.class, "msgCount");
同样地,average()方法也只能对具有运算能力的列进行求平均值,如果你传入了一个字符串类型的列,也是无法得到任何结果的,这时同样只会返回一个0作为结果。
- max()
max()方法主要用于求出某个列中最大的数值,比如我们想要知道User表中所有人中消息最多的是多少,就可以这样写:
int max = DataSupport.max(User.class, "msgCount", int.class);
- min()
min()方法主要用于求出某个列中最小的数值,比如我们想要知道User表中所有人中消息最少的是多少,就可以这样写:
int min = DataSupport.min(User.class, "msgCount", int.class);