Skip to content
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

实现jpa的@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy #32

Closed
qzsiniong opened this issue Aug 6, 2019 · 4 comments

Comments

@qzsiniong
Copy link

qzsiniong commented Aug 6, 2019

怎样实现类似jpa的@CreatedDate、@createdby、@LastModifiedDate、@LastModifiedBy功能

@vincentlauvlwj
Copy link
Member

Ktorm 是一个轻量级的 ORM 框架,只负责做好数据持久层的事情就可以了,不会提供像审计这种与具体业务紧密联系的功能

因此,如果你需要的话,可以自己基于 Ktorm 去扩展实现,在这里我只是给出一点建议:

  • 提供一个 AuditEntity 类,继承 Entity,作为所有业务实体类的公共父类,里面包含了 lastModifiedDatelastModifiedBy 等通用的属性
  • 提供一个 AuditTable 类,继承 Table,作为所有业务表对象的公共父类,里面包含了通用的列定义,并绑定到 AuditEntity 的相应属性中
interface AuditEntity<E : AuditEntity<E>> : Entity<E> {
    var createdDate: Instant?
    var createdBy: String?
    var lastModifiedDate: Instant?
    var lastModifiedBy: String?

    fun flushChangesAuditing(user: String? = null): Int {
        lastModifiedDate = Instant.now()
        lastModifiedBy = user
        return this.flushChanges()
    }
}

open class AuditTable<E : AuditEntity<E>>(
    tableName: String,
    alias: String? = null,
    entityClass: KClass<E>? = null
) : Table<E>(tableName, alias, entityClass) {

    val createdDate by timestamp("created_date").bindTo { it.createdDate }
    val createdBy by varchar("created_by").bindTo { it.createdBy }
    val lastModifiedDate by timestamp("last_modified_date").bindTo { it.lastModifiedDate }
    val lastModifiedBy by varchar("last_modified_by").bindTo { it.lastModifiedBy }

    fun addAuditing(entity: E, user: String? = null): Int {
        entity.createdDate = Instant.now()
        entity.createdBy = user
        entity.lastModifiedDate = entity.createdDate
        entity.lastModifiedBy = user
        return this.add(entity)
    }
}

有了这两个类,所有的业务表对象和实体类都从这里继承就可以了,假设我们有一个 Products 表,它的定义就是这样的:

interface Product : AuditEntity<Product> {
    var id: Int
    var name: String
    var price: BigDecimal?
}

object Products : AuditTable<Product>("t_product") {
    val id by int("id").primaryKey().bindTo { it.id }
    val name by varchar("name").bindTo { it.name }
    val price by decimal("price").bindTo { it.price }
}

可以看到,两个父类中分别增加了 addAuditingflushChangesAuditing 两个函数,以后我们的新增和修改操作都走这两个函数就好了,不知能否实现你的需求?

@qzsiniong
Copy link
Author

Ktorm 是一个轻量级的 ORM 框架,只负责做好数据持久层的事情就可以了,不会提供像审计这种与具体业务紧密联系的功能

因此,如果你需要的话,可以自己基于 Ktorm 去扩展实现,在这里我只是给出一点建议:

  • 提供一个 AuditEntity 类,继承 Entity,作为所有业务实体类的公共父类,里面包含了 lastModifiedDatelastModifiedBy 等通用的属性
  • 提供一个 AuditTable 类,继承 Table,作为所有业务表对象的公共父类,里面包含了通用的列定义,并绑定到 AuditEntity 的相应属性中
interface AuditEntity<E : AuditEntity<E>> : Entity<E> {
    var createdDate: Instant?
    var createdBy: String?
    var lastModifiedDate: Instant?
    var lastModifiedBy: String?

    fun flushChangesAuditing(user: String? = null): Int {
        lastModifiedDate = Instant.now()
        lastModifiedBy = user
        return this.flushChanges()
    }
}

open class AuditTable<E : AuditEntity<E>>(
    tableName: String,
    alias: String? = null,
    entityClass: KClass<E>? = null
) : Table<E>(tableName, alias, entityClass) {

    val createdDate by timestamp("created_date").bindTo { it.createdDate }
    val createdBy by varchar("created_by").bindTo { it.createdBy }
    val lastModifiedDate by timestamp("last_modified_date").bindTo { it.lastModifiedDate }
    val lastModifiedBy by varchar("last_modified_by").bindTo { it.lastModifiedBy }

    fun addAuditing(entity: E, user: String? = null): Int {
        entity.createdDate = Instant.now()
        entity.createdBy = user
        entity.lastModifiedDate = entity.createdDate
        entity.lastModifiedBy = user
        return this.add(entity)
    }
}

有了这两个类,所有的业务表对象和实体类都从这里继承就可以了,假设我们有一个 Products 表,它的定义就是这样的:

interface Product : AuditEntity<Product> {
    var id: Int
    var name: String
    var price: BigDecimal?
}

object Products : AuditTable<Product>("t_product") {
    val id by int("id").primaryKey().bindTo { it.id }
    val name by varchar("name").bindTo { it.name }
    val price by decimal("price").bindTo { it.price }
}

可以看到,两个父类中分别增加了 addAuditingflushChangesAuditing 两个函数,以后我们的新增和修改操作都走这两个函数就好了,不知能否实现你的需求?

以这种方式batchInsert不好实现。
结合spring的时候可否用切面实现呢?

@vincentlauvlwj
Copy link
Member

batchInsert 的时候手动设置一下这几个字段就好了嘛,我认为这个并不是一个问题:

Products.batchInsert {
    for (i in 1..100) {
        item {
            it.id to i
            it.name to "product-$i"
            it.price to i.toBigDecimal()
            it.createdDate to Instant.now()
            it.createdBy to "vince"
            it.lastModifiedDate to Instant.now()
            it.lastModifiedBy to "vince"
        }
    }
}

@qzsiniong
Copy link
Author

batchInsert 的时候手动设置一下这几个字段就好了嘛,我认为这个并不是一个问题:

Products.batchInsert {
    for (i in 1..100) {
        item {
            it.id to i
            it.name to "product-$i"
            it.price to i.toBigDecimal()
            it.createdDate to Instant.now()
            it.createdBy to "vince"
            it.lastModifiedDate to Instant.now()
            it.lastModifiedBy to "vince"
        }
    }
}

我考虑的是写在一个公共的地方,不用每个地方都自己处理

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants