首页 > 解决方案 > 房间交界处 Pojo

问题描述

我尝试在 pojo 中获取 N:M 数据库实体。

以下是实体:

人:

@Entity(
    tableName = "person_table",
    indices = [Index("person_id")]
)
class Person() {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "person_id")
    var id: Long = 0
}

车:

@Entity(
    tableName = "car_table",
    indices = [Index("car_id")]
)
class Car() {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "car_id")
    var id: Long = 0
}

和结实体:

@Entity(
    tableName = "person_car_join",
    primaryKeys = ["fk_person_id", "fk_car_id"],
    indices = [
        Index("fk_person_id"),
        Index("fk_car_id")
    ],
    foreignKeys = [
        ForeignKey(
            entity = Person::class,
            childColumns = arrayOf("fk_person_id"),
            parentColumns = arrayOf("person_id")
        ), ForeignKey(
            entity = Car::class,
            childColumns = arrayOf("fk_car_id"),
            parentColumns = arrayOf("car_id")
        )
    ]
)
class PersonCarJoin(
    @ColumnInfo(name = "fk_person_id") var fkPersonId: Long,
    @ColumnInfo(name = "fk_car_id") var fkCarId: Long
)

这是我的 Pojo:

class PersonWithCarsPojo {

    @Embedded
    lateinit var person: Person

    @Relation(
        entityColumn = "car_id",
        parentColumn = "person_id",
        associateBy = Junction(
            PersonCarJoin::class,
            parentColumn = "fk_person_id",
            entityColumn = "fk_car_id"
        )
    )
    var cars: List<Car> = arrayListOf()
}

我尝试用这个查询来获取它们:

@Query(
    """
    SELECT
        *
    FROM
        person_table;
    """
)
fun getAllPersonsWithCars(): LiveData<List<PersonWithCarsPojo>>

但我只得到汽车列表中只有一辆车的所有人。我究竟做错了什么?

提前致谢。

标签: androidmany-to-manyandroid-room

解决方案


您确定要添加关系吗?

或者您是否至少拥有相应 Room 库的2.2.0 版本associateBy,其中添加了和@Junction2.2.0 版 - 2019 年 10 月 9 日

根据您的代码(但使用 Java 而不是 Kotlin)然后是以下内容:-

    mPersonCarsDao = mRTDB.personCarsDao();
    mPersonCarsDao.insertPeople(
            new Person("Fred"),
            new Person("Jane"),
            new Person("Anne")
    );
    mPersonCarsDao.insertCars(
            new Car("A"),
            new Car("B"),
            new Car("C")
    );
    mPersonCarsDao.insertPersonCarJoins(
            new PersonCarJoin(1,2), // Fred -> B
            new PersonCarJoin(1,3), // Fred -> C
            new PersonCarJoin(2,1), // Jane -> A
            new PersonCarJoin(2,3), // Jane -> C
            new PersonCarJoin(3,3) // Anne -> C
    );

    List<PersonWithCarsPojo> personWithCarsPojos = mPersonCarsDao.getAllPeopleWithCars();
    for (PersonWithCarsPojo pwcp: personWithCarsPojos) {
        for (Car c: pwcp.cars) {
            Log.d("PWCPINFO","Person is " + pwcp.getPerson().getName() + " Car is " + c.getCar());
        }
    }

输出:-

2019-10-09 07:22:40.163 D/PWCPINFO: Person is Fred Car is B
2019-10-09 07:22:40.163 D/PWCPINFO: Person is Fred Car is C
2019-10-09 07:22:40.163 D/PWCPINFO: Person is Jane Car is A
2019-10-09 07:22:40.163 D/PWCPINFO: Person is Jane Car is C
2019-10-09 07:22:40.163 D/PWCPINFO: Person is Anne Car is C

PersonCarsDao 是:-

@Dao
public interface PersonCarsDao {

    @Insert
    long[] insertPeople(Person... people);

    @Insert
    long insertPerson(Person person);

    @Insert
    long[] insertCars(Car... cars);

    @Insert
    long insertCar(Car car);

    @Insert
    long insertPersonCarJoin(PersonCarJoin personCarJoin);

    @Insert
    long[] insertPersonCarJoins(PersonCarJoin... personCarJoins);

    @Query("SELECT * FROM car_table")
    List<Car> getAllCars();

    @Query("SELECT * FROM person_table")
    List<Person> getAllPeople();

    @Query("SELECT * FROM car_table WHERE car_id = :car_id")
    Car getCarById(long car_id);

    @Query("SELECT * FROM person_table WHERE person_id = :person_id")
    Person getPersonById(long person_id);

    @Query("SELECT * FROM person_table")
    List<PersonWithCarsPojo> getAllPeopleWithCars();

}

附加(使用 Kotlin)

