Android的LitePal数据库ORM使用总结(避坑指南)

简介: Android的LitePal数据库ORM使用总结(避坑指南)

LitePal是Android《第一行代码》作者郭神的开源ORM框架,一个很好用的ORM。


虽然好用,但是如果不加注意,会遇到很多坑。所谓坑,并不是说框架不好,只是说有一些细节注意不到可能会犯错。


这不是bug,但是教程也好,示例demo中也罢,很少有提到,只能在使用过程中一一总结了。


以下总结自己使用中遇到的问题,逐步完善。


先介绍下简单使用:


app目录下的build.gradle中增加依赖:


//litepal数据库ORM
implementation 'org.litepal.guolindev:core:3.2.3'


在assets文件夹下创建一个相应的litepal.xml文件夹::


<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value="testdb"/>
    <version value="1"/>
    <list>
        <mapping class="com.test.model.User"/>
    </list>
   <storage value="mydir" />
</litepal>


在Application的onCreate中,增加初始化:LitePal.initialize(this);引入完毕。


问题一:


默认的数据库存储位置问题,可在litepal.xml文件中指定storage value="external"或者 "internal",默认是internal,文件浏览器查看是不可见或无权限的。external则在Android/data/目录下能找到数据库文件。但是,无论设置为哪种,只要应用卸载,数据库就跟着清除掉了。


如何能够持久保留数据库文件,不受是否卸载的影响呢?也简单,改下storage即可。


如:storage value="mydir" ,就会在根目录下的mydir目录下找到数据库文件。但前提是这个mydir已经提前创建好吧,若未创建会怎样,试下就知道。


问题二:


多表关联问题,关联的表无法存入数据。


这里有个隐藏的秘密,很难发现。建立一对一关联或一对多关联后,首先你要记得把关联表的数据save!!并不是你直接把数据set赋值之后,关联表就有数据了。set只是给两个表建立关联的。并且,除了save外,那个set也一样不能漏,否则你会看到关联的表里那个外键字段内容为空。


正解如:


News news=new News();
        news.setTitle("这是一条新闻标题");
        news.setContent("这是一条新闻内容");
        news.setPublishDate(new Date());
        Introduction introduction=new Introduction();
        introduction.setGuide("这是新闻导语");
        introduction.setDigest("这是新闻摘要");
        news.setIntroduction(introduction);//只是建立关联
        introduction.save();//重点
        news.save();


问题三:


有多表关联的实体,查询时查出来的关联的表内容为空。


比如定义了一个实体,内部还关联了其他实体类。查询时如果不加注意,只能查到本实体的内容,关联的实体查到的为空。


举例如:


public  class OrderDishTransdtlRecord extends LitePalSupport {
    @Column(nullable = false)
    private String billno;// 点餐单号
    @Nullable
    private String goodsid;//菜品编号 char(16)
    @Nullable
    private String typename; //菜品类别名称
    private int orderno;// 每笔订单菜品序列号
    private int price;
    private int qty;
    @Column(ignore = true)
    private List<OrderComboFoodRecord> comboFoods;// 套餐详情,不存数据库
    private  List<OrderDishTransdtlRecord> dtlList;// 细节  关联OrderDishDtlRecord
.....
}


如果只是想当然的  LitePal.find(OrderTransdtlRecord.class,10),这样查到的dtlList为null,没有数据。而应该如下写法:


 OrderTransdtlRecord recc = LitePal.find(OrderTransdtlRecord.class,10,true);//重点,第三个参数必须有,且为true
 Log.d(TAG,recc.toString());


问题四:


删除一条记录,关联的表里内容本该跟着删除的,但是数据还在,删除不掉的问题。如:


 OrderTransdtlRecord recc = LitePal.find(OrderTransdtlRecord.class,10);
 recc.delete();


这样是删不掉OrderTransdtlRecord的关联表OrderDishTransdtlRecord中的数据的。原因跟上个类似,这里的查询没增加第三个参数,isEager:True to load the associated models, false not.加上第三个参数,查询成功后,再删除,这样关联表才会跟着删除。或者使用这种方式,LitePal.delete(OrderTransdtlRecord.class,18),关联表会跟着删除。


或者使用这种方式,关联的表也会随之删除:


LitePal.deleteAll(OrderTransdtlRecord.class,"id = ? ","19");


问题五:


LitePal中不支持枚举类型。如果你的model里使用了枚举类型,在生成的表结构里枚举类型的字段会被忽略。


常用的类型如String和int,long可以放心用,其他类型需做好测试,不能想当然。


