重构Gaea服务, 升级版本
This commit is contained in:
@@ -21,7 +21,7 @@ allprojects {
|
|||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
ext {
|
ext {
|
||||||
version '0.3.2'
|
version '0.4.0'
|
||||||
spring_version = "2.3.0.RELEASE"
|
spring_version = "2.3.0.RELEASE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app
|
||||||
|
|
||||||
import com.synebula.gaea.app.cmd.ICommandApp
|
import com.synebula.gaea.app.cmd.ICommandApp
|
||||||
import com.synebula.gaea.app.query.IQueryTypedApp
|
import com.synebula.gaea.app.query.IQueryApp
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
||||||
import com.synebula.gaea.domain.service.ICommand
|
import com.synebula.gaea.domain.service.ICommand
|
||||||
import com.synebula.gaea.domain.service.IService
|
import com.synebula.gaea.domain.service.IService
|
||||||
@@ -17,13 +17,13 @@ import javax.annotation.Resource
|
|||||||
* @param query 业务查询服务
|
* @param query 业务查询服务
|
||||||
* @param logger 日志组件
|
* @param logger 日志组件
|
||||||
*/
|
*/
|
||||||
open class UnionApp<TCommand : ICommand, TView, TKey>(
|
open class Application<TCommand : ICommand, TView, TKey>(
|
||||||
override var name: String,
|
override var name: String,
|
||||||
override var clazz: Class<TView>,
|
override var clazz: Class<TView>,
|
||||||
override var service: IService<TKey>?,
|
override var service: IService<TKey>?,
|
||||||
override var query: IQuery?,
|
override var query: IQuery?,
|
||||||
override var logger: ILogger)
|
override var logger: ILogger?
|
||||||
: ICommandApp<TCommand, TKey>, IQueryTypedApp<TView, TKey> {
|
) : ICommandApp<TCommand, TKey>, IQueryApp<TView, TKey> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
override var jsonSerializer: IJsonSerializer? = null
|
||||||
@@ -14,7 +14,7 @@ interface IApplication {
|
|||||||
/**
|
/**
|
||||||
* 日志组件
|
* 日志组件
|
||||||
*/
|
*/
|
||||||
var logger: ILogger
|
var logger: ILogger?
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,11 +24,11 @@ interface IApplication {
|
|||||||
val msg = HttpMessage(Status.Success)
|
val msg = HttpMessage(Status.Success)
|
||||||
try {
|
try {
|
||||||
process(msg)
|
process(msg)
|
||||||
logger.debug(this, "$name business execute success")
|
logger?.debug(this, "$name business execute success")
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
msg.status = Status.Error
|
msg.status = Status.Error
|
||||||
msg.message = if (error.isEmpty()) ex.message ?: "" else error
|
msg.message = if (error.isEmpty()) ex.message ?: "" else error
|
||||||
logger.error(this, ex, "$error: ${ex.message}")
|
logger?.error(this, ex, "$error: ${ex.message}")
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
@@ -40,9 +40,9 @@ interface IApplication {
|
|||||||
val msg = HttpMessage(Status.Success)
|
val msg = HttpMessage(Status.Success)
|
||||||
try {
|
try {
|
||||||
process(msg)
|
process(msg)
|
||||||
logger.debug(this, "$name business execute success")
|
logger?.debug(this, "$name business execute success")
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
logger.error(this, ex, "$error。异常消息将抛出!: ${ex.message}")
|
logger?.error(this, ex, "$error。异常消息将抛出!: ${ex.message}")
|
||||||
throw RuntimeException(error, ex)
|
throw RuntimeException(error, ex)
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package com.synebula.gaea.app
|
|
||||||
|
|
||||||
import com.synebula.gaea.app.component.HttpMessage
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户登入登出接口定义
|
|
||||||
*/
|
|
||||||
interface ISignInOut {
|
|
||||||
/**
|
|
||||||
* 定义登录方法。
|
|
||||||
*
|
|
||||||
* @param name 登录名
|
|
||||||
* @param password 登录密码
|
|
||||||
* @return StatusMessage, data 内容为 map 其中 key account中存储用户账户名称
|
|
||||||
*/
|
|
||||||
fun signIn(name: String, password: String): HttpMessage
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登出
|
|
||||||
*
|
|
||||||
* @param user 登出的用户
|
|
||||||
*/
|
|
||||||
fun signOut(user: String): HttpMessage
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.synebula.gaea.app
|
|
||||||
|
|
||||||
import com.synebula.gaea.app.cmd.ICommandApp
|
|
||||||
import com.synebula.gaea.app.query.IQueryGenericApp
|
|
||||||
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.IGenericQuery
|
|
||||||
import javax.annotation.Resource
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
|
||||||
*
|
|
||||||
* @param name 业务名称
|
|
||||||
* @param service 业务domain服务
|
|
||||||
* @param query 业务查询服务
|
|
||||||
* @param logger 日志组件
|
|
||||||
*/
|
|
||||||
open class UnionGenericApp<TCommand : ICommand, TView, TKey>(
|
|
||||||
override var name: String,
|
|
||||||
override var service: IService<TKey>?,
|
|
||||||
override var query: IGenericQuery<TView, TKey>?,
|
|
||||||
override var logger: ILogger
|
|
||||||
) : ICommandApp<TCommand, TKey>, IQueryGenericApp<TView, TKey> {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@ import javax.annotation.Resource
|
|||||||
open class CommandApp<TCommand : ICommand, TKey>(
|
open class CommandApp<TCommand : ICommand, TKey>(
|
||||||
override var name: String,
|
override var name: String,
|
||||||
override var service: IService<TKey>?,
|
override var service: IService<TKey>?,
|
||||||
override var logger: ILogger) : ICommandApp<TCommand, TKey> {
|
override var logger: ILogger?) : ICommandApp<TCommand, TKey> {
|
||||||
@Resource
|
@Resource
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
override var jsonSerializer: IJsonSerializer? = null
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.synebula.gaea.app.component
|
package com.synebula.gaea.app.component
|
||||||
|
|
||||||
import com.synebula.gaea.data.message.Status
|
|
||||||
import com.synebula.gaea.data.message.Message
|
import com.synebula.gaea.data.message.Message
|
||||||
|
|
||||||
class HttpMessage() : Message<Any>() {
|
class HttpMessage() : Message<Any>() {
|
||||||
|
|||||||
@@ -2,50 +2,66 @@ package com.synebula.gaea.app.query
|
|||||||
|
|
||||||
import com.synebula.gaea.app.IApplication
|
import com.synebula.gaea.app.IApplication
|
||||||
import com.synebula.gaea.app.component.HttpMessage
|
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.Params
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
|
||||||
interface IQueryApp<TView, TKey> : IApplication {
|
interface IQueryApp<TView, TKey> : IApplication {
|
||||||
|
/**
|
||||||
|
* 查询服务
|
||||||
|
*/
|
||||||
|
var query: IQuery?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询的View类型
|
||||||
|
*/
|
||||||
|
var clazz: Class<TView>
|
||||||
|
|
||||||
@GetMapping("/{key:.+}")
|
@GetMapping("/{key:.+}")
|
||||||
fun get(@PathVariable key: TKey): HttpMessage {
|
fun get(@PathVariable key: TKey): HttpMessage {
|
||||||
return this.doGet(key)
|
return this.doQuery("获取${this.name}数据失败") {
|
||||||
|
this.query!!.get(key, clazz)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
fun list(@RequestParam params: MutableMap<String, Any>): HttpMessage {
|
fun list(@RequestParam params: MutableMap<String, Any>): HttpMessage {
|
||||||
return this.doList(params)
|
return this.doQuery("获取${this.name}列表数据失败") {
|
||||||
|
this.query!!.list(params, clazz)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/segments/{size}/pages/{page}")
|
@GetMapping("/segments/{size}/pages/{page}")
|
||||||
fun paging(@PathVariable size: Int, @PathVariable page: Int, @RequestParam parameters: MutableMap<String, Any>): HttpMessage {
|
fun paging(
|
||||||
return this.doPaging(size, page, parameters)
|
@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, clazz)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实际查询单条数据逻辑
|
* 抽取查询业务判断功能
|
||||||
*
|
*
|
||||||
* @param key 数据的主键
|
* @param error 错误消息
|
||||||
|
* @param biz 业务执行逻辑
|
||||||
*/
|
*/
|
||||||
fun doGet(key: TKey): HttpMessage
|
fun doQuery(error: String, biz: (() -> Any?)): HttpMessage {
|
||||||
|
return this.safeExecute(error) {
|
||||||
/**
|
if (this.query != null) {
|
||||||
* 实际查询列表逻辑
|
it.data = biz()
|
||||||
*
|
} else {
|
||||||
* @param params 查询参数
|
it.status = Status.Error
|
||||||
*/
|
it.message = "没有对应服务,无法执行该操作"
|
||||||
fun doList(params: Map<String, Any>): HttpMessage
|
}
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* 实际分页逻辑
|
|
||||||
*
|
|
||||||
* @param size 单页数量
|
|
||||||
* @param page 分页页码
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
fun doPaging(size: Int, page: Int, params: MutableMap<String, Any>): HttpMessage
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package com.synebula.gaea.app.query
|
|
||||||
|
|
||||||
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.Params
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用类接口,提供实现Query服务的接口.
|
|
||||||
* 依赖查询接口 @see IQueryTyped
|
|
||||||
*
|
|
||||||
* @author alex
|
|
||||||
* @version 0.1
|
|
||||||
* @since 2020-05-15
|
|
||||||
*/
|
|
||||||
interface IQueryTypedApp<TView, TKey> : IQueryApp<TView, TKey> {
|
|
||||||
/**
|
|
||||||
* 查询服务
|
|
||||||
*/
|
|
||||||
var query: IQuery?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询的View类型
|
|
||||||
*/
|
|
||||||
var clazz: Class<TView>
|
|
||||||
|
|
||||||
override fun doGet(key: TKey): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}数据失败") {
|
|
||||||
this.query!!.get(key, clazz)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doList(params: Map<String, Any>): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}列表数据失败") {
|
|
||||||
this.query!!.list(params, clazz)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doPaging(size: Int, page: Int, params: MutableMap<String, Any>): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}分页数据[条数:$size,页码:$page]失败") {
|
|
||||||
val data = Params(page, size)
|
|
||||||
data.parameters = params
|
|
||||||
this.query!!.paging(data, clazz)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 抽取查询业务判断功能
|
|
||||||
*
|
|
||||||
* @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,9 +1,13 @@
|
|||||||
package com.synebula.gaea.app.query
|
package com.synebula.gaea.app.query
|
||||||
|
|
||||||
|
import com.synebula.gaea.app.IApplication
|
||||||
import com.synebula.gaea.app.component.HttpMessage
|
import com.synebula.gaea.app.component.HttpMessage
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import com.synebula.gaea.query.IGenericQuery
|
import com.synebula.gaea.query.ISpecificQuery
|
||||||
import com.synebula.gaea.query.Params
|
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服务的接口
|
* 应用类接口,提供实现Query服务的接口
|
||||||
@@ -13,50 +17,40 @@ import com.synebula.gaea.query.Params
|
|||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 2020-05-15
|
* @since 2020-05-15
|
||||||
*/
|
*/
|
||||||
interface IQueryGenericApp<TView, TKey> : IQueryApp<TView, TKey> {
|
interface ISpecificQueryApp<TView, TKey> : IApplication {
|
||||||
/**
|
/**
|
||||||
* 查询服务
|
* 查询服务
|
||||||
*/
|
*/
|
||||||
var query: IGenericQuery<TView, TKey>?
|
var query: ISpecificQuery<TView, TKey>?
|
||||||
|
|
||||||
|
@GetMapping("/{key:.+}")
|
||||||
/**
|
fun get(@PathVariable key: TKey): HttpMessage {
|
||||||
* 实际查询单条数据逻辑
|
|
||||||
*
|
|
||||||
* @param key 数据的主键
|
|
||||||
*/
|
|
||||||
override fun doGet(key: TKey): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}数据失败") {
|
return this.doQuery("获取${this.name}数据失败") {
|
||||||
this.query!!.get(key)
|
this.query!!.get(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@GetMapping
|
||||||
* 实际查询列表逻辑
|
fun list(@RequestParam params: MutableMap<String, Any>): HttpMessage {
|
||||||
*
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
override fun doList(params: Map<String, Any>): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}列表数据失败") {
|
return this.doQuery("获取${this.name}列表数据失败") {
|
||||||
this.query!!.list(params)
|
this.query!!.list(params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@GetMapping("/segments/{size}/pages/{page}")
|
||||||
* 实际分页逻辑
|
fun paging(
|
||||||
*
|
@PathVariable size: Int,
|
||||||
* @param size 单页数量
|
@PathVariable page: Int,
|
||||||
* @param page 分页页码
|
@RequestParam parameters: MutableMap<String, Any>
|
||||||
* @param params 查询参数
|
): HttpMessage {
|
||||||
*/
|
|
||||||
override fun doPaging(size: Int, page: Int, params: MutableMap<String, Any>): HttpMessage {
|
|
||||||
return this.doQuery("获取${this.name}分页数据[条数:$size,页码:$page]失败") {
|
return this.doQuery("获取${this.name}分页数据[条数:$size,页码:$page]失败") {
|
||||||
val data = Params(page, size)
|
val data = Params(page, size)
|
||||||
data.parameters = params
|
data.parameters = parameters
|
||||||
this.query!!.paging(data)
|
this.query!!.paging(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽取查询业务判断功能
|
* 抽取查询业务判断功能
|
||||||
*
|
*
|
||||||
@@ -73,5 +67,4 @@ interface IQueryGenericApp<TView, TKey> : IQueryApp<TView, TKey> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,9 +10,9 @@ import com.synebula.gaea.query.IQuery
|
|||||||
* @param query 业务查询服务
|
* @param query 业务查询服务
|
||||||
* @param logger 日志组件
|
* @param logger 日志组件
|
||||||
*/
|
*/
|
||||||
open class QueryTypedApp<TView, TKey>(
|
open class QueryApp<TView, TKey>(
|
||||||
override var name: String,
|
override var name: String,
|
||||||
override var clazz: Class<TView>,
|
override var clazz: Class<TView>,
|
||||||
override var query: IQuery?,
|
override var query: IQuery?,
|
||||||
override var logger: ILogger) : IQueryTypedApp<TView, TKey> {
|
override var logger: ILogger?
|
||||||
}
|
) : IQueryApp<TView, TKey>
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.synebula.gaea.app.query
|
|
||||||
|
|
||||||
import com.synebula.gaea.log.ILogger
|
|
||||||
import com.synebula.gaea.query.IGenericQuery
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
|
||||||
*
|
|
||||||
* @param name 业务名称
|
|
||||||
* @param genericQuery 业务查询服务
|
|
||||||
* @param logger 日志组件
|
|
||||||
*/
|
|
||||||
open class QueryGenericApp<TView, TKey>(
|
|
||||||
override var name: String,
|
|
||||||
override var query: IGenericQuery<TView, TKey>?,
|
|
||||||
override var logger: ILogger
|
|
||||||
) : IQueryGenericApp<TView, TKey> {
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
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>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.synebula.gaea.mongo
|
package com.synebula.gaea.mongo
|
||||||
|
|
||||||
import com.synebula.gaea.data.date.DateTime
|
import com.synebula.gaea.data.date.DateTime
|
||||||
import com.synebula.gaea.query.Operator
|
import com.synebula.gaea.query.annotation.Where
|
||||||
import com.synebula.gaea.query.OrderType
|
import com.synebula.gaea.query.type.Operator
|
||||||
import com.synebula.gaea.query.Where
|
import com.synebula.gaea.query.type.Order
|
||||||
import org.springframework.data.domain.Sort
|
import org.springframework.data.domain.Sort
|
||||||
import org.springframework.data.mongodb.core.query.Criteria
|
import org.springframework.data.mongodb.core.query.Criteria
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
import org.springframework.data.mongodb.core.query.Query
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package com.synebula.gaea.mongo.query
|
|||||||
import com.synebula.gaea.extension.fieldNames
|
import com.synebula.gaea.extension.fieldNames
|
||||||
import com.synebula.gaea.extension.firstCharLowerCase
|
import com.synebula.gaea.extension.firstCharLowerCase
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.mongo.*
|
import com.synebula.gaea.mongo.order
|
||||||
import com.synebula.gaea.mongo.Collection
|
import com.synebula.gaea.mongo.select
|
||||||
|
import com.synebula.gaea.mongo.where
|
||||||
|
import com.synebula.gaea.mongo.whereId
|
||||||
import com.synebula.gaea.query.IQuery
|
import com.synebula.gaea.query.IQuery
|
||||||
import com.synebula.gaea.query.Page
|
import com.synebula.gaea.query.Page
|
||||||
import com.synebula.gaea.query.Params
|
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.MongoTemplate
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
import org.springframework.data.mongodb.core.query.Query
|
||||||
|
|
||||||
@@ -36,20 +39,20 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
|
|||||||
return this.template.count(query.where(params, clazz), this.collection(clazz)).toInt()
|
return this.template.count(query.where(params, clazz), this.collection(clazz)).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <TView> paging(param: Params, clazz: Class<TView>): Page<TView> {
|
override fun <TView> paging(params: Params, clazz: Class<TView>): Page<TView> {
|
||||||
val query = Query()
|
val query = Query()
|
||||||
val fields = clazz.fieldNames()
|
val fields = clazz.fieldNames()
|
||||||
val result = Page<TView>(param.page, param.size)
|
val result = Page<TView>(params.page, params.size)
|
||||||
result.total = this.count(param.parameters, clazz)
|
result.total = this.count(params.parameters, clazz)
|
||||||
//如果总数和索引相同,说明该页没有数据,直接跳到上一页
|
//如果总数和索引相同,说明该页没有数据,直接跳到上一页
|
||||||
if (result.total == result.index) {
|
if (result.total == result.index) {
|
||||||
param.page -= 1
|
params.page -= 1
|
||||||
result.page -= 1
|
result.page -= 1
|
||||||
}
|
}
|
||||||
query.select(fields.toTypedArray())
|
query.select(fields.toTypedArray())
|
||||||
query.where(param.parameters, clazz)
|
query.where(params.parameters, clazz)
|
||||||
query.with(order(param.orders))
|
query.with(order(params.orders))
|
||||||
query.skip(param.index).limit(param.size)
|
query.skip(params.index).limit(params.size)
|
||||||
result.data = this.template.find(query, clazz, this.collection(clazz))
|
result.data = this.template.find(query, clazz, this.collection(clazz))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -61,17 +64,19 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
|
|||||||
/**
|
/**
|
||||||
* 获取collection
|
* 获取collection
|
||||||
*/
|
*/
|
||||||
protected fun <TView> collection(clazz: Class<TView>): String {
|
fun <TView> collection(clazz: Class<TView>): String {
|
||||||
val collection: Collection? = clazz.getDeclaredAnnotation(Collection::class.java)
|
val table: Table? = clazz.getDeclaredAnnotation(
|
||||||
return if (collection != null)
|
Table::class.java
|
||||||
return collection.name
|
)
|
||||||
|
return if (table != null)
|
||||||
|
return table.name
|
||||||
else {
|
else {
|
||||||
this.logger?.info(this, "视图类没有标记[Collection]注解,无法获取Collection名称。尝试使用View<${clazz.name}>名称解析集合")
|
this.logger?.info(this, "视图类没有标记[Collection]注解,无法获取Collection名称。尝试使用View<${clazz.name}>名称解析集合")
|
||||||
val name = clazz.simpleName.removeSuffix("View").firstCharLowerCase()
|
val name = clazz.simpleName.removeSuffix("View").firstCharLowerCase()
|
||||||
if (!validViewCollection || this.template.collectionExists(name))
|
if (!validViewCollection || this.template.collectionExists(name))
|
||||||
name
|
name
|
||||||
else {
|
else {
|
||||||
throw RuntimeException("找不到名为[$collection]的集合")
|
throw RuntimeException("找不到名为[$table]的集合")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ package com.synebula.gaea.mongo.query
|
|||||||
import com.synebula.gaea.extension.fieldNames
|
import com.synebula.gaea.extension.fieldNames
|
||||||
import com.synebula.gaea.extension.firstCharLowerCase
|
import com.synebula.gaea.extension.firstCharLowerCase
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.mongo.Collection
|
|
||||||
import com.synebula.gaea.mongo.order
|
import com.synebula.gaea.mongo.order
|
||||||
import com.synebula.gaea.mongo.select
|
import com.synebula.gaea.mongo.select
|
||||||
import com.synebula.gaea.mongo.where
|
import com.synebula.gaea.mongo.where
|
||||||
import com.synebula.gaea.mongo.whereId
|
import com.synebula.gaea.mongo.whereId
|
||||||
import com.synebula.gaea.query.IGenericQuery
|
import com.synebula.gaea.query.ISpecificQuery
|
||||||
import com.synebula.gaea.query.Page
|
import com.synebula.gaea.query.Page
|
||||||
import com.synebula.gaea.query.Params
|
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.MongoTemplate
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
import org.springframework.data.mongodb.core.query.Query
|
||||||
|
|
||||||
@@ -20,10 +20,11 @@ import org.springframework.data.mongodb.core.query.Query
|
|||||||
* @param template MongoRepo对象
|
* @param template MongoRepo对象
|
||||||
* @param logger 日志组件
|
* @param logger 日志组件
|
||||||
*/
|
*/
|
||||||
open class MongoGenericQuery<TView>(
|
open class MongoSpecificQuery<TView>(
|
||||||
var template: MongoTemplate,
|
var template: MongoTemplate,
|
||||||
var clazz: Class<TView>? = null,
|
var clazz: Class<TView>? = null,
|
||||||
var logger: ILogger? = null) : IGenericQuery<TView, String> {
|
var logger: ILogger? = null
|
||||||
|
) : ISpecificQuery<TView, String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用View解析是collection时是否校验存在,默认不校验
|
* 使用View解析是collection时是否校验存在,默认不校验
|
||||||
@@ -129,7 +130,7 @@ open class MongoGenericQuery<TView>(
|
|||||||
*/
|
*/
|
||||||
protected fun <TView> collection(clazz: Class<TView>?): String {
|
protected fun <TView> collection(clazz: Class<TView>?): String {
|
||||||
if (clazz == null) throw java.lang.RuntimeException("[${this.javaClass}]没有指定查询实体类型[clazz]")
|
if (clazz == null) throw java.lang.RuntimeException("[${this.javaClass}]没有指定查询实体类型[clazz]")
|
||||||
val collection: Collection? = clazz.getDeclaredAnnotation(Collection::class.java)
|
val collection = clazz.getDeclaredAnnotation(Table::class.java)
|
||||||
return if (collection != null)
|
return if (collection != null)
|
||||||
return collection.name
|
return collection.name
|
||||||
else {
|
else {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.synebula.gaea.mongo.repository
|
package com.synebula.gaea.mongo.repository
|
||||||
|
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||||
import com.synebula.gaea.domain.repository.IGenericRepository
|
import com.synebula.gaea.domain.repository.ISpecificRepository
|
||||||
import com.synebula.gaea.mongo.whereId
|
import com.synebula.gaea.mongo.whereId
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate
|
import org.springframework.data.mongodb.core.MongoTemplate
|
||||||
|
|
||||||
@@ -9,8 +9,8 @@ import org.springframework.data.mongodb.core.MongoTemplate
|
|||||||
* 实现IAggregateRoot的mongo仓储类
|
* 实现IAggregateRoot的mongo仓储类
|
||||||
* @param repo MongoRepo对象
|
* @param repo MongoRepo对象
|
||||||
*/
|
*/
|
||||||
class MongoGenericRepository<TAggregateRoot : IAggregateRoot<String>>(private var repo: MongoTemplate) :
|
class MongoSpecificRepository<TAggregateRoot : IAggregateRoot<String>>(private var repo: MongoTemplate) :
|
||||||
IGenericRepository<TAggregateRoot, String> {
|
ISpecificRepository<TAggregateRoot, String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 仓储的对象类
|
* 仓储的对象类
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package com.synebula.gaea.domain.repository
|
|
||||||
|
|
||||||
import com.synebula.gaea.domain.model.complex.IComplexAggregateRoot
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 继承本接口表示对象为仓储类。
|
|
||||||
*
|
|
||||||
* @param <TAggregateRoot> this T is the parameter
|
|
||||||
* @author alex
|
|
||||||
*/
|
|
||||||
interface IComplexRepository<TAggregateRoot : IComplexAggregateRoot<TKey, TSecond>, TKey, TSecond> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插入单个对象。
|
|
||||||
*
|
|
||||||
* @param obj 需要插入的对象。
|
|
||||||
* @return 返回原对象,如果对象ID为自增,则补充自增ID。
|
|
||||||
*/
|
|
||||||
fun add(obj: TAggregateRoot)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新对象。
|
|
||||||
*
|
|
||||||
* @param obj 需要更新的对象。
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
fun update(obj: TAggregateRoot)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过id删除该条数据
|
|
||||||
*
|
|
||||||
* @param key 对象ID。
|
|
||||||
* @param secondary 对象副主键。
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
fun remove(key: TKey, secondary: TSecond)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据ID获取对象。
|
|
||||||
*
|
|
||||||
* @param key 对象ID。
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
operator fun get(key: TKey, secondary: TSecond): TAggregateRoot
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ import com.synebula.gaea.domain.model.IAggregateRoot
|
|||||||
* @param <TAggregateRoot> this T is the parameter
|
* @param <TAggregateRoot> this T is the parameter
|
||||||
* @author alex
|
* @author alex
|
||||||
*/
|
*/
|
||||||
interface IGenericRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
interface ISpecificRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 仓储的对象类
|
* 仓储的对象类
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
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.IComplexRepository
|
|
||||||
import com.synebula.gaea.log.ILogger
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 复合主键的服务基类
|
|
||||||
*
|
|
||||||
* @author alex
|
|
||||||
* @version 0.1
|
|
||||||
* @since 2020-05-15
|
|
||||||
*/
|
|
||||||
open class ComplexService<TAggregateRoot : IComplexAggregateRoot<TKey, TSecond>, TKey, TSecond>(
|
|
||||||
protected var clazz: Class<TAggregateRoot>,
|
|
||||||
protected var repository: IComplexRepository<TAggregateRoot, TKey, TSecond>,
|
|
||||||
protected var converter: IObjectConverter,
|
|
||||||
override var logger: ILogger
|
|
||||||
) : IComplexService<TKey, TSecond> {
|
|
||||||
|
|
||||||
override fun add(command: ICommand): Message<Pair<TKey, TSecond>> {
|
|
||||||
val msg = Message<Pair<TKey, TSecond>>()
|
|
||||||
val root = this.convert(command)
|
|
||||||
repository.add(root)
|
|
||||||
msg.data = Pair<TKey, TSecond>(root.id!!, root.secondary!!)
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun update(key: TKey, secondary: TSecond, command: ICommand) {
|
|
||||||
val root = this.convert(command)
|
|
||||||
root.id = key
|
|
||||||
root.secondary = secondary
|
|
||||||
repository.update(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun remove(key: TKey, secondary: TSecond) {
|
|
||||||
repository.remove(key, secondary)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换ICommand类型到聚合根类型,默认实现,根据需要进行覆写。
|
|
||||||
*
|
|
||||||
* @param command
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected fun convert(command: ICommand): TAggregateRoot {
|
|
||||||
try {
|
|
||||||
return converter.convert(command, clazz)
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
throw RuntimeException("command not match aggregate root", ex)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.synebula.gaea.domain.service
|
|
||||||
|
|
||||||
import com.synebula.gaea.data.message.Message
|
|
||||||
import com.synebula.gaea.log.ILogger
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class IFlatService
|
|
||||||
*
|
|
||||||
* @author alex
|
|
||||||
* @version 0.1
|
|
||||||
* @since 2020-05-15
|
|
||||||
*/
|
|
||||||
interface IComplexService<TKey, TSecond> {
|
|
||||||
/**
|
|
||||||
* 日志组件。
|
|
||||||
*/
|
|
||||||
var logger: ILogger
|
|
||||||
|
|
||||||
fun add(command: ICommand): Message<Pair<TKey, TSecond>>
|
|
||||||
|
|
||||||
fun update(key: TKey, secondary: TSecond, command: ICommand)
|
|
||||||
|
|
||||||
fun remove(key: TKey, secondary: TSecond)
|
|
||||||
}
|
|
||||||
@@ -8,8 +8,8 @@ import com.synebula.gaea.log.ILogger
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 依赖了IRepositoryTyped仓储借口的服务实现类 ServiceTyped
|
* 依赖了IRepository仓储借口的服务实现类 Service
|
||||||
* 该类依赖仓储接口 @see IRepositoryTyped ,需要显式提供聚合根的class对象
|
* 该类依赖仓储接口 @see IRepository, 需要显式提供聚合根的class对象
|
||||||
*
|
*
|
||||||
* @param repository 仓储对象
|
* @param repository 仓储对象
|
||||||
* @param clazz 聚合根类对象
|
* @param clazz 聚合根类对象
|
||||||
@@ -20,10 +20,10 @@ import com.synebula.gaea.log.ILogger
|
|||||||
* @since 2020-05-17
|
* @since 2020-05-17
|
||||||
*/
|
*/
|
||||||
open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
||||||
protected open var clazz: Class<TAggregateRoot>,
|
protected open var clazz: Class<TAggregateRoot>,
|
||||||
protected open var repository: IRepository,
|
protected open var repository: IRepository,
|
||||||
protected open var converter: IObjectConverter,
|
protected open var converter: IObjectConverter,
|
||||||
override var logger: ILogger
|
override var logger: ILogger
|
||||||
) : IService<TKey> {
|
) : IService<TKey> {
|
||||||
|
|
||||||
override fun add(command: ICommand): Message<TKey> {
|
override fun add(command: ICommand): Message<TKey> {
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package com.synebula.gaea.domain.service
|
|||||||
import com.synebula.gaea.data.IObjectConverter
|
import com.synebula.gaea.data.IObjectConverter
|
||||||
import com.synebula.gaea.data.message.Message
|
import com.synebula.gaea.data.message.Message
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||||
import com.synebula.gaea.domain.repository.IGenericRepository
|
import com.synebula.gaea.domain.repository.ISpecificRepository
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class FlatService
|
* 依赖了ISpecificRepository仓储借口的服务实现类 Service
|
||||||
|
* 该类依赖仓储接口 @see ISpecificRepository, 泛型类上指定了仓储实例的类型
|
||||||
*
|
*
|
||||||
* @param repository 仓储对象
|
* @param repository 仓储对象
|
||||||
* @param clazz 聚合根类对象
|
* @param clazz 聚合根类对象
|
||||||
@@ -18,9 +19,9 @@ import com.synebula.gaea.log.ILogger
|
|||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 2020-05-15
|
* @since 2020-05-15
|
||||||
*/
|
*/
|
||||||
open class GenericService<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
open class SpecificService<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
||||||
protected var clazz: Class<TAggregateRoot>,
|
protected var clazz: Class<TAggregateRoot>,
|
||||||
protected var repository: IGenericRepository<TAggregateRoot, TKey>,
|
protected var repository: ISpecificRepository<TAggregateRoot, TKey>,
|
||||||
protected var converter: IObjectConverter,
|
protected var converter: IObjectConverter,
|
||||||
override var logger: ILogger
|
override var logger: ILogger
|
||||||
) : IService<TKey> {
|
) : IService<TKey> {
|
||||||
@@ -33,8 +33,8 @@ interface IQuery {
|
|||||||
/**
|
/**
|
||||||
* 根据实体类条件查询所有符合条件记录(分页查询)
|
* 根据实体类条件查询所有符合条件记录(分页查询)
|
||||||
*
|
*
|
||||||
* @param param 分页条件
|
* @param params 分页条件
|
||||||
* @return 分页数据
|
* @return 分页数据
|
||||||
*/
|
*/
|
||||||
fun <TView> paging(param: Params, clazz: Class<TView>): Page<TView>
|
fun <TView> paging(params: Params, clazz: Class<TView>): Page<TView>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.synebula.gaea.query
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询基接口。
|
|
||||||
*
|
|
||||||
* @author wxf
|
|
||||||
*/
|
|
||||||
interface IQueryComplex<TView, TKey, TSecond> {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据Key获取对象。
|
|
||||||
*
|
|
||||||
* @param key 对象Key。
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
fun get(key: TKey, secondary: TSecond): TView
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据实体类条件查询所有符合条件记录
|
|
||||||
*
|
|
||||||
* @param parameters 查询条件。
|
|
||||||
* @return list
|
|
||||||
*/
|
|
||||||
fun list(parameters: Map<String, Any>): List<TView>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件查询符合条件记录的数量
|
|
||||||
*
|
|
||||||
* @param parameters 查询条件。
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
fun count(parameters: Map<String, Any>): Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据实体类条件查询所有符合条件记录(分页查询)
|
|
||||||
*
|
|
||||||
* @param param 分页条件
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
fun paging(param: Params): Page<TView>
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ package com.synebula.gaea.query
|
|||||||
*
|
*
|
||||||
* @author alex
|
* @author alex
|
||||||
*/
|
*/
|
||||||
interface IGenericQuery<TView, TKey> {
|
interface ISpecificQuery<TView, TKey> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reference in New Issue
Block a user