波霍交界处

时间:2019-10-08 16:00:19

标签: android many-to-many android-room

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

以下是实体:

人员:

js

汽车:

@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
}

这是我的Pojo:

@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
)

然后我尝试通过以下查询获取它们:

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()
}

但是我只让所有只有1辆车的人进入汽车列表。我在做什么错了?

谢谢。

1 个答案:

答案 0 :(得分:0)

确定要添加关系吗?

或者您是否至少有相应的Room库的 2.2.0版本,其中添加了associateBy@JunctionVersion 2.2.0 - October 9, 2019

根据您的代码(但使用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)
            }
        }
    }
}

结果(final 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辆车)