重构Gaea服务, 升级版本

This commit is contained in:
2020-07-07 15:07:27 +08:00
parent 0d747f92b2
commit 66869fd34e
26 changed files with 139 additions and 409 deletions

View File

@@ -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"
} }

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
} }

View File

@@ -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>() {

View File

@@ -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
} }

View File

@@ -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 = "没有对应服务,无法执行该操作"
}
}
}
}

View File

@@ -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> {
} }
} }
} }
} }

View File

@@ -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>

View File

@@ -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> {
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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]的集合")
} }
} }
} }

View File

@@ -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 {

View File

@@ -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> {
/** /**
* 仓储的对象类 * 仓储的对象类

View File

@@ -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
}

View File

@@ -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> {
/** /**
* 仓储的对象类 * 仓储的对象类

View File

@@ -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)
}
}
}

View File

@@ -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)
}

View File

@@ -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> {

View File

@@ -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> {

View File

@@ -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>
} }

View File

@@ -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>
}

View File

@@ -5,7 +5,7 @@ package com.synebula.gaea.query
* *
* @author alex * @author alex
*/ */
interface IGenericQuery<TView, TKey> { interface ISpecificQuery<TView, TKey> {
/** /**