美文网首页程序员
Sqlite之主键乱序和GreenDao设计的坑

Sqlite之主键乱序和GreenDao设计的坑

作者: 楚云之南 | 来源:发表于2015-08-03 16:19 被阅读5742次

    公司Android项目使用的ORM框架是Greendao,曾经出现过一个bug:数据库中读出来的缓存数据顺序和存入的顺序不一样,不知大家是否也遇到?当时找到了几种解决方案,但是没有去探究具体的原因。

    Sqlite rowId什么鬼?

    如果我们使用可视化工具打开sqlite的数据库文件,你可以看到每个表中第一列都是rowid,这是谁定义的?

    SQLITE会默认给所有的表增加一个rowid列,它会和Integer类型的主键绑定起来,官方文档中的说法:"INTEGER PRIMARY KEY" means that the column is an alias for the rowid.你能想象到比这这个扯淡的事情么?也就是说,你自己定义了一个Integer类型的主键,那么你给这个主键的所有赋值都会copyrowid,这样的话取出来的数据会按照rowid升序排的。

    SQLITE数据库还有很多奇怪的其它特性,比如主键是可以为空,为空的主键还可以插入多个。。知道真相的我眼泪掉下来。。。

    Greendao对主键的处理

    既然Sqlite给我们留了这么美好的一个坑,GreenDao坚定地走在了踩坑的路上,我们一般定义一个主键:

     e.addIntProperty("id").primaryKey().notNull();
     
     or
     
     e.addLongProperty("id").primaryKey().notNull();
    

    那么GreenDao如何处理的呢?Schema.java中的代码:

         //-----------------------------------------------
         propertyToDbType.put(PropertyType.Boolean, "INTEGER");
        propertyToDbType.put(PropertyType.Byte, "INTEGER");
        propertyToDbType.put(PropertyType.Short, "INTEGER");
        propertyToDbType.put(PropertyType.Int, "INTEGER");
        propertyToDbType.put(PropertyType.Long, "INTEGER");
        //------------知道真相的我眼泪再次留下来。。-------------
        propertyToDbType.put(PropertyType.Float, "REAL");
        propertyToDbType.put(PropertyType.Double, "REAL");
        propertyToDbType.put(PropertyType.String, "TEXT");
        propertyToDbType.put(PropertyType.ByteArray, "BLOB");
        propertyToDbType.put(PropertyType.Date, "INTEGER");
    

    这么多类型被GreenDao处理成了INTEGER。这样我们在GreenDao里面定义的非小数类型的主键都会和rowid进行绑定,WTF!!

    解决方案

    提供之前想的几种折衷方案,但是感觉再怎么样都没有直接去修改GreenDao的源码来的直接。

    1. 将主键改成String类型,然后在代码里面做数值字符转化。这种写法是最省事的,因为我们这边项目是和Gson配合使用,Gson是支持 String<----->Number 自动转化的。如果表里面的数据量不大,那么是可以接受的,如果数据量较大,还是考虑第二种方案吧。
    2. 取消将业务的ID设置成主键,只设置成unique,让rowid行使主键的职责,这也是sqlite引入的目的。但是GreenDao上层的Dao.load(PK)支持对PK的直接查询,所以以后查表时需要封入相应的Where条件。

    不知道大伙还有别的更好的解决方案吗?

    相关文章

      网友评论

        本文标题:Sqlite之主键乱序和GreenDao设计的坑

        本文链接:https://www.haomeiwen.com/subject/lcevqttx.html