-
-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Table annotation support specify supper class #561
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