Android room存储高级数据类型
比如一个项目的bean对象,有很多个坐标信息,通常服务器把他们当成数组传下来,我们客户端把他们放在List里面,用Gson很容易就解析出来了,一切都是如此完美。突然,要求把这些对象存储在本地数据库,这时候懵逼的发现数据库不支持List这个数据类型,那我们如何保存这种非基础数据类型呢?
{
"areaInfo": [
{
"longitude": 106.4621997480343,
"latitude": 29.510238334206996
},
{
"longitude": 106.45794048667334,
"latitude": 29.510538137429645
},
{
"longitude": 106.45197740193589,
"latitude": 29.50990225016947
}],
"projectTypeName": "路灯",
"projectId": "13",
"projectName": "智博会路灯",
}
一、初级做法
和服务器协议商定将数组转成string类型再传下来,我们直接把这个string存储起来即可。要用时候,再把这个string用Gson解析成List。
这么做显得很low。。。
二、高级做法
room大佬可能想到我们会有这些乱七八糟脑路清奇的想法,给我们提供了类型转换这一高级工具,让我们爱怎么折腾就怎么折腾。
- 现在,我们这个bean就要这样写了:
@Entity
public class BeanProject {
@PrimaryKey(autoGenerate = true)
public int _id;
public String address;
public String projectId;
public String projectName;
public List<AreaInfo> areaInfo;
public class AreaInfo {
public double longitude;
public double latitude;
}
}
由于这个坐标类过于简单,外部也用不上,我直接写成内部类。
- 定义转换器
public class AreaConverter {
@TypeConverter
public static List<BeanProject.AreaInfo> revert(String areaInfoStr) {
// 使用Gson方法把json格式的string转成List
try {
return JsonUtil.getReponseBeanList(new JSONArray(areaInfoStr), BeanProject.AreaInfo.class);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@TypeConverter
public static String converter(List<BeanProject.AreaInfo> areaInfoStr) {
// 使用Gson方法把List转成json格式的string,便于我们用的解析
return new Gson().toJson(areaInfoStr);
}
}
- 注解转换器
@TypeConverters注解,告知数据库要依赖哪些转换类
@Database(entities = {BeanProject.class}, version = 1)
@TypeConverters({AreaConverter.class})
public abstract class DbHic extends RoomDatabase {
public abstract DaoProject daoProject();
}
现在可以愉快的使用room给我们带来的便利了。
- 查看数据库中存储结果
我的android studio使用database navigator查看数据库这篇文章有写如何查看数据库。
可以看到,跟我们预想的一致,List被转换成string存储在本地数据库中。
其他存储方法
room有提供使用外键的方式来存储,但是我看了一下,非常的麻烦,这里不做推荐,有需要的可以参考这篇文章Android room 存储复杂数据类型