Table annotation support specify supper class#561
Table annotation support specify supper class#561qumn wants to merge 3 commits intokotlin-orm:masterfrom
Conversation
|
According to this issue, the KSTypeNotPresentException error occurred even though the class exists in the project. The issue was temporarily resolved using by the comment |
985a319 to
513f06d
Compare
|
让用户指定父类有什么用处吗?可以说一说你的使用场景 |
|
对于一个Entity,对于其中的一部分字段可以在父类中通过Ktorm提供的api更灵活的实现。剩下的字段使用 KSP 生成。 @JvmInline
value class UID(val value: Long)
interface UserBaseEntity<E : Entity<E>> : Entity<E> {
var uid: UID
}
abstract class UserBaseTable<E : UserBaseEntity<E>>(
tableName: String,
alias: String? = null,
catalog: String? = null,
schema: String? = null,
entityClass: KClass<E>? = null,
) : org.ktorm.schema.Table<E>(
tableName, alias, catalog, schema, entityClass
) {
val uid = long("uid").transform({ UID(it) }, { it.value }).primaryKey().bindTo { it.uid }
}
@Table(
"t_user",
superClass = UserBaseTable::class,
ignoreProperties = ["uid"]
)
interface User: UserBaseEntity<User> {
var username: String
var password: String
}生成的代码如下: /**
* Table t_user.
*/
public open class Users(alias: String?) : UserBaseTable<User>("t_user", alias) {
/**
* Column username.
*/
public val username: Column<String> = varchar("username").bindTo { it.username }
/**
* Column password.
*/
public val password: Column<String> = varchar("password").bindTo { it.password }
/**
* Return a new-created table object with all properties (including the table name and columns and
* so on) being copied from this table, but applying a new alias given by the parameter.
*/
public override fun aliased(alias: String): Users = Users(alias)
/**
* The default table object of t_user.
*/
public companion object : Users(alias = null)
} |
|
想法很棒,但这方案对于一个通用框架来说还不够完美,以你的代码为例 @Table(
"t_user",
superClass = UserBaseTable::class,
ignoreProperties = ["uid"]
)
interface User: UserBaseEntity<User> {
var username: String
var password: String
}这里有些没必要的噪音:
这两个问题会导致,如果我们项目中使用了抽象表父类,我们就不得不把这坨注解复制到每个实体类上,这种用户体验对一个公共框架来说是不可接受的 我提供一个方案你看如何?首先增加一个 @SuperTableClass(UserBaseTable::class)
interface UserBaseEntity<E : Entity<E>> : Entity<E> {
var uid: UID
}
abstract class UserBaseTable<E : UserBaseEntity<E>>(
tableName: String,
alias: String? = null,
catalog: String? = null,
schema: String? = null,
entityClass: KClass<E>? = null,
) : org.ktorm.schema.Table<E>(
tableName, alias, catalog, schema, entityClass
) {
val uid = long("uid").transform({ UID(it) }, { it.value }).primaryKey().bindTo { it.uid }
}然后,普通的实体类,就只需要继承 @Table
interface User : UserBaseEntity<User> {
var username: String
var password: String
}Ktorm 需要能识别到 |
|
当然,为了功能的完备性和严谨性,我们还需要实现这些:
|
|
我也认为 @SuperTableClass(ATable::class)
Interface AEntity : Entity : {}
abstract class ATable(...) : Table(...)
@SuperTableClass(BTable::class)
Interface BEntity : AEntity : {}
abstract class BTable(...) : ATable(...)
@Table(name = "CTable")
Interface CEntity : BEntity {}虽然 CEntity 的继承链上存在两个 |
|
嗯,我之所以制定第 4 条规则,是考虑到 interface 的多继承,比如 当然,我们也可以实现你说的这种,自动检测出这些表对象的继承关系,当只有一条继承链的时候,使用最底层的子类,当存在多条继承链的时候才抛出异常 两种方案都 OK,考虑到开发成本,直接禁止继承也是可以接受的,我感觉这个需求并不算常见 |
|
我尝试实现了下 |
#559