From 2d0de09816adf842a30e018a83d1e9938ee9e602 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 22 May 2020 16:31:26 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E5=91=BD=E5=90=8D=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=92=8C=E6=B3=9B=E5=9E=8B=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?repo/srv/query?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/synebula/gaea/app/UnionApp.kt | 13 +- .../{UnionTypedApp.kt => UnionGenericApp.kt} | 17 +- .../gaea/app/query/IQueryGenericApp.kt | 8 +- .../synebula/gaea/app/query/IQueryTypedApp.kt | 15 +- .../gaea/app/query/QueryGenericApp.kt | 11 +- .../synebula/gaea/app/query/QueryTypedApp.kt | 10 +- .../com/synebula/gaea/mongo/MongoExt.kt | 2 +- .../gaea/mongo/query/MongoGenericQuery.kt | 130 +++++++++++++++ .../synebula/gaea/mongo/query/MongoQuery.kt | 150 ++++++------------ .../gaea/mongo/query/MongoQueryTyped.kt | 84 ---------- .../repository/MongoGenericRepository.kt | 51 ++++++ .../gaea/mongo/repository/MongoRepository.kt | 45 ++---- .../mongo/repository/MongoRepositoryTyped.kt | 30 ---- ...sitoryComplex.kt => IComplexRepository.kt} | 2 +- .../domain/repository/IGenericRepository.kt | 61 +++++++ .../gaea/domain/repository/IRepository.kt | 35 +--- .../domain/repository/IRepositoryTyped.kt | 42 ----- .../{ServiceComplex.kt => ComplexService.kt} | 14 +- .../{ServiceTyped.kt => GenericService.kt} | 41 +++-- ...{IServiceComplex.kt => IComplexService.kt} | 7 +- .../synebula/gaea/domain/service/IService.kt | 2 +- .../synebula/gaea/domain/service/Service.kt | 37 ++--- .../{IQueryTyped.kt => IGenericQuery.kt} | 14 +- .../kotlin/com/synebula/gaea/query/IQuery.kt | 14 +- 24 files changed, 423 insertions(+), 412 deletions(-) rename src/gaea.app/src/main/kotlin/com/synebula/gaea/app/{UnionTypedApp.kt => UnionGenericApp.kt} (58%) create mode 100644 src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoGenericQuery.kt delete mode 100644 src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQueryTyped.kt create mode 100644 src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoGenericRepository.kt delete mode 100644 src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepositoryTyped.kt rename src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/{IRepositoryComplex.kt => IComplexRepository.kt} (93%) create mode 100644 src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IGenericRepository.kt delete mode 100644 src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryTyped.kt rename src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/{ServiceComplex.kt => ComplexService.kt} (73%) rename src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/{ServiceTyped.kt => GenericService.kt} (55%) rename src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/{IServiceComplex.kt => IComplexService.kt} (71%) rename src/gaea/src/main/kotlin/com/synebula/gaea/query/{IQueryTyped.kt => IGenericQuery.kt} (59%) diff --git a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionApp.kt b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionApp.kt index 460440f..3bde34c 100644 --- a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionApp.kt +++ b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionApp.kt @@ -1,7 +1,7 @@ package com.synebula.gaea.app import com.synebula.gaea.app.cmd.ICommandApp -import com.synebula.gaea.app.query.IQueryGenericApp +import com.synebula.gaea.app.query.IQueryTypedApp import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.domain.service.ICommand import com.synebula.gaea.domain.service.IService @@ -18,11 +18,12 @@ import javax.annotation.Resource * @param logger 日志组件 */ open class UnionApp( - override var name: String, - override var service: IService?, - override var query: IQuery?, - override var logger: ILogger) - : ICommandApp, IQueryGenericApp { + override var name: String, + override var clazz: Class, + override var service: IService?, + override var query: IQuery?, + override var logger: ILogger) + : ICommandApp, IQueryTypedApp { @Resource override var jsonSerializer: IJsonSerializer? = null diff --git a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionTypedApp.kt b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionGenericApp.kt similarity index 58% rename from src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionTypedApp.kt rename to src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionGenericApp.kt index bb151f7..6272ab2 100644 --- a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionTypedApp.kt +++ b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/UnionGenericApp.kt @@ -2,13 +2,11 @@ package com.synebula.gaea.app import com.synebula.gaea.app.cmd.ICommandApp import com.synebula.gaea.app.query.IQueryGenericApp -import com.synebula.gaea.app.query.IQueryTypedApp import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.domain.service.ICommand import com.synebula.gaea.domain.service.IService import com.synebula.gaea.log.ILogger -import com.synebula.gaea.query.IQuery -import com.synebula.gaea.query.IQueryTyped +import com.synebula.gaea.query.IGenericQuery import javax.annotation.Resource /** @@ -19,13 +17,12 @@ import javax.annotation.Resource * @param query 业务查询服务 * @param logger 日志组件 */ -open class UnionTypedApp( - override var name: String, - override var viewClass: Class, - override var service: IService?, - override var query: IQueryTyped?, - override var logger: ILogger) - : ICommandApp, IQueryTypedApp { +open class UnionGenericApp( + override var name: String, + override var service: IService?, + override var query: IGenericQuery?, + override var logger: ILogger +) : ICommandApp, IQueryGenericApp { @Resource override var jsonSerializer: IJsonSerializer? = null diff --git a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryGenericApp.kt b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryGenericApp.kt index d3cdeff..d71418a 100644 --- a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryGenericApp.kt +++ b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryGenericApp.kt @@ -1,13 +1,9 @@ package com.synebula.gaea.app.query -import com.synebula.gaea.app.IApplication import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.data.message.Status -import com.synebula.gaea.query.IQuery +import com.synebula.gaea.query.IGenericQuery import com.synebula.gaea.query.PagingParam -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestParam /** * 应用类接口,提供实现Query服务的接口 @@ -21,7 +17,7 @@ interface IQueryGenericApp : IQueryApp { /** * 查询服务 */ - var query: IQuery? + var query: IGenericQuery? /** diff --git a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryTypedApp.kt b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryTypedApp.kt index c9f6c10..37aaf33 100644 --- a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryTypedApp.kt +++ b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/IQueryTypedApp.kt @@ -1,9 +1,8 @@ package com.synebula.gaea.app.query -import com.synebula.gaea.app.IApplication import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.data.message.Status -import com.synebula.gaea.query.IQueryTyped +import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.PagingParam /** @@ -14,26 +13,26 @@ import com.synebula.gaea.query.PagingParam * @version 0.1 * @since 2020-05-15 */ -interface IQueryTypedApp : IApplication, IQueryApp { +interface IQueryTypedApp : IQueryApp { /** * 查询服务 */ - var query: IQueryTyped? + var query: IQuery? /** * 查询的View类型 */ - var viewClass: Class + var clazz: Class override fun doGet(key: TKey): HttpMessage { return this.doQuery("获取${this.name}数据失败") { - this.query!!.get(key, viewClass) + this.query!!.get(key, clazz) } } override fun doList(params: Map): HttpMessage { return this.doQuery("获取${this.name}列表数据失败") { - this.query!!.list(params, viewClass) + this.query!!.list(params, clazz) } } @@ -41,7 +40,7 @@ interface IQueryTypedApp : IApplication, IQueryApp { return this.doQuery("获取${this.name}分页数据[条数:$size,页码:$page]失败") { val data = PagingParam(page, size) data.parameters = params - this.query!!.paging(data, viewClass) + this.query!!.paging(data, clazz) } } diff --git a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryGenericApp.kt b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryGenericApp.kt index eae969f..63b2fce 100644 --- a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryGenericApp.kt +++ b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryGenericApp.kt @@ -1,17 +1,18 @@ package com.synebula.gaea.app.query import com.synebula.gaea.log.ILogger -import com.synebula.gaea.query.IQuery +import com.synebula.gaea.query.IGenericQuery /** * 联合服务,同时实现了ICommandApp和IQueryApp接口 * * @param name 业务名称 - * @param query 业务查询服务 + * @param genericQuery 业务查询服务 * @param logger 日志组件 */ open class QueryGenericApp( - override var name: String, - override var query: IQuery?, - override var logger: ILogger) : IQueryGenericApp { + override var name: String, + override var query: IGenericQuery?, + override var logger: ILogger +) : IQueryGenericApp { } \ No newline at end of file diff --git a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryTypedApp.kt b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryTypedApp.kt index 9462847..a8c2dec 100644 --- a/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryTypedApp.kt +++ b/src/gaea.app/src/main/kotlin/com/synebula/gaea/app/query/QueryTypedApp.kt @@ -1,7 +1,7 @@ package com.synebula.gaea.app.query import com.synebula.gaea.log.ILogger -import com.synebula.gaea.query.IQueryTyped +import com.synebula.gaea.query.IQuery /** * 联合服务,同时实现了ICommandApp和IQueryApp接口 @@ -11,8 +11,8 @@ import com.synebula.gaea.query.IQueryTyped * @param logger 日志组件 */ open class QueryTypedApp( - override var name: String, - override var viewClass: Class, - override var query: IQueryTyped?, - override var logger: ILogger) : IQueryTypedApp { + override var name: String, + override var clazz: Class, + override var query: IQuery?, + override var logger: ILogger) : IQueryTypedApp { } diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/MongoExt.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/MongoExt.kt index 0333976..0807da1 100644 --- a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/MongoExt.kt +++ b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/MongoExt.kt @@ -41,7 +41,7 @@ fun Query.where(params: Map?): Query { * * @param id 业务ID */ -fun whereId(id: TKey): Query = Query(Criteria("_id").isEqualTo(id)) +fun whereId(id: TKey): Query = Query.query(Criteria.where("_id").`is`(id)) /** * 获取排序对象 diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoGenericQuery.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoGenericQuery.kt new file mode 100644 index 0000000..1ae8521 --- /dev/null +++ b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoGenericQuery.kt @@ -0,0 +1,130 @@ +package com.synebula.gaea.mongo.query + +import com.synebula.gaea.extension.fields +import com.synebula.gaea.extension.firstCharLowerCase +import com.synebula.gaea.log.ILogger +import com.synebula.gaea.mongo.order +import com.synebula.gaea.mongo.select +import com.synebula.gaea.mongo.where +import com.synebula.gaea.mongo.whereId +import com.synebula.gaea.query.IGenericQuery +import com.synebula.gaea.query.PagingData +import com.synebula.gaea.query.PagingParam +import org.springframework.data.mongodb.core.MongoTemplate +import org.springframework.data.mongodb.core.query.Query + +/** + * 实现IQuery的Mongo查询类 + * @param template MongoRepo对象 + * @param logger 日志组件 + */ +open class MongoGenericQuery(var template: MongoTemplate, var logger: ILogger? = null) : IGenericQuery { + /** + * 查询的对象类 + */ + var clazz: Class? = null + + private var _collection = "" + + /** + * 查询的集合名称 + */ + var collection: String + set(value) { + this._collection = value + } + get() = if (this._collection.isNotEmpty()) + this._collection + else { + if (this.clazz != null) + this.clazz!!.simpleName.removeSuffix("View").firstCharLowerCase() + else + "" + } + + /** + * 构造方法 + * + * @param clazz 视图对象类型 + * @param query MongoRepo对象 + */ + constructor(clazz: Class, query: MongoTemplate) + : this(query) { + this.clazz = clazz + } + + /** + * 构造方法 + * + * @param collection 查询的集合名称 + * @param query MongoRepo对象 + */ + constructor(collection: String, query: MongoTemplate) + : this(query) { + this.collection = collection + } + + /** + * 构造方法 + * + * @param collection 查询的集合名称 + * @param clazz 视图对象类型 + * @param query MongoRepo对象 + */ + constructor(collection: String, clazz: Class, query: MongoTemplate) + : this(clazz, query) { + this.collection = collection + } + + + override fun list(params: Map?): List { + this.check() + return if (this.clazz != null) { + val fields = this.clazz!!.fields() + val query = Query() + query.select(fields.toTypedArray()) + query.where(params) + this.template.find(query, this.clazz!!, this.collection) + } else listOf() + } + + override fun count(params: Map?): Int { + this.check() + return if (this.clazz != null) { + val query = Query() + this.template.count(query.where(params), this.collection).toInt() + } else 0 + } + + override fun paging(params: PagingParam): PagingData { + this.check() + return if (this.clazz != null) { + val query = Query() + val fields = this.clazz!!.fields() + val result = PagingData(params.page, params.size) + query.where(params.parameters) + result.total = this.count(params.parameters) + query.select(fields.toTypedArray()) + query.with(order(params.orderBy)) + query.skip(params.index).limit(params.size) + result.data = this.template.find(query, this.clazz!!, this.collection) + result + } else PagingData(1, 10) + } + + override fun get(key: String): TView? { + this.check() + return if (this.clazz != null) { + val view = this.template.findOne(whereId(key), this.clazz!!, this.collection) + view + } else null + } + + protected fun check() { + if (this.clazz == null) + throw RuntimeException("[${this.javaClass.name}] 没有声明查询View的类型") + if (this._collection.isEmpty()) + this.logger?.warn(this, "查询集合参数[collection]值为空, 尝试使用View<${this.clazz?.name}>名称解析集合") + } + +} diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQuery.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQuery.kt index 5790625..709738b 100644 --- a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQuery.kt +++ b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQuery.kt @@ -12,119 +12,73 @@ import com.synebula.gaea.query.PagingData import com.synebula.gaea.query.PagingParam import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.query.Query +import java.lang.RuntimeException /** * 实现IQuery的Mongo查询类 - * @param template MongoRepo对象 - * @param logger 日志组件 + * @param repo MongoRepo对象 */ -open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null) : IQuery { - /** - * 查询的对象类 - */ - var clazz: Class? = null - private var _collection = "" +open class MongoQuery(var repo: MongoTemplate, var logger: ILogger? = null) : IQuery { /** * 查询的集合名称 + * + * 若没有为成员变量collection赋值,会尝试使用View名称解析集合名称。 + * 规则为移除View后缀并首字母小写,此时使用 */ - var collection: String - set(value) { - this._collection = value - } - get() = if (this._collection.isNotEmpty()) - this._collection - else { - if (this.clazz != null) - this.clazz!!.simpleName.removeSuffix("View").firstCharLowerCase() - else - "" - } + var collection: String = "" /** - * 构造方法 - * - * @param clazz 视图对象类型 - * @param query MongoRepo对象 + * 使用View解析是collection时是否校验存在,默认不校验 */ - constructor(clazz: Class, query: MongoTemplate) - : this(query) { - this.clazz = clazz + var validViewCollection = false + + override fun list(params: Map?, clazz: Class): List { + val fields = clazz.fields() + val query = Query() + query.where(params) + query.select(fields.toTypedArray()) + return this.repo.find(query, clazz, this.collection(clazz)) + } + + override fun count(params: Map?, clazz: Class): Int { + val query = Query() + return this.repo.count(query.where(params), this.collection(clazz)).toInt() + } + + override fun paging(params: PagingParam, clazz: Class): PagingData { + val fields = clazz.fields() + val result = PagingData(1, 10) + result.size = params.size + result.page = params.page + val query = Query() + query.where(params.parameters) + result.total = this.count(params.parameters, clazz) + query.select(fields.toTypedArray()) + query.with(order(params.orderBy)) + query.skip(params.index).limit(params.size) + result.data = this.repo.find(query, clazz, this.collection(clazz)) + return result + } + + override fun get(key: TKey, clazz: Class): TView? { + return this.repo.findOne(whereId(key), clazz, this.collection(clazz)) } /** - * 构造方法 - * - * @param collection 查询的集合名称 - * @param query MongoRepo对象 + * 获取collection */ - constructor(collection: String, query: MongoTemplate) - : this(query) { - this.collection = collection + protected fun collection(clazz: Class): String { + return if (this.collection.isEmpty()) { + this.logger?.info(this, "查询集合参数[collection]值为空, 尝试使用View<${clazz.name}>名称解析集合") + val collection = clazz.simpleName.removeSuffix("View").firstCharLowerCase() + if (!validViewCollection || this.repo.collectionExists(collection)) + collection + else { + throw RuntimeException("找不到名为[$collection]的集合") + } + } else + this.collection } - - /** - * 构造方法 - * - * @param collection 查询的集合名称 - * @param clazz 视图对象类型 - * @param query MongoRepo对象 - */ - constructor(collection: String, clazz: Class, query: MongoTemplate) - : this(clazz, query) { - this.collection = collection - } - - - override fun list(params: Map?): List { - this.check() - return if (this.clazz != null) { - val fields = this.clazz!!.fields() - val query = Query() - query.select(fields.toTypedArray()) - query.where(params) - this.template.find(query, this.clazz!!, this.collection) - } else listOf() - } - - override fun count(params: Map?): Int { - this.check() - return if (this.clazz != null) { - val query = Query() - this.template.count(query.where(params), this.collection).toInt() - } else 0 - } - - override fun paging(params: PagingParam): PagingData { - this.check() - return if (this.clazz != null) { - val query = Query() - val fields = this.clazz!!.fields() - val result = PagingData(params.page, params.size) - query.where(params.parameters) - result.total = this.count(params.parameters) - query.select(fields.toTypedArray()) - query.with(order(params.orderBy)) - query.skip(params.index).limit(params.size) - result.data = this.template.find(query, this.clazz!!, this.collection) - result - } else PagingData(1, 10) - } - - override fun get(key: String): TView? { - this.check() - return if (this.clazz != null) { - val view = this.template.findOne(whereId(key), this.clazz!!, this.collection) - view - } else null - } - - protected fun check() { - if (this.clazz == null) - throw RuntimeException("[${this.javaClass.name}] 没有声明查询View的类型") - if (this._collection.isEmpty()) - this.logger?.warn(this, "查询集合参数[collection]值为空, 尝试使用View<${this.clazz?.name}>名称解析集合") - } - } diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQueryTyped.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQueryTyped.kt deleted file mode 100644 index 22a32e2..0000000 --- a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/query/MongoQueryTyped.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.synebula.gaea.mongo.query - -import com.synebula.gaea.extension.fields -import com.synebula.gaea.extension.firstCharLowerCase -import com.synebula.gaea.log.ILogger -import com.synebula.gaea.mongo.order -import com.synebula.gaea.mongo.select -import com.synebula.gaea.mongo.where -import com.synebula.gaea.mongo.whereId -import com.synebula.gaea.query.IQueryTyped -import com.synebula.gaea.query.PagingData -import com.synebula.gaea.query.PagingParam -import org.springframework.data.mongodb.core.MongoTemplate -import org.springframework.data.mongodb.core.query.Query -import java.lang.RuntimeException - -/** - * 实现IQuery的Mongo查询类 - * @param repo MongoRepo对象 - */ - -open class MongoQueryTyped(var repo: MongoTemplate, var logger: ILogger? = null) : IQueryTyped { - - /** - * 查询的集合名称 - * - * 若没有为成员变量collection赋值,会尝试使用View名称解析集合名称。 - * 规则为移除View后缀并首字母小写,此时使用 - */ - var collection: String = "" - - /** - * 使用View解析是collection时是否校验存在,默认不校验 - */ - var validViewCollection = false - - override fun list(params: Map?, clazz: Class): List { - val fields = clazz.fields() - val query = Query() - query.where(params) - query.select(fields.toTypedArray()) - return this.repo.find(query, clazz, this.collection(clazz)) - } - - override fun count(params: Map?, clazz: Class): Int { - val query = Query() - return this.repo.count(query.where(params), this.collection(clazz)).toInt() - } - - override fun paging(params: PagingParam, clazz: Class): PagingData { - val fields = clazz.fields() - val result = PagingData(1, 10) - result.size = params.size - result.page = params.page - val query = Query() - query.where(params.parameters) - result.total = this.count(params.parameters, clazz) - query.select(fields.toTypedArray()) - query.with(order(params.orderBy)) - query.skip(params.index).limit(params.size) - result.data = this.repo.find(query, clazz, this.collection(clazz)) - return result - } - - override fun get(key: TKey, clazz: Class): TView? { - return this.repo.findOne(whereId(key), clazz, this.collection(clazz)) - } - - /** - * 获取collection - */ - protected fun collection(clazz: Class): String { - return if (this.collection.isEmpty()) { - this.logger?.info(this, "查询集合参数[collection]值为空, 尝试使用View<${clazz.name}>名称解析集合") - val collection = clazz.simpleName.removeSuffix("View").firstCharLowerCase() - if (!validViewCollection || this.repo.collectionExists(collection)) - collection - else { - throw RuntimeException("找不到名为[$collection]的集合") - } - } else - this.collection - } -} diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoGenericRepository.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoGenericRepository.kt new file mode 100644 index 0000000..93d0d92 --- /dev/null +++ b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoGenericRepository.kt @@ -0,0 +1,51 @@ +package com.synebula.gaea.mongo.repository + +import com.synebula.gaea.domain.model.IAggregateRoot +import com.synebula.gaea.domain.repository.IGenericRepository +import com.synebula.gaea.mongo.whereId +import org.springframework.data.mongodb.core.MongoTemplate + +/** + * 实现IAggregateRoot的mongo仓储类 + * @param repo MongoRepo对象 + */ +class MongoGenericRepository>(private var repo: MongoTemplate) : + IGenericRepository { + + /** + * 仓储的对象类 + */ + override var clazz: Class? = null + + /** + * 构造 + * @param clazz 仓储Domain对象 + * @param repo MongoRepo对象 + */ + constructor(clazz: Class, repo: MongoTemplate) : this(repo) { + this.clazz = clazz + } + + override fun add(obj: TAggregateRoot) { + this.repo.save(obj) + } + + override fun update(obj: TAggregateRoot) { + this.repo.save(obj) + } + + override fun remove(id: String) { + this.repo.remove(whereId(id), this.clazz!!) + } + + override fun get(id: String): TAggregateRoot { + return this.repo.findOne(whereId(id), clazz!!) as TAggregateRoot + } + + override fun , TKey> get( + id: TKey, + clazz: Class + ): TAggregateRoot { + return this.repo.findOne(whereId(id.toString()), clazz) as TAggregateRoot + } +} diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepository.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepository.kt index 22d14f4..d212882 100644 --- a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepository.kt +++ b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepository.kt @@ -6,43 +6,30 @@ import com.synebula.gaea.mongo.whereId import org.springframework.data.mongodb.core.MongoTemplate /** - * 实现IAggregateRoot的mongo仓储类 + * 实现ITypedRepository的mongo仓储类 * @param repo MongoRepo对象 */ -class MongoRepository>(private var repo: MongoTemplate) - : IRepository { +open class MongoRepository(private var repo: MongoTemplate) : IRepository { - /** - * 仓储的对象类 - */ - override var clazz: Class? = null - - /** - * 构造 - * @param clazz 仓储Domain对象 - * @param repo MongoRepo对象 - */ - constructor(clazz: Class, repo: MongoTemplate) : this(repo) { - this.clazz = clazz + override fun , TKey> remove(id: TKey, clazz: Class) { + this.repo.remove(whereId(id), clazz) } - override fun add(obj: TAggregateRoot) { + override fun , TKey> get( + id: TKey, + clazz: Class + ): TAggregateRoot { + return this.repo.findOne(whereId(id), clazz) as TAggregateRoot + } + + override fun , TKey> update( + obj: TAggregateRoot, + clazz: Class + ) { this.repo.save(obj) } - override fun update(obj: TAggregateRoot) { + override fun , TKey> add(obj: TAggregateRoot, clazz: Class) { this.repo.save(obj) } - - override fun remove(id: String) { - this.repo.remove(whereId(id), this.clazz!!) - } - - override fun get(id: String): TAggregateRoot { - return this.repo.findOne(whereId(id), clazz!!) as TAggregateRoot - } - - override fun , TKey> get(id: TKey, clazz: Class): TAggregateRoot { - return this.repo.findOne(whereId(id.toString()), clazz) as TAggregateRoot - } } diff --git a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepositoryTyped.kt b/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepositoryTyped.kt deleted file mode 100644 index 8e6e80b..0000000 --- a/src/gaea.mongo/src/main/kotlin/com/synebula/gaea/mongo/repository/MongoRepositoryTyped.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.synebula.gaea.mongo.repository - -import com.synebula.gaea.domain.model.IAggregateRoot -import com.synebula.gaea.domain.repository.IRepositoryTyped -import com.synebula.gaea.mongo.whereId -import org.springframework.data.mongodb.core.MongoTemplate - -/** - * 实现ITypedRepository的mongo仓储类 - * @param repo MongoRepo对象 - */ -open class MongoRepositoryTyped(private var repo: MongoTemplate) - : IRepositoryTyped { - - override fun , TKey> remove(id: TKey, clazz: Class) { - this.repo.remove(whereId(id), clazz) - } - - override fun , TKey> get(id: TKey, clazz: Class): TAggregateRoot { - return this.repo.findOne(whereId(id), clazz) as TAggregateRoot - } - - override fun , TKey> update(obj: TAggregateRoot, clazz: Class) { - this.repo.save(obj) - } - - override fun , TKey> add(obj: TAggregateRoot, clazz: Class) { - this.repo.save(obj) - } -} diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryComplex.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IComplexRepository.kt similarity index 93% rename from src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryComplex.kt rename to src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IComplexRepository.kt index 6df44ee..cacc48d 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryComplex.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IComplexRepository.kt @@ -8,7 +8,7 @@ import com.synebula.gaea.domain.model.complex.IComplexAggregateRoot * @param this T is the parameter * @author alex */ -interface IRepositoryComplex, TKey, TSecond> { +interface IComplexRepository, TKey, TSecond> { /** * 插入单个对象。 diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IGenericRepository.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IGenericRepository.kt new file mode 100644 index 0000000..3850107 --- /dev/null +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IGenericRepository.kt @@ -0,0 +1,61 @@ +package com.synebula.gaea.domain.repository + +import com.synebula.gaea.domain.model.IAggregateRoot + +/** + * 继承本接口表示对象为仓储类。 + * 定义了提供增删改的仓储接口。 + * 本接口泛型定义在类上,不需要显式提供聚合根的class对象,class对象作为类的成员变量声明。 + * + * @param this T is the parameter + * @author alex + */ +interface IGenericRepository, TKey> { + + /** + * 仓储的对象类 + */ + var clazz: Class? + + /** + * 插入单个对象。 + * + * @param obj 需要插入的对象。 + * @return 返回原对象,如果对象ID为自增,则补充自增ID。 + */ + fun add(obj: TAggregateRoot) + + /** + * 更新对象。 + * + * @param obj 需要更新的对象。 + * @return + */ + fun update(obj: TAggregateRoot) + + /** + * 通过id删除该条数据 + * + * @param id + * @return + */ + fun remove(id: TKey) + + /** + * 根据ID获取对象。 + * + * @param id 对象ID。 + * @return + */ + fun get(id: TKey): TAggregateRoot + + /** + * 根据ID获取对象。 + * + * @param id id + * @param clazz 操作数据的类型 + * @return 聚合根 + */ + fun , TKey> get(id: TKey, clazz: Class): T + +} diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepository.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepository.kt index ff7bd56..ba452e9 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepository.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepository.kt @@ -3,27 +3,17 @@ package com.synebula.gaea.domain.repository import com.synebula.gaea.domain.model.IAggregateRoot /** - * 继承本接口表示对象为仓储类。 * 定义了提供增删改的仓储接口。 - * 本接口泛型定义在类上,不需要显式提供聚合根的class对象,class对象作为类的成员变量声明。 - * - * @param this T is the parameter - * @author alex + * 本接口泛型放置到方法上,并需要显式提供聚合根的class对象 */ -interface IRepository, TKey> { - - /** - * 仓储的对象类 - */ - var clazz: Class? - +interface IRepository { /** * 插入单个对象。 * * @param obj 需要插入的对象。 * @return 返回原对象,如果对象ID为自增,则补充自增ID。 */ - fun add(obj: TAggregateRoot) + fun , TKey> add(obj: TAggregateRoot, clazz: Class) /** * 更新对象。 @@ -31,23 +21,15 @@ interface IRepository, TKey> { * @param obj 需要更新的对象。 * @return */ - fun update(obj: TAggregateRoot) + fun , TKey> update(obj: TAggregateRoot, clazz: Class) /** * 通过id删除该条数据 * - * @param id - * @return + * @param id id + * @param clazz 操作数据的类型 */ - fun remove(id: TKey) - - /** - * 根据ID获取对象。 - * - * @param id 对象ID。 - * @return - */ - fun get(id: TKey): TAggregateRoot + fun , TKey> remove(id: TKey, clazz: Class) /** * 根据ID获取对象。 @@ -56,6 +38,5 @@ interface IRepository, TKey> { * @param clazz 操作数据的类型 * @return 聚合根 */ - fun , TKey> get(id: TKey, clazz: Class): T - + fun , TKey> get(id: TKey, clazz: Class): TAggregateRoot } diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryTyped.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryTyped.kt deleted file mode 100644 index d00164d..0000000 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/repository/IRepositoryTyped.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.synebula.gaea.domain.repository - -import com.synebula.gaea.domain.model.IAggregateRoot - -/** - * 定义了提供增删改的仓储接口。 - * 本接口泛型放置到方法上,并需要显式提供聚合根的class对象 - */ -interface IRepositoryTyped { - /** - * 插入单个对象。 - * - * @param obj 需要插入的对象。 - * @return 返回原对象,如果对象ID为自增,则补充自增ID。 - */ - fun , TKey> add(obj: TAggregateRoot, clazz: Class) - - /** - * 更新对象。 - * - * @param obj 需要更新的对象。 - * @return - */ - fun , TKey> update(obj: TAggregateRoot, clazz: Class) - - /** - * 通过id删除该条数据 - * - * @param id id - * @param clazz 操作数据的类型 - */ - fun , TKey> remove(id: TKey, clazz: Class) - - /** - * 根据ID获取对象。 - * - * @param id id - * @param clazz 操作数据的类型 - * @return 聚合根 - */ - fun , TKey> get(id: TKey, clazz: Class): TAggregateRoot -} diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ServiceComplex.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ComplexService.kt similarity index 73% rename from src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ServiceComplex.kt rename to src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ComplexService.kt index e907788..42b26a1 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ServiceComplex.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ComplexService.kt @@ -3,7 +3,7 @@ package com.synebula.gaea.domain.service import com.synebula.gaea.data.IObjectConverter import com.synebula.gaea.data.message.Message import com.synebula.gaea.domain.model.complex.IComplexAggregateRoot -import com.synebula.gaea.domain.repository.IRepositoryComplex +import com.synebula.gaea.domain.repository.IComplexRepository import com.synebula.gaea.log.ILogger /** @@ -13,10 +13,12 @@ import com.synebula.gaea.log.ILogger * @version 0.1 * @since 2020-05-15 */ -open class ServiceComplex, TKey, TSecond> -(var logger: ILogger, protected var repository: IRepositoryComplex, - protected var converter: IObjectConverter, protected var aggregateRootClass: Class) - : IServiceComplex { +open class ComplexService, TKey, TSecond>( + protected var clazz: Class, + protected var repository: IComplexRepository, + protected var converter: IObjectConverter, + override var logger: ILogger +) : IComplexService { override fun add(command: ICommand): Message> { val msg = Message>() @@ -45,7 +47,7 @@ open class ServiceComplex, */ protected fun convert(command: ICommand): TAggregateRoot { try { - return converter.convert(command, aggregateRootClass) + return converter.convert(command, clazz) } catch (ex: Exception) { throw RuntimeException("command not match aggregate root", ex) } diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ServiceTyped.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/GenericService.kt similarity index 55% rename from src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ServiceTyped.kt rename to src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/GenericService.kt index 2126c23..b236298 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/ServiceTyped.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/GenericService.kt @@ -3,32 +3,36 @@ package com.synebula.gaea.domain.service import com.synebula.gaea.data.IObjectConverter import com.synebula.gaea.data.message.Message import com.synebula.gaea.domain.model.IAggregateRoot -import com.synebula.gaea.domain.repository.IRepositoryTyped +import com.synebula.gaea.domain.repository.IGenericRepository import com.synebula.gaea.log.ILogger /** - * 依赖了IRepositoryTyped仓储借口的服务实现类 ServiceTyped - * 该类依赖仓储接口 @see IRepositoryTyped ,需要显式提供聚合根的class对象 + * class FlatService * * @param repository 仓储对象 - * @param rootClass 聚合根类对象 + * @param clazz 聚合根类对象 * @param converter 对象转换组件 * @param logger 日志组件 * @author alex * @version 0.1 - * @since 2020-05-17 + * @since 2020-05-15 */ -open class ServiceTyped, TKey>( - protected var rootClass: Class, - protected var repository: IRepositoryTyped, - protected var converter: IObjectConverter, - override var logger: ILogger) : IService { +open class GenericService, TKey>( + protected var clazz: Class, + protected var repository: IGenericRepository, + protected var converter: IObjectConverter, + override var logger: ILogger +) : IService { + + init { + this.repository.clazz = clazz + } override fun add(command: ICommand): Message { val msg = Message() val root = this.convert(command) - this.repository.add(root, rootClass) + this.repository.add(root) msg.data = root.id return msg } @@ -36,24 +40,29 @@ open class ServiceTyped, TKey>( override fun update(key: TKey, command: ICommand) { val root = this.convert(command) root.id = key - this.repository.update(root, rootClass) + this.repository.update(root) } override fun remove(key: TKey) { - this.repository.remove(key, rootClass) + this.repository.remove(key) + } + + fun get(key: TKey): TAggregateRoot { + return this.repository.get(key) } /** * 转换ICommand类型到聚合根类型,默认实现,根据需要进行覆写。 * - * @param command 需要转换的命令 - * @return 聚合根 + * @param command + * @return */ protected fun convert(command: ICommand): TAggregateRoot { try { - return converter.convert(command, rootClass) + return converter.convert(command, this.clazz) } catch (ex: Exception) { throw RuntimeException("command not match aggregate root", ex) } + } } diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IServiceComplex.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IComplexService.kt similarity index 71% rename from src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IServiceComplex.kt rename to src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IComplexService.kt index 13a545c..0da83b6 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IServiceComplex.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IComplexService.kt @@ -1,6 +1,7 @@ package com.synebula.gaea.domain.service import com.synebula.gaea.data.message.Message +import com.synebula.gaea.log.ILogger /** * class IFlatService @@ -9,7 +10,11 @@ import com.synebula.gaea.data.message.Message * @version 0.1 * @since 2020-05-15 */ -interface IServiceComplex { +interface IComplexService { + /** + * 日志组件。 + */ + var logger: ILogger fun add(command: ICommand): Message> diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IService.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IService.kt index 8a56335..cc8fc3a 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IService.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/IService.kt @@ -13,7 +13,7 @@ import com.synebula.gaea.log.ILogger */ interface IService { /** - * 日志组件。若无日志组件则默认为NullLogger对象,不会为null。 + * 日志组件。 */ var logger: ILogger diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/Service.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/Service.kt index e801806..fde1df5 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/Service.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/domain/service/Service.kt @@ -8,30 +8,28 @@ import com.synebula.gaea.log.ILogger /** - * class FlatService + * 依赖了IRepositoryTyped仓储借口的服务实现类 ServiceTyped + * 该类依赖仓储接口 @see IRepositoryTyped ,需要显式提供聚合根的class对象 * * @param repository 仓储对象 - * @param rootClass 聚合根类对象 + * @param clazz 聚合根类对象 * @param converter 对象转换组件 * @param logger 日志组件 * @author alex * @version 0.1 - * @since 2020-05-15 + * @since 2020-05-17 */ open class Service, TKey>( - protected var rootClass: Class, - protected var repository: IRepository, - protected var converter: IObjectConverter, - override var logger: ILogger) : IService { - - init { - this.repository.clazz = rootClass - } + protected var clazz: Class, + protected var repository: IRepository, + protected var converter: IObjectConverter, + override var logger: ILogger +) : IService { override fun add(command: ICommand): Message { val msg = Message() val root = this.convert(command) - this.repository.add(root) + this.repository.add(root, this.clazz) msg.data = root.id return msg } @@ -39,29 +37,24 @@ open class Service, TKey>( override fun update(key: TKey, command: ICommand) { val root = this.convert(command) root.id = key - this.repository.update(root) + this.repository.update(root, this.clazz) } override fun remove(key: TKey) { - this.repository.remove(key) - } - - fun get(key: TKey): TAggregateRoot { - return this.repository.get(key) + this.repository.remove(key, this.clazz) } /** * 转换ICommand类型到聚合根类型,默认实现,根据需要进行覆写。 * - * @param command - * @return + * @param command 需要转换的命令 + * @return 聚合根 */ protected fun convert(command: ICommand): TAggregateRoot { try { - return converter.convert(command, rootClass) + return converter.convert(command, this.clazz) } catch (ex: Exception) { throw RuntimeException("command not match aggregate root", ex) } - } } diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/query/IQueryTyped.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/query/IGenericQuery.kt similarity index 59% rename from src/gaea/src/main/kotlin/com/synebula/gaea/query/IQueryTyped.kt rename to src/gaea/src/main/kotlin/com/synebula/gaea/query/IGenericQuery.kt index 93221ac..1900e13 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/query/IQueryTyped.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/query/IGenericQuery.kt @@ -1,18 +1,20 @@ package com.synebula.gaea.query /** - * 查询基接口, 其中方法都指定了查询的视图类型。 + * 查询基接口。 * * @author alex */ -interface IQueryTyped { +interface IGenericQuery { + + /** * 根据Key获取对象。 * * @param key 对象Key。 * @return */ - fun get(key: TKey, clazz: Class): TView? + fun get(key: TKey): TView? /** * 根据实体类条件查询所有符合条件记录 @@ -20,7 +22,7 @@ interface IQueryTyped { * @param params 查询条件。 * @return list */ - fun list(params: Map?, clazz: Class): List + fun list(params: Map?): List /** * 根据条件查询符合条件记录的数量 @@ -28,7 +30,7 @@ interface IQueryTyped { * @param params 查询条件。 * @return int */ - fun count(params: Map?, clazz: Class): Int + fun count(params: Map?): Int /** * 根据实体类条件查询所有符合条件记录(分页查询) @@ -36,5 +38,5 @@ interface IQueryTyped { * @param params 分页条件 * @return 分页数据 */ - fun paging(params: PagingParam, clazz: Class): PagingData + fun paging(params: PagingParam): PagingData } diff --git a/src/gaea/src/main/kotlin/com/synebula/gaea/query/IQuery.kt b/src/gaea/src/main/kotlin/com/synebula/gaea/query/IQuery.kt index 3ae09bc..96dcbb9 100644 --- a/src/gaea/src/main/kotlin/com/synebula/gaea/query/IQuery.kt +++ b/src/gaea/src/main/kotlin/com/synebula/gaea/query/IQuery.kt @@ -1,20 +1,18 @@ package com.synebula.gaea.query /** - * 查询基接口。 + * 查询基接口, 其中方法都指定了查询的视图类型。 * * @author alex */ -interface IQuery { - - +interface IQuery { /** * 根据Key获取对象。 * * @param key 对象Key。 * @return */ - fun get(key: TKey): TView? + fun get(key: TKey, clazz: Class): TView? /** * 根据实体类条件查询所有符合条件记录 @@ -22,7 +20,7 @@ interface IQuery { * @param params 查询条件。 * @return list */ - fun list(params: Map?): List + fun list(params: Map?, clazz: Class): List /** * 根据条件查询符合条件记录的数量 @@ -30,7 +28,7 @@ interface IQuery { * @param params 查询条件。 * @return int */ - fun count(params: Map?): Int + fun count(params: Map?, clazz: Class): Int /** * 根据实体类条件查询所有符合条件记录(分页查询) @@ -38,5 +36,5 @@ interface IQuery { * @param params 分页条件 * @return 分页数据 */ - fun paging(params: PagingParam): PagingData + fun paging(params: PagingParam, clazz: Class): PagingData }