LitePal支持的数据类型有8种,分别为:int、short、long、float、double、boolean、String和Date。其他不支持的如枚举,会被忽略。


并且,如果里面使用了表关联,需在litpal.xml中注册,否则,也会被忽略,而非生成关联的表结构。


在进行boolean类型操作的时候也需要注意。对于LitePal数据库,存储boolean值为true的时候可以直接用LitePal存储对象的方式存储,若存储的对象中boolean为false,需要调用setToDefault(String name)方法存储,其中参数name为对象中Boolean属性的名称,为字符串boolean值其实是以0和1的方式存到数据库中的,true=1,false=0,所以在查询的时候需要注意。


问题六:


LitePal数据库的操作,默认是在主线程中的,使用时需注意自己处理线程和异步问题。


虽然之前版本LitePal提供的有异步操作api,但是作者说了,尽量少用。后续版本可能废弃不再维护。推荐应用开发者自己处理异步问题,如使用RxJava异步库。


问题七:


LitePal不能更改数据库表名和字段名。默认的表名就是定义的实体类的类名,且都为小写,字段名都是实体类中定义的属性的小写。


问题八:


LitePal不支持自定义主键,默认的主键为id,不管一个实体类对象有没有设置id字段,数据库的表中都会创建一个id的主键,而这个id的值会在新记录插入时被自动置为表中的Id,也即是唯一值。如果你里面定义了个String id,运行会报错的。


问题九:


升级表结构时要格外注意,以防历史数据被清空。以下一些升级情况LitePal无法处理并且被升级表格里的所有数据将被清空:


添加了一个标注为 unique = true 的属性;


修改某个属性的标注为 unique = true;


修改某个属性的标注为 nullable = false;


以上情况会导致数据丢失,要格外注意。


相关文章
|
23天前
|
SQL 关系型数据库 MySQL
探索Gorm - Golang流行的数据库ORM框架
探索Gorm - Golang流行的数据库ORM框架
|
23天前
|
SQL 缓存 安全
Android ORM 框架之 greenDAO
Android ORM 框架之 greenDAO
44 0
|
23天前
|
网络协议 关系型数据库 MySQL
如何实现无公网ip远程访问本地安卓Termux部署的MySQL数据库【内网穿透】
如何实现无公网ip远程访问本地安卓Termux部署的MySQL数据库【内网穿透】
|
2天前
|
API 数据库 数据库管理
Flask Web开发基础:数据库与ORM实战
该文介绍了如何使用 Flask、SQLAlchemy 和 SQLite 实现数据库操作。首先,通过创建虚拟环境和安装 flask-sqlalchemy(版本2.5.1)及 sqlalchemy(版本1.4.47)来设置环境。接着,配置数据库URI,定义User和Movie模型类表示数据库表,并通过db.create_all()创建表。文章还展示了如何插入、查询、更新和删除记录,强调了db.session.commit()在保存更改中的关键作用。查询涉及filter、order_by等方法,提供了一系列示例。
142 1
|
3天前
|
SQL 存储 数据库
48. 【Android教程】数据库:SQLite 的使用
48. 【Android教程】数据库:SQLite 的使用
7 1
|
20天前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
23天前
|
API 数据库 Python
Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法
Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法
|
23天前
|
关系型数据库 MySQL API
Python web框架fastapi数据库操作ORM(一)
Python web框架fastapi数据库操作ORM(一)
|
23天前
|
SQL 缓存 数据库
在Python Web开发过程中:数据库与缓存,如何使用ORM(例如Django ORM)执行查询并优化查询性能?
在Python Web开发中,使用ORM如Django ORM能简化数据库操作。为了优化查询性能,可以:选择合适索引,避免N+1查询(利用`select_related`和`prefetch_related`),批量读取数据(`iterator()`),使用缓存,分页查询,适时使用原生SQL,优化数据库配置,定期优化数据库并监控性能。这些策略能提升响应速度和用户体验。
22 0
|
23天前
|
安全 API 数据库
Python中的Tortoise ORM框架:高效、灵活的数据库交互新选择
【4月更文挑战第14天】在Python的数据库交互领域中,对象关系映射(ORM)框架扮演着举足轻重的角色。近年来,随着技术的不断发展和进步,众多ORM框架如雨后春笋般涌现,其中Tortoise ORM以其高效、灵活的特性受到了广大开发者的青睐。本文将深入探讨Tortoise ORM框架的核心特性、使用方法以及其在Python开发中的应用。