精简代码:删除Specific相关代码
修改mongo query获取字段范围值类型
This commit is contained in:
@@ -1,70 +0,0 @@
|
|||||||
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.ISpecificQuery
|
|
||||||
import com.synebula.gaea.query.Params
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用类接口,提供实现Query服务的接口
|
|
||||||
* 依赖查询接口 @see IQuery
|
|
||||||
*
|
|
||||||
* @author alex
|
|
||||||
* @version 0.1
|
|
||||||
* @since 2020-05-15
|
|
||||||
*/
|
|
||||||
interface ISpecificQueryApp<TView, TKey> : IApplication {
|
|
||||||
/**
|
|
||||||
* 查询服务
|
|
||||||
*/
|
|
||||||
var query: ISpecificQuery<TView, TKey>?
|
|
||||||
|
|
||||||
@GetMapping("/{id:.+}")
|
|
||||||
fun get(@PathVariable id: TKey): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}数据失败") {
|
|
||||||
this.query!!.get(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
fun list(@RequestParam params: MutableMap<String, Any>): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}列表数据失败") {
|
|
||||||
this.query!!.list(params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/segments/{size}/pages/{page}")
|
|
||||||
fun paging(
|
|
||||||
@PathVariable size: Int,
|
|
||||||
@PathVariable page: Int,
|
|
||||||
@RequestParam parameters: MutableMap<String, Any>
|
|
||||||
): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}分页数据[条数:$size,页码:$page]失败") {
|
|
||||||
val data = Params(page, size)
|
|
||||||
data.parameters = parameters
|
|
||||||
this.query!!.paging(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 抽取查询业务判断功能
|
|
||||||
*
|
|
||||||
* @param error 错误消息
|
|
||||||
* @param biz 业务执行逻辑
|
|
||||||
*/
|
|
||||||
fun doQuery(error: String, biz: (() -> Any?)): HttpMessage {
|
|
||||||
return this.safeExecute(error) {
|
|
||||||
if (this.query != null) {
|
|
||||||
it.data = biz()
|
|
||||||
} else {
|
|
||||||
it.status = Status.Error
|
|
||||||
it.message = "没有对应服务,无法执行该操作"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.synebula.gaea.app.query
|
|
||||||
|
|
||||||
import com.synebula.gaea.log.ILogger
|
|
||||||
import com.synebula.gaea.query.ISpecificQuery
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
|
||||||
*
|
|
||||||
* @param name 业务名称
|
|
||||||
* @param query 业务查询服务
|
|
||||||
* @param logger 日志组件
|
|
||||||
*/
|
|
||||||
open class SpecificQueryApp<TView, TKey>(
|
|
||||||
override var name: String,
|
|
||||||
override var query: ISpecificQuery<TView, TKey>?,
|
|
||||||
override var logger: ILogger?
|
|
||||||
) : ISpecificQueryApp<TView, TKey>
|
|
||||||
@@ -30,7 +30,7 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
|
|||||||
val fields = this.fields(clazz)
|
val fields = this.fields(clazz)
|
||||||
val query = Query()
|
val query = Query()
|
||||||
query.where(params, clazz)
|
query.where(params, clazz)
|
||||||
query.select(fields.toTypedArray())
|
query.select(fields)
|
||||||
return this.template.find(query, clazz, this.collection(clazz))
|
return this.template.find(query, clazz, this.collection(clazz))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
|
|||||||
params.page -= 1
|
params.page -= 1
|
||||||
result.page -= 1
|
result.page -= 1
|
||||||
}
|
}
|
||||||
query.select(fields.toTypedArray())
|
query.select(fields)
|
||||||
query.where(params.parameters, clazz)
|
query.where(params.parameters, clazz)
|
||||||
query.with(order(params.orders))
|
query.with(order(params.orders))
|
||||||
query.skip(params.index).limit(params.size)
|
query.skip(params.index).limit(params.size)
|
||||||
@@ -61,7 +61,7 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
|
|||||||
return this.template.findOne(whereId(id), clazz, this.collection(clazz))
|
return this.template.findOne(whereId(id), clazz, this.collection(clazz))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <TView> fields(clazz: Class<TView>): List<String> {
|
fun <TView> fields(clazz: Class<TView>): Array<String> {
|
||||||
val fields = mutableListOf<String>()
|
val fields = mutableListOf<String>()
|
||||||
fields.addAll(clazz.fieldNames())
|
fields.addAll(clazz.fieldNames())
|
||||||
var parent = clazz.superclass
|
var parent = clazz.superclass
|
||||||
@@ -69,7 +69,7 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
|
|||||||
fields.addAll(clazz.superclass.fieldNames())
|
fields.addAll(clazz.superclass.fieldNames())
|
||||||
parent = parent.superclass
|
parent = parent.superclass
|
||||||
}
|
}
|
||||||
return fields
|
return fields.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,146 +0,0 @@
|
|||||||
package com.synebula.gaea.mongo.query
|
|
||||||
|
|
||||||
import com.synebula.gaea.ext.fieldNames
|
|
||||||
import com.synebula.gaea.ext.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.ISpecificQuery
|
|
||||||
import com.synebula.gaea.query.Page
|
|
||||||
import com.synebula.gaea.query.Params
|
|
||||||
import com.synebula.gaea.query.annotation.Table
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate
|
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现IQuery的Mongo查询类
|
|
||||||
* @param clazz 查询的对象类
|
|
||||||
* @param template MongoRepo对象
|
|
||||||
* @param logger 日志组件
|
|
||||||
*/
|
|
||||||
open class MongoSpecificQuery<TView>(
|
|
||||||
var template: MongoTemplate,
|
|
||||||
var clazz: Class<TView>? = null,
|
|
||||||
var logger: ILogger? = null
|
|
||||||
) : ISpecificQuery<TView, String> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用View解析是collection时是否校验存在,默认不校验
|
|
||||||
*/
|
|
||||||
var validViewCollection = false
|
|
||||||
|
|
||||||
private var _collection = ""
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询的集合名称
|
|
||||||
*/
|
|
||||||
var collection: String
|
|
||||||
set(value) {
|
|
||||||
this._collection = value
|
|
||||||
}
|
|
||||||
get() = if (this._collection.isNotEmpty())
|
|
||||||
this._collection
|
|
||||||
else {
|
|
||||||
this.collection(this.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<TView>, query: MongoTemplate)
|
|
||||||
: this(query, clazz) {
|
|
||||||
this.collection = collection
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun list(params: Map<String, Any>?): List<TView> {
|
|
||||||
this.check()
|
|
||||||
return if (this.clazz != null) {
|
|
||||||
val fields = this.clazz!!.fieldNames()
|
|
||||||
val query = Query()
|
|
||||||
query.select(fields.toTypedArray())
|
|
||||||
query.where(params, this.clazz!!)
|
|
||||||
this.template.find(query, this.clazz!!, this.collection)
|
|
||||||
} else listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun count(params: Map<String, Any>?): Int {
|
|
||||||
this.check()
|
|
||||||
return if (this.clazz != null) {
|
|
||||||
val query = Query()
|
|
||||||
this.template.count(query.where(params, this.clazz!!), this.collection).toInt()
|
|
||||||
} else 0
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun paging(param: Params): Page<TView> {
|
|
||||||
this.check()
|
|
||||||
return if (this.clazz != null) {
|
|
||||||
val query = Query()
|
|
||||||
val fields = this.clazz!!.fieldNames()
|
|
||||||
val result = Page<TView>(param.page, param.size)
|
|
||||||
result.total = this.count(param.parameters)
|
|
||||||
//如果总数和索引相同,说明该页没有数据,直接跳到上一页
|
|
||||||
if (result.total == result.index) {
|
|
||||||
param.page -= 1
|
|
||||||
result.page -= 1
|
|
||||||
}
|
|
||||||
query.select(fields.toTypedArray())
|
|
||||||
query.where(param.parameters, this.clazz!!)
|
|
||||||
query.with(order(param.orders))
|
|
||||||
query.skip(param.index).limit(param.size)
|
|
||||||
result.data = this.template.find(query, this.clazz!!, this.collection)
|
|
||||||
result
|
|
||||||
} else Page(1, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(id: String): TView? {
|
|
||||||
this.check()
|
|
||||||
return if (this.clazz != null) {
|
|
||||||
val view = this.template.findOne(whereId(id), 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}>名称解析集合")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取collection
|
|
||||||
*/
|
|
||||||
protected fun <TView> collection(clazz: Class<TView>?): String {
|
|
||||||
if (clazz == null) throw java.lang.RuntimeException("[${this.javaClass}]没有指定查询实体类型[clazz]")
|
|
||||||
val collection = clazz.getDeclaredAnnotation(Table::class.java)
|
|
||||||
return if (collection != null)
|
|
||||||
return collection.name
|
|
||||||
else {
|
|
||||||
this.logger?.info(this, "视图类没有标记[Collection]注解,无法获取Collection名称。尝试使用View<${clazz.name}>名称解析集合")
|
|
||||||
val name = clazz.simpleName.removeSuffix("View").firstCharLowerCase()
|
|
||||||
if (!validViewCollection || this.template.collectionExists(name))
|
|
||||||
name
|
|
||||||
else {
|
|
||||||
throw RuntimeException("找不到名为[$collection]的集合")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package com.synebula.gaea.mongo.repository
|
|
||||||
|
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
|
||||||
import com.synebula.gaea.domain.repository.ISpecificRepository
|
|
||||||
import com.synebula.gaea.mongo.where
|
|
||||||
import com.synebula.gaea.mongo.whereId
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate
|
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现IAggregateRoot的mongo仓储类
|
|
||||||
* @param repo MongoRepo对象
|
|
||||||
*/
|
|
||||||
class MongoSpecificRepository<TAggregateRoot : IAggregateRoot<String>>(private var repo: MongoTemplate) :
|
|
||||||
ISpecificRepository<TAggregateRoot, String> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 仓储的对象类
|
|
||||||
*/
|
|
||||||
override var clazz: Class<TAggregateRoot>? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造
|
|
||||||
* @param clazz 仓储Domain对象
|
|
||||||
* @param repo MongoRepo对象
|
|
||||||
*/
|
|
||||||
constructor(clazz: Class<TAggregateRoot>, 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 <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(
|
|
||||||
id: TKey,
|
|
||||||
clazz: Class<TAggregateRoot>
|
|
||||||
): TAggregateRoot {
|
|
||||||
return this.repo.findOne(whereId(id.toString()), clazz) as TAggregateRoot
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun <TAggregateRoot> count(params: Map<String, Any>?): Int {
|
|
||||||
val query = Query()
|
|
||||||
return this.repo.count(query.where(params, this.clazz!!), this.clazz!!).toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
package com.synebula.gaea.domain.service
|
|
||||||
|
|
||||||
import com.synebula.gaea.data.IObjectConverter
|
|
||||||
import com.synebula.gaea.data.message.DataMessage
|
|
||||||
import com.synebula.gaea.data.message.Message
|
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
|
||||||
import com.synebula.gaea.domain.repository.ISpecificRepository
|
|
||||||
import com.synebula.gaea.log.ILogger
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 依赖了ISpecificRepository仓储借口的服务实现类 Service
|
|
||||||
* 该类依赖仓储接口 @see ISpecificRepository, 泛型类上指定了仓储实例的类型
|
|
||||||
*
|
|
||||||
* @param repository 仓储对象
|
|
||||||
* @param clazz 聚合根类对象
|
|
||||||
* @param converter 对象转换组件
|
|
||||||
* @param logger 日志组件
|
|
||||||
* @author alex
|
|
||||||
* @version 0.1
|
|
||||||
* @since 2020-05-15
|
|
||||||
*/
|
|
||||||
open class SpecificService<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
|
||||||
protected var clazz: Class<TAggregateRoot>,
|
|
||||||
protected var repository: ISpecificRepository<TAggregateRoot, TKey>,
|
|
||||||
protected var converter: IObjectConverter,
|
|
||||||
override var logger: ILogger
|
|
||||||
) : IService<TKey> {
|
|
||||||
|
|
||||||
init {
|
|
||||||
this.repository.clazz = clazz
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除对象前执行监听器。
|
|
||||||
*/
|
|
||||||
protected val beforeRemoveListeners = mutableMapOf<String, (id: TKey) -> Message>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一个删除对象前执行监听器。
|
|
||||||
* @param key 监听器标志。
|
|
||||||
* @param func 监听方法。
|
|
||||||
*/
|
|
||||||
override fun addBeforeRemoveListener(key: String, func: (id: TKey) -> Message) {
|
|
||||||
this.beforeRemoveListeners[key] = func
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除一个删除对象前执行监听器。
|
|
||||||
* @param key 监听器标志。
|
|
||||||
*/
|
|
||||||
override fun removeBeforeRemoveListener(key: String) {
|
|
||||||
this.beforeRemoveListeners.remove(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun add(command: ICommand): DataMessage<TKey> {
|
|
||||||
val msg = DataMessage<TKey>()
|
|
||||||
val root = this.convert(command)
|
|
||||||
this.repository.add(root)
|
|
||||||
msg.data = root.id
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun update(id: TKey, command: ICommand) {
|
|
||||||
val root = this.convert(command)
|
|
||||||
root.id = id
|
|
||||||
this.repository.update(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun remove(id: TKey) {
|
|
||||||
val functions = this.beforeRemoveListeners.values
|
|
||||||
var msg: Message
|
|
||||||
for (func in functions) {
|
|
||||||
msg = func(id)
|
|
||||||
if (!msg.success) {
|
|
||||||
throw java.lang.RuntimeException(msg.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.repository.remove(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun get(id: TKey): TAggregateRoot {
|
|
||||||
return this.repository.get(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换ICommand类型到聚合根类型,默认实现,根据需要进行覆写。
|
|
||||||
*
|
|
||||||
* @param command
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected fun convert(command: ICommand): TAggregateRoot {
|
|
||||||
try {
|
|
||||||
return converter.convert(command, this.clazz)
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
throw RuntimeException("command not match aggregate root", ex)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.synebula.gaea.query
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询基接口。
|
|
||||||
*
|
|
||||||
* @author alex
|
|
||||||
*/
|
|
||||||
interface ISpecificQuery<TView, TKey> {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据Key获取对象。
|
|
||||||
*
|
|
||||||
* @param key 对象Key。
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
fun get(id: TKey): TView?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据实体类条件查询所有符合条件记录
|
|
||||||
*
|
|
||||||
* @param params 查询条件。
|
|
||||||
* @return list
|
|
||||||
*/
|
|
||||||
fun list(params: Map<String, Any>?): List<TView>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件查询符合条件记录的数量
|
|
||||||
*
|
|
||||||
* @param params 查询条件。
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
fun count(params: Map<String, Any>?): Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据实体类条件查询所有符合条件记录(分页查询)
|
|
||||||
*
|
|
||||||
* @param param 分页条件
|
|
||||||
* @return 分页数据
|
|
||||||
*/
|
|
||||||
fun paging(param: Params): Page<TView>
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user