当_id为INTEGER + PRIMARY_KEY + AUTOINCREMENT时,为什么Anko无法忽略_id的传递值?

时间:2017-11-15 03:44:43

标签: android kotlin anko

我设计的_id字段为INTEGER + PRIMARY_KEY+ AUTOINCREMENT,我使用代码SettingManage().addSetting(MSetting(10L,"My Settings",2000L,"This is description!"))将记录插入表格。

我认为Anko将忽略_id传递的值10并自动将新值传递给_id,但事实上_id的值10被插入到表中。

当_id是INTEGER + PRIMARY_KEY+ AUTOINCREMENT时,如何让Anko忽略_id的传递值?

插入数据

SettingManage().addSetting(MSetting(10L,"My Settings",2000L,"This is description!"))

设计表

    class DBSettingHelper(mContext: Context = UIApp.instance) : ManagedSQLiteOpenHelper(
            mContext,
            DB_NAME,
            null,
            DB_VERSION) {

        companion object {
            val DB_NAME = "setting.db"
            val DB_VERSION = 5
            val instance by lazy { DBSettingHelper() }
        }

        override fun onCreate(db: SQLiteDatabase) {
            db.createTable( DBSettingTable.TableNAME , true,
                    DBSettingTable._ID to INTEGER + PRIMARY_KEY+ AUTOINCREMENT ,
                    DBSettingTable.Name to TEXT,
                    DBSettingTable.CreatedDate to INTEGER,
                    DBSettingTable.Description to TEXT
            )
        }

        override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
            db.dropTable(DBSettingTable.TableNAME, true)
            onCreate(db)
        }

    }



    class DBSetting(val mMutableMap: MutableMap<String, Any?>) {
        var _id: Long by mMutableMap
        var name: String by mMutableMap
        var createdDate: Long by mMutableMap
        var description: String by mMutableMap

        constructor(_id: Long, name: String, createdDate: Long, description: String)
                : this(HashMap()) {
            this._id = _id
            this.name = name
            this.createdDate = createdDate
            this.description=description
        }
    }


    object DBSettingTable {
        val TableNAME = "SettingTable"

        val _ID = "_id"
        val Name = "name"
        val CreatedDate = "createdDate"
        val Description="description"
    }


   data class MSetting (
        val _id: Long,  
        val name: String,
        val createdDate: Long,
        val description: String
   )

业务逻辑

class SettingManage {
    fun addSetting(mMSetting:MSetting){
        DBSettingManage().addDBSetting(DbDataMapper().convertMSetting_To_DBSetting(mMSetting))
    }
}

class DBSettingManage(private val mDBSettingHelper: DBSettingHelper =DBSettingHelper.instance) {
    fun addDBSetting(mDBSetting: DBSetting)=mDBSettingHelper.use{
        insert(DBSettingTable.TableNAME,*mDBSetting.mMutableMap.toVarargArray())
    }
}

class DbDataMapper {
    fun convertMSetting_To_DBSetting(mMSetting: MSetting) =with(mMSetting){
        DBSetting(_id,name,createdDate,description)
    }
    fun convertDBSetting_To_MSetting(mDBSetting: DBSetting)=with(mDBSetting){
        MSetting(_id,name,createdDate,description )
    }
}


fun <T : Any> SelectQueryBuilder.parseList(parser: (Map<String, Any?>) -> T): List<T> =
        parseList(object : MapRowParser<T> {
            override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
        })

1 个答案:

答案 0 :(得分:2)

Anko,在您的使用中,是SQLite的包装器。 SQL本身overrides auto increment when a custom value is passed。如果没有传递任何价值 - &gt;自动值。否则 - &gt;手册。它假定它因PRIMARY_KEY而独特,但这是一个不同的问题。

据我所知,Anko没有集成功能允许手动覆盖它。相反,你唯一能做的就是不传递一个值。任何错误的SQL查询都不会被Anko本身捕获,而是由原始SQL捕获。它的SQL会抛出任何异常,这意味着Anko不会检查缺失的数据。

简单地说,不要传递身份证明。您可以编写一个仍然包含ID的函数,但如果该行设置为PRIMARY_KEY和AUTO_INCREMENT,则会丢弃该函数。

我在源代码中做了更多的挖掘,如果它被设置为自动递增,则不支持忽略传递的值。

这意味着你可以让它实际自动增加的唯一方法是不传递任何值。如果您使用任何类型的手动查询,则根本不传递任何值。所以,不要给数据库提供ID。因为它会自动增加,所以它会自动添加它并在基本SQL级别上添加它。

Ank默认不会忽略它,因为它本质上是SQLite的包装器。这意味着如果要覆盖ID,则必须能够传递(请参阅本答案第二句中的链接)。因此,Anko忽视它会导致更多问题,而不是做得好。你必须确保它没有通过