ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android-GreenDao IndsertOrReplaceInTx仅插入列表的最后一项

2019-11-21 05:25:57  阅读:289  来源: 互联网

标签:greendao sqlite android greendao-generator


我有一些POJOS,并为它们创建了一些表.它们全部工作良好,这意味着我可以插入它们并加载它们…除了以下一项:

我的品牌列表包含6个元素,我确实确定它们是不同的(放置断点并看到它们),但是当我要通过greenDao将它们插入DB时,只会插入最后一个元素.我的表是空的,此语句想填充它.

代码:

public class SingletonDatabase {

    private static SingletonDatabase mInstance;
    private DaoMaster.OpenHelper mHelper;
    private DaoSession mDaoSessionForUI;
    private DaoMaster mDaoMaster;
    private static Context mCtx;

    private SingletonDatabase(Context context) {
        mCtx = context;
        setupDb();
    }

    public static synchronized SingletonDatabase getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new SingletonDatabase(context);
        }
        return mInstance;
    }

    private void setupDb() {
        mHelper = new DaoMaster.OpenHelper(
                mCtx.getApplicationContext(), "mydb", null) {

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion,
                    int newVersion) {
                // Handle upgrade
            }
        };

        SQLiteDatabase db = mHelper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSessionForUI = mDaoMaster.newSession();


    }

    public DaoSession getDaoSessionForUI() {
        return mDaoSessionForUI;

    }

    public DaoSession getDaoSeesion(){

        return mDaoMaster.newSession();
    }

}

生成的品牌代码:

 * Entity mapped to table BRAND.
 */
public class Brand {

    private long tableId;
    private String id;
    private String name;
    private String publicImage;
    private String description;
    private String lastDownloadedTime;

    public Brand() {
    }

    public Brand(long tableId) {
        this.tableId = tableId;
    }

    public Brand(long tableId, String id, String name, String publicImage, String description, String lastDownloadedTime) {
        this.tableId = tableId;
        this.id = id;
        this.name = name;
        this.publicImage = publicImage;
        this.description = description;
        this.lastDownloadedTime = lastDownloadedTime;
    }

    public long getTableId() {
        return tableId;
    }

    public void setTableId(long tableId) {
        this.tableId = tableId;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPublicImage() {
        return publicImage;
    }

    public void setPublicImage(String publicImage) {
        this.publicImage = publicImage;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getLastDownloadedTime() {
        return lastDownloadedTime;
    }

    public void setLastDownloadedTime(String lastDownloadedTime) {
        this.lastDownloadedTime = lastDownloadedTime;
    }

}

用于创建模式的代码:

public class DaoGen {

    public static void main(String[] args) throws Exception {

        Schema schema = new Schema(1, "com.mmlooloo");

        Entity brandList = addBrand(schema);



        File f = new File("src-gen");
        f.mkdir();

        new DaoGenerator().generateAll(schema,f.getAbsolutePath());
    }

    private static Entity addBrand(Schema schema) {

        Entity brand = schema.addEntity("Brand");
        brand.addLongProperty("tableId").notNull().primaryKey().autoincrement();
        brand.addStringProperty("id");
        brand.addStringProperty("name");
        brand.addStringProperty("publicImage");
        brand.addStringProperty("description");
        brand.addStringProperty("lastDownloadedTime");
        return brand; 

    }

}

最后是我如何插入它们:

public class BrandDownloadService extends IntentService {
public BrandDownloadService() {
    super("BrandDownloadService");

}
@Override
protected void onHandleIntent(Intent intent) {
    ....
    BrandDao brandDao = SingletonDatabase.getInstance(this).getDaoSeesion().getBrandDao();
    brandDao.insertOrReplaceInTx(brandList,true);

}

我设置断点并检查我的品牌列表,它有6个元素.

任何帮助,解决方法,调试技巧……我真的不知道问题出在哪里.

非常感谢!!

编辑:

我已经创建了一个非常简单的测试项目(真的很简单,相信我:-)),该测试项目从文件中读取json,将其解析为列表并将其插入到this的db中,并且存在问题.谁能告诉我我的错误是什么?非常感谢 :-).

解决方法:

您的6个品牌商品可能共享相同的tableId.因此greendao认为这是一个项目(由主键标识),并用第二个替换第一个,第二个替换第三个,依此类推…

如果使用notNull().primaryKey().autoincrement()

我曾经遇到过同样的问题,并通过更改dao-generator项目中用于代码生成的dao-template来“解决”它.

如果您没有在primarykey属性上使用notNull(),那么它也可能会起作用.

更新

我再次看看绿岛:

在greendao-generator的src-template / dao.ftl文件中,您可以找到以下几行:

protected void bindValues(SQLiteStatement stmt, ${entity.className} entity) {
    stmt.clearBindings();
<#list entity.properties as property>
<#if property.notNull || entity.protobuf>
<#if entity.protobuf>
    if(entity.has${property.propertyName?cap_first}()) {
</#if>        stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, entity.get${property.propertyName?cap_first}()<#if
 property.propertyType == "Boolean"> ? 1l: 0l</#if><#if property.propertyType == "Date">.getTime()</#if>);

这意味着,如果您在自动增量属性上使用notNull(),则将始终将相应的变量绑定为插入或更新语句.这导致始终手动设置主键的值,而忽略自动增量,因为

CREATE TABLE mytable ( id integer primary key autoincrement, details varchar(30));
INSERT INTO mytable (id, details) VALUES (0, 'something');

结果在此数据库行中:0 | “东西”.

因此,这是greendao内部的一个错误!为了解决这个问题,您可以不在主键列上指定notNull,也可以修改文件dao.ftl(第126ff行):

<#list entity.properties as property>
<#if property.notNull || entity.protobuf>
<#if entity.protobuf>
        if(entity.has${property.propertyName?cap_first}()) {
</#if>
<#if property.pkAutoincrement>
        if(entity.get${property.propertyName?cap_first}() != 0) {
</#if>        stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, entity.get${property.propertyName?cap_first}()<#if
     property.propertyType == "Boolean"> ? 1l: 0l</#if><#if property.propertyType == "Date">.getTime()</#if>);
<#if entity.protobuf || property.pkAutoincrement>
    }
</#if>
<#else> <#-- nullable, non-protobuff -->
    ${property.javaType} ${property.propertyName} = entity.get${property.propertyName?cap_first}();
    if (${property.propertyName} != null) {
<#if property.pkAutoincrement>    if (${property.propertyName} != 0) {
    </#if>       stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, ${property.propertyName}<#if property.propertyType == "Boolean"> ? 1l: 0l</#if><#if property.propertyType == "Date">.getTime()    </#if>);
<#if property.pkAutoincrement>        }</#if>
    }
</#if>

这将导致greendao不会将autoincrement-primarykey值绑定到更新或插入语句,除非它为!= 0或null.

不过,请谨慎使用第二种方法:该方法未经测试,因此可能会对绿道的其他部分产生副作用!

标签:greendao,sqlite,android,greendao-generator
来源: https://codeday.me/bug/20191121/2049483.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有