目录
一、原有表中添加另外对象--嵌套类
使用嵌套类:
二、外键定义:
三、多表联查
多表联查使用步骤
四、数据库升级
一、原有表中添加另外对象--嵌套类 使用嵌套类:在原有的表中需要添加另外一个实体类时,可以使用嵌套类。
@embedded,将额外对象的内容字段,添加到当前entry的表内,所以,其字段不可与当前entry字段重复
例如原来的数据实体类叫DBUser,此时我们需要将另外一个实体类Child的相关属性也添加到原来DBUser表中。
首先定义一个Child类,需要注意的是Child类中的属性字段不能够和原来的DBUser中的字段重复,因为最后Child的字段是和DBUser插入到同一个表中的,否则会编译报错
data class Child(
val cid: Int,
val cname: String,
val cAge: Int,
val sex: Int
)
使用步骤:原有表中添加@Embedded
@Embedded
var baby: Child? = null//孩子
具体添加时可以作为user的一个属性加入:
user = DbUser()
user.age = 20 + i
user.city = "北京 $i"
user.name = "小明 $i"
user.isSingle = i % 2 == 0
user.bookId = i
user.baby = Child(i, " 孩子 $i", 10 + i, i % 2)
二、外键定义:
定义一个普通的@Entity类:
@Entity
data class Book(
@PrimaryKey
val bid: Int,
val name: String,
val price: Double
)
在原有的DbUser@Entity中定义外键:foreignKeys,关联的主键是DbUser中的bookId字段,
//room数据库的注解标记,数据表entity (tableName="db_user",indices = {@Index(value = "uname",unique = true)})
@Entity(
tableName = "db_user", foreignKeys = [ForeignKey(
entity = Book::class,
parentColumns = ["bid"], childColumns = ["bookId"], onDelete = SET_DEFAULT
)], indices = [Index("uid"), Index("bookId")]
)
在DbUser中添加bookID作为关联表的外键:
var bookId: Int = 0
需要注意,在多表关联时存在多个表用一个主键关联,存在当一个外键的表数据变化时引起主键表数据也要刷新一次,引起性能问题。
因此需要在表上建立一些索引例如:indices = [Index("uid"), Index("bookId"),将不同表的索引加入后,一张表的数据变化不会引起其他表的数据刷新
三、多表联查 多表联查使用步骤-
sql语句返回数据,构建临时bean对象
-
databaseView需要在dataBase的抽象类中@database的views添加,而后可用于在@query中使用
在Entity中建立@DatabaseView
可以在这里添加多表联查的SQL语句,这个数据类只能进行查询,而不能增删改操作
/**
* 这个注解,表明该数据类是sql的执行结果数据,可用于其他的dao操作,用于class较为合适,而不是data class
* You can SELECT FROM a DatabaseView similar to an Entity, but you can not INSERT, DELETE or UPDATE into a DatabaseView.
*/
@DatabaseView("select uname,name from db_user,book where uid=3 or bookId=3", viewName = "tempBean")
class TempBean {
var uname = ""
var name = ""
override fun toString(): String {
return "TempBean(uname='$uname', name='$name')"
}
在Dao层查询:
@Query("select * from tempBean")
fun queryUserBook(): List
在数据库中添加TempBean:
@Database(
entities = [DbUser::class, JUser::class, Book::class],
version = 1,
exportSchema = true,
views = [TempBean::class]
)
四、数据库升级
- 创建migration-->内部处理数据库迁移逻辑
- addMigrations,可多个版本迁移处理
步骤:在数据库类中创建migration,addMigrations(),数据可以从版本1-->版本2;也可以降级从版本3到-->版本1
instance = Room.databaseBuilder(
context!!,
UserDatabase::class.java,
DB_NAME
)
.allowMainThreadQueries() //默认room不允许在主线程操作数据库,这里设置允许
.addMigrations(migration1_2)
.build()
/**
* 数据库的升级 迁移
*/
val migration1_2 = object : Migration(2, 1) {
override fun migrate(database: SupportSQLiteDatabase) {
// database.execSQL()
}
}
添加升级的方法addMigrations()
,这个方法可以接受多个升级语句,比如当前要升级到版本3,但考虑到一部分用户已经是版本2,一部分用户仍然在用版本1,那么此时应该提供两种升级方式:从版本1升级到版本3 和 从版本2升级到版本3。写好两种升级语句,一起传给addMigrations()
方法即可。