以下是上面的完整代码,但在 Kotlin 中并且可以正常工作。

Person.kt(添加了 personName 列)

@Entity(
    tableName = "person_table",
    indices = [Index("person_id")]
)
class Person() {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "person_id")
    var id: Long = 0

    var personName: String = ""
}

Car.kt(添加了 carName 列)

@Entity(
    tableName = "car_table",
    indices = [Index("car_id")]
)
class Car {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "car_id")
    var id: Long = 0

    var carName: String = ""
}

PersonCarJoin.kt(未更改)

@Entity(
    tableName = "person_car_join",
    primaryKeys = ["fk_person_id", "fk_car_id"],
    indices = [
        Index("fk_person_id"),
        Index("fk_car_id")
    ],
    foreignKeys = [
        ForeignKey(
            entity = Person::class,
            childColumns = arrayOf("fk_person_id"),
            parentColumns = arrayOf("person_id")
        ), ForeignKey(
            entity = Car::class,
            childColumns = arrayOf("fk_car_id"),
            parentColumns = arrayOf("car_id")
        )
    ]
)
class PersonCarJoin(
    @ColumnInfo(name = "fk_person_id") var fkPersonId: Long,
    @ColumnInfo(name = "fk_car_id") var fkCarId: Long
)

PersonWithCarsPojo(未更改)

class PersonWithCarsPojo {

    @Embedded
    lateinit var person: Person

    @Relation(
        entityColumn = "car_id",
        parentColumn = "person_id",
        associateBy = Junction(
            PersonCarJoin::class,
            parentColumn = "fk_person_id",
            entityColumn = "fk_car_id"
        )
    )
    var cars: List<Car> = arrayListOf()
}

PersonCarDoa(已创建但包含您的 getAllPersonsWithCars)

@Dao
interface PersonCarDao {

    @Insert
    fun insertPerson(person: Person): Long

    @Insert
    fun insertpeople(vararg People: Person)

    @Insert
    fun insertCar(car: Car): Long

    @Insert
    fun insertCars(vararg cars: Car)

    @Insert
    fun insertPersonCarJoin(personCarJoin: PersonCarJoin): Long

    @Query("SELECT * FROM person_table")
    fun getAllPersonsWithCars(): List<PersonWithCarsPojo>
}

AppDatabase.kt(已创建)

@Database(version = 1, entities =  [Person::class,Car::class,PersonCarJoin::class])
abstract class AppDatabase : RoomDatabase() {

    abstract fun personCarDao(): PersonCarDao
}

MainActivity.kt

class MainActivity : AppCompatActivity() {



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val db = Room.databaseBuilder(applicationContext,AppDatabase::class.java,"personcardb")
            .allowMainThreadQueries()
            .build()
        val personCarDao = db.personCarDao()

        val person = Person()
        person.personName = "Fred"
        personCarDao.insertPerson(person)
        person.personName = "Jane"
        personCarDao.insertPerson(person)
        person.personName = "Anne"
        personCarDao.insertPerson(person)

        val car = Car()
        car.carName = "A"
        personCarDao.insertCar(car)
        car.carName = "B"
        personCarDao.insertCar(car)
        car.carName = "C"
        personCarDao.insertCar(car)

        val pcj1 = PersonCarJoin(1,2)
        personCarDao.insertPersonCarJoin(pcj1)
        val pcj2 = PersonCarJoin(1,3)
        personCarDao.insertPersonCarJoin(pcj2)
        val pcj3 = PersonCarJoin(2,1)
        personCarDao.insertPersonCarJoin(pcj3)
        val pcj4 = PersonCarJoin(2,3)
        personCarDao.insertPersonCarJoin(pcj4)
        val pcj5 = PersonCarJoin(3,3)
        personCarDao.insertPersonCarJoin(pcj5)

        val theList: List<PersonWithCarsPojo> = personCarDao.getAllPersonsWithCars()
        for (pwc: PersonWithCarsPojo in theList) {
            for(c: Car in pwc.cars) {
                Log.d("PWCINFO","Person is " + pwc.person.personName + " Car is " + c.carName)
            }
        }
    }
}

结果(来自最终 for 循环的日志)

2019-10-09 20:25:08.364 D/PWCINFO: Person is Fred Car is B
2019-10-09 20:25:08.364 D/PWCINFO: Person is Fred Car is C
2019-10-09 20:25:08.364 D/PWCINFO: Person is Jane Car is A
2019-10-09 20:25:08.364 D/PWCINFO: Person is Jane Car is C
2019-10-09 20:25:08.364 D/PWCINFO: Person is Anne Car is C

正如您所看到的 3 人和 3 辆汽车,但有 5 个输出(弗雷德有 2 辆汽车,简也有,而安妮只有 1 辆汽车)


推荐阅读