Kotlin:如何将对象列表插入Room?

时间:2018-01-09 23:06:44

标签: android kotlin android-room

我正在尝试在基本接口中定义常见的CRUD方法,如下所示:

interface BaseDao<in I> {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun create(obj: I)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun createAll(objects: List<I>)

    @Delete
    fun delete(obj: I)

}

RoomProductDao接口继承自基接口:

@Dao
interface ProductDao : BaseDao<Product> {

    // Specific methods

}

当我编译fun createAll(objects: List<I>)的定义时会产生以下错误:

  

参数的类型必须是使用@Entity或其集合/数组注释的类。

5 个答案:

答案 0 :(得分:5)

尝试将@JvmSuppressWildcards添加到您的功能中。

@Insert
@JvmSuppressWildcards
fun createAll(objects: List<I>)

来自文档:

  

指示编译器为与声明 - 站点差异的参数对应的类型参数生成或省略通配符,例如Collection has。

     

只有从Java中使用声明似乎不方便时才有用。

答案 1 :(得分:1)

我通过以下方式解决了问题:

$api->post('addpost', 'App\\Api\\V1\\Controllers\\Front\\PostController@store');

@JvmSuppressWildcards 为我做了诀窍

答案 2 :(得分:0)

你应该为你的模型类添加@Entity注释(你应该有Dao方法的具体模型类), 但您在界面BaseDao<in I>中使用泛型。 https://developer.android.com/training/data-storage/room/defining-data.html

答案 3 :(得分:0)

我有同样的问题,我相信我找到了解决方案:

Kotlin不可能创建通用对象数组,所以你必须做出这样的解决方法:

@Transaction

@Insert(onConflict = OnConflictStrategy.REPLACE) fun createAll(objects: List<Product>) 应该在一次交易中完成所有这一切,因此不应该引入任何性能问题,但我不确定这一点。

更重要的是,简单:

public class Board {
    private char [][] positions = new char[7][8];

    //getters and setters

}

public class Another {
    Board board;

    public void printBoard(){
        board.getPositions();
    }

}

也可以,只要它使用真实对象,而不是泛型。

答案 4 :(得分:0)

我的解决方法是在 Java 中实施BaseDao界面,直到问题仍然存在。

public interface IBaseDao<T> {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    @WorkerThread
    void save(T item);

    @Delete
    @WorkerThread
    void delete(T item);

    @Delete
    @WorkerThread
    void deleteAll(List<T> items);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    @WorkerThread
    void saveAll(List<T> items);
}

Kotlin中的摘要BaseDao

abstract class BaseDao<T> : IBaseDao<T> {

    @WorkerThread
    open fun getAll(): List<T> = TODO("Override and place the annotation @Query. Ex: @Query(\"SELECT * FROM Model\")")

    @WorkerThread
    open fun loadAll(): LiveData<List<T>> = TODO("Override and place the annotation @Query. Ex: @Query(\"SELECT * FROM Model\")")
}

有效!