重构query,拆分功能
This commit is contained in:
@@ -6,7 +6,7 @@ dependencies {
|
|||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
mavenJava(MavenPublication) {
|
publish(MavenPublication) {
|
||||||
group 'com.synebula'
|
group 'com.synebula'
|
||||||
artifactId 'gaea.app'
|
artifactId 'gaea.app'
|
||||||
version "$version"
|
version "$version"
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app
|
||||||
|
|
||||||
|
import com.synebula.gaea.app.cmd.ICommandApp
|
||||||
|
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
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app
|
||||||
|
|
||||||
|
import com.synebula.gaea.app.cmd.ICommandApp
|
||||||
|
import com.synebula.gaea.app.query.IQueryTypedApp
|
||||||
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
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.query.IQuery
|
|
||||||
import com.synebula.gaea.query.IQueryTyped
|
import com.synebula.gaea.query.IQueryTyped
|
||||||
import javax.annotation.Resource
|
import javax.annotation.Resource
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app.cmd
|
||||||
|
|
||||||
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
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app.cmd
|
||||||
|
|
||||||
|
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.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
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import javax.annotation.Resource
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用类接口,提供向Command服务的接口
|
* 应用类接口,提供向Command服务的接口
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.synebula.gaea.app
|
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.IQuery
|
import com.synebula.gaea.query.IQuery
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.synebula.gaea.app
|
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.IQuery
|
|
||||||
import com.synebula.gaea.query.IQueryTyped
|
import com.synebula.gaea.query.IQueryTyped
|
||||||
import com.synebula.gaea.query.PagingParam
|
import com.synebula.gaea.query.PagingParam
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
@@ -44,7 +44,7 @@ interface IQueryTypedApp<TView, TKey> : IApplication {
|
|||||||
fun list(@RequestParam parameters: MutableMap<String, Any>): HttpMessage {
|
fun list(@RequestParam parameters: MutableMap<String, Any>): HttpMessage {
|
||||||
return this.safeExecute("获取${this.name}列表数据失败") {
|
return this.safeExecute("获取${this.name}列表数据失败") {
|
||||||
if (this.query != null)
|
if (this.query != null)
|
||||||
it.data = this.query!!.list<TView, TKey>(parameters, viewClass)
|
it.data = this.query!!.list(parameters, viewClass)
|
||||||
else {
|
else {
|
||||||
it.status = Status.Error
|
it.status = Status.Error
|
||||||
it.message = "没有对应服务,无法执行该操作"
|
it.message = "没有对应服务,无法执行该操作"
|
||||||
@@ -58,7 +58,7 @@ interface IQueryTypedApp<TView, TKey> : IApplication {
|
|||||||
if (this.query != null) {
|
if (this.query != null) {
|
||||||
val params = PagingParam(page, size)
|
val params = PagingParam(page, size)
|
||||||
params.parameters = parameters
|
params.parameters = parameters
|
||||||
it.data = this.query!!.paging<TView, TKey>(params, viewClass)
|
it.data = this.query!!.paging(params, viewClass)
|
||||||
} else {
|
} else {
|
||||||
it.status = Status.Error
|
it.status = Status.Error
|
||||||
it.message = "没有对应服务,无法执行该操作"
|
it.message = "没有对应服务,无法执行该操作"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app.query
|
||||||
|
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.query.IQuery
|
import com.synebula.gaea.query.IQuery
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.synebula.gaea.app
|
package com.synebula.gaea.app.query
|
||||||
|
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.query.IQuery
|
|
||||||
import com.synebula.gaea.query.IQueryTyped
|
import com.synebula.gaea.query.IQueryTyped
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -5,7 +5,7 @@ dependencies {
|
|||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
mavenJava(MavenPublication) {
|
publish(MavenPublication) {
|
||||||
group 'com.synebula'
|
group 'com.synebula'
|
||||||
artifactId 'gaea.mongo'
|
artifactId 'gaea.mongo'
|
||||||
version "$version"
|
version "$version"
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.synebula.gaea.mongo
|
||||||
|
|
||||||
|
import com.synebula.gaea.query.OrderType
|
||||||
|
import org.springframework.data.domain.Sort
|
||||||
|
import org.springframework.data.mongodb.core.query.Criteria
|
||||||
|
import org.springframework.data.mongodb.core.query.Query
|
||||||
|
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取查询条件
|
||||||
|
*
|
||||||
|
* @param fields 字段列表
|
||||||
|
*/
|
||||||
|
fun Query.select(fields: Array<String>): Query {
|
||||||
|
fields.forEach {
|
||||||
|
this.fields().include(it)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据参数获取查询条件
|
||||||
|
*
|
||||||
|
* @param params 参数列表
|
||||||
|
*/
|
||||||
|
fun Query.where(params: Map<String, Any>?): Query {
|
||||||
|
val criteria = Criteria()
|
||||||
|
if (params != null) {
|
||||||
|
for (param in params) {
|
||||||
|
criteria.and(param.key).isEqualTo(param.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.addCriteria(criteria)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取ID查询条件
|
||||||
|
*
|
||||||
|
* @param id 业务ID
|
||||||
|
*/
|
||||||
|
fun <TKey> whereId(id: TKey): Query = Query(Criteria("_id").isEqualTo(id))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取排序对象
|
||||||
|
*
|
||||||
|
* @param orders 排序条件字段
|
||||||
|
*/
|
||||||
|
fun order(orders: Map<String, OrderType>?): Sort {
|
||||||
|
val orderList = mutableListOf<Sort.Order>()
|
||||||
|
orders?.forEach {
|
||||||
|
orderList.add(Sort.Order(Sort.Direction.valueOf(it.value.name), it.key))
|
||||||
|
}
|
||||||
|
return if (orderList.size == 0)
|
||||||
|
Sort.by("_id")
|
||||||
|
else
|
||||||
|
Sort.by(orderList)
|
||||||
|
}
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
package com.synebula.gaea.query.mongo
|
package com.synebula.gaea.mongo.query
|
||||||
|
|
||||||
|
import com.synebula.gaea.extension.fields
|
||||||
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.order
|
||||||
|
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.PagingData
|
import com.synebula.gaea.query.PagingData
|
||||||
import com.synebula.gaea.query.PagingParam
|
import com.synebula.gaea.query.PagingParam
|
||||||
@@ -12,8 +17,7 @@ import org.springframework.data.mongodb.core.query.Query
|
|||||||
* 实现IQuery的Mongo查询类
|
* 实现IQuery的Mongo查询类
|
||||||
* @param repo MongoRepo对象
|
* @param repo MongoRepo对象
|
||||||
*/
|
*/
|
||||||
open class MongoQuery<TView>(var repo: MongoTemplate, override var logger: ILogger? = null) :
|
open class MongoQuery<TView>(var repo: MongoTemplate, var logger: ILogger? = null) : IQuery<TView, String> {
|
||||||
IQuery<TView, String>, IMongoQuery {
|
|
||||||
/**
|
/**
|
||||||
* 查询的对象类
|
* 查询的对象类
|
||||||
*/
|
*/
|
||||||
@@ -74,10 +78,10 @@ open class MongoQuery<TView>(var repo: MongoTemplate, override var logger: ILogg
|
|||||||
override fun list(params: Map<String, Any>?): List<TView> {
|
override fun list(params: Map<String, Any>?): List<TView> {
|
||||||
this.check()
|
this.check()
|
||||||
return if (this.clazz != null) {
|
return if (this.clazz != null) {
|
||||||
val viewFields = this.fields(this.clazz!!)
|
val fields = this.clazz!!.fields()
|
||||||
val query = Query()
|
val query = Query()
|
||||||
this.where(query, params, this.clazz!!)
|
query.select(fields.toTypedArray())
|
||||||
this.select(query, viewFields.toTypedArray())
|
query.where(params)
|
||||||
this.repo.find(query, this.clazz!!, this.collection)
|
this.repo.find(query, this.clazz!!, this.collection)
|
||||||
} else listOf()
|
} else listOf()
|
||||||
}
|
}
|
||||||
@@ -86,21 +90,19 @@ open class MongoQuery<TView>(var repo: MongoTemplate, override var logger: ILogg
|
|||||||
this.check()
|
this.check()
|
||||||
return if (this.clazz != null) {
|
return if (this.clazz != null) {
|
||||||
val query = Query()
|
val query = Query()
|
||||||
this.repo.count(where(query, params, this.clazz!!), this.collection).toInt()
|
this.repo.count(query.where(params), this.collection).toInt()
|
||||||
} else 0
|
} else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun paging(params: PagingParam): PagingData<TView> {
|
override fun paging(params: PagingParam): PagingData<TView> {
|
||||||
this.check()
|
this.check()
|
||||||
return if (this.clazz != null) {
|
return if (this.clazz != null) {
|
||||||
val viewFields = this.fields(this.clazz!!)
|
|
||||||
val result = PagingData<TView>(1, 10)
|
|
||||||
result.size = params.size
|
|
||||||
result.page = params.page
|
|
||||||
val query = Query()
|
val query = Query()
|
||||||
this.where(query, params.parameters, this.clazz!!)
|
val fields = this.clazz!!.fields()
|
||||||
result.total = this.repo.count(query, this.collection).toInt()
|
val result = PagingData<TView>(params.page, params.size)
|
||||||
this.select(query, viewFields.toTypedArray())
|
query.where(params.parameters)
|
||||||
|
result.total = this.count(params.parameters)
|
||||||
|
query.select(fields.toTypedArray())
|
||||||
query.with(order(params.orderBy))
|
query.with(order(params.orderBy))
|
||||||
query.skip(params.index).limit(params.size)
|
query.skip(params.index).limit(params.size)
|
||||||
result.data = this.repo.find(query, this.clazz!!, this.collection)
|
result.data = this.repo.find(query, this.clazz!!, this.collection)
|
||||||
@@ -111,7 +113,7 @@ open class MongoQuery<TView>(var repo: MongoTemplate, override var logger: ILogg
|
|||||||
override fun get(key: String): TView? {
|
override fun get(key: String): TView? {
|
||||||
this.check()
|
this.check()
|
||||||
return if (this.clazz != null) {
|
return if (this.clazz != null) {
|
||||||
val view = this.repo.findOne(idQuery(key), this.clazz!!, this.collection)
|
val view = this.repo.findOne(whereId(key), this.clazz!!, this.collection)
|
||||||
view
|
view
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
package com.synebula.gaea.query.mongo
|
package com.synebula.gaea.mongo.query
|
||||||
|
|
||||||
|
import com.synebula.gaea.extension.fields
|
||||||
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.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.IQueryTyped
|
||||||
import com.synebula.gaea.query.PagingData
|
import com.synebula.gaea.query.PagingData
|
||||||
import com.synebula.gaea.query.PagingParam
|
import com.synebula.gaea.query.PagingParam
|
||||||
@@ -14,7 +19,7 @@ import java.lang.RuntimeException
|
|||||||
* @param repo MongoRepo对象
|
* @param repo MongoRepo对象
|
||||||
*/
|
*/
|
||||||
|
|
||||||
open class MongoQueryTyped(var repo: MongoTemplate, override var logger: ILogger? = null) : IQueryTyped, IMongoQuery {
|
open class MongoQueryTyped(var repo: MongoTemplate, var logger: ILogger? = null) : IQueryTyped {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询的集合名称
|
* 查询的集合名称
|
||||||
@@ -29,28 +34,28 @@ open class MongoQueryTyped(var repo: MongoTemplate, override var logger: ILogger
|
|||||||
*/
|
*/
|
||||||
var validViewCollection = false
|
var validViewCollection = false
|
||||||
|
|
||||||
override fun <TView, TKey> list(params: Map<String, Any>?, clazz: Class<TView>): List<TView> {
|
override fun <TView> list(params: Map<String, Any>?, clazz: Class<TView>): List<TView> {
|
||||||
val viewFields = this.fields(clazz)
|
val fields = clazz.fields()
|
||||||
val query = Query()
|
val query = Query()
|
||||||
this.where(query, params, clazz)
|
query.where(params)
|
||||||
this.select(query, viewFields.toTypedArray())
|
query.select(fields.toTypedArray())
|
||||||
return this.repo.find(query, clazz, this.collection(clazz))
|
return this.repo.find(query, clazz, this.collection(clazz))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <TView, TKey> count(params: Map<String, Any>?, clazz: Class<TView>): Int {
|
override fun <TView> count(params: Map<String, Any>?, clazz: Class<TView>): Int {
|
||||||
val query = Query()
|
val query = Query()
|
||||||
return this.repo.count(this.where(query, params, clazz), this.collection(clazz)).toInt()
|
return this.repo.count(query.where(params), this.collection(clazz)).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <TView, TKey> paging(params: PagingParam, clazz: Class<TView>): PagingData<TView> {
|
override fun <TView> paging(params: PagingParam, clazz: Class<TView>): PagingData<TView> {
|
||||||
val viewFields = this.fields(clazz)
|
val fields = clazz.fields()
|
||||||
val result = PagingData<TView>(1, 10)
|
val result = PagingData<TView>(1, 10)
|
||||||
result.size = params.size
|
result.size = params.size
|
||||||
result.page = params.page
|
result.page = params.page
|
||||||
val query = Query()
|
val query = Query()
|
||||||
this.where(query, params.parameters, clazz)
|
query.where(params.parameters)
|
||||||
result.total = this.count<TView, TKey>(params.parameters, clazz)
|
result.total = this.count(params.parameters, clazz)
|
||||||
this.select(query, viewFields.toTypedArray())
|
query.select(fields.toTypedArray())
|
||||||
query.with(order(params.orderBy))
|
query.with(order(params.orderBy))
|
||||||
query.skip(params.index).limit(params.size)
|
query.skip(params.index).limit(params.size)
|
||||||
result.data = this.repo.find(query, clazz, this.collection(clazz))
|
result.data = this.repo.find(query, clazz, this.collection(clazz))
|
||||||
@@ -58,7 +63,7 @@ open class MongoQueryTyped(var repo: MongoTemplate, override var logger: ILogger
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <TView, TKey> get(key: TKey, clazz: Class<TView>): TView? {
|
override fun <TView, TKey> get(key: TKey, clazz: Class<TView>): TView? {
|
||||||
return this.repo.findOne(idQuery(key), clazz, this.collection(clazz))
|
return this.repo.findOne(whereId(key), clazz, this.collection(clazz))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +71,7 @@ open class MongoQueryTyped(var repo: MongoTemplate, override var logger: ILogger
|
|||||||
*/
|
*/
|
||||||
protected fun <TView> collection(clazz: Class<TView>): String {
|
protected fun <TView> collection(clazz: Class<TView>): String {
|
||||||
return if (this.collection.isEmpty()) {
|
return if (this.collection.isEmpty()) {
|
||||||
this.logger?.warn(this, "查询集合参数[collection]值为空, 尝试使用View<${clazz.name}>名称解析集合")
|
this.logger?.info(this, "查询集合参数[collection]值为空, 尝试使用View<${clazz.name}>名称解析集合")
|
||||||
val collection = clazz.simpleName.removeSuffix("View").firstCharLowerCase()
|
val collection = clazz.simpleName.removeSuffix("View").firstCharLowerCase()
|
||||||
if (!validViewCollection || this.repo.collectionExists(collection))
|
if (!validViewCollection || this.repo.collectionExists(collection))
|
||||||
collection
|
collection
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.synebula.gaea.mongo.repository
|
||||||
|
|
||||||
|
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||||
|
import com.synebula.gaea.domain.repository.IRepository
|
||||||
|
import com.synebula.gaea.mongo.whereId
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现IAggregateRoot的mongo仓储类
|
||||||
|
* @param repo MongoRepo对象
|
||||||
|
*/
|
||||||
|
class MongoRepository<TAggregateRoot : IAggregateRoot<String>>(private var repo: MongoTemplate)
|
||||||
|
: IRepository<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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
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 <TAggregateRoot : IAggregateRoot<TKey>, TKey> remove(id: TKey, clazz: Class<TAggregateRoot>) {
|
||||||
|
this.repo.remove(whereId(id), clazz)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
||||||
|
return this.repo.findOne(whereId(id), clazz) as TAggregateRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
||||||
|
this.repo.save(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
||||||
|
this.repo.save(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
package com.synebula.gaea.query.mongo
|
|
||||||
|
|
||||||
import com.synebula.gaea.log.ILogger
|
|
||||||
import com.synebula.gaea.query.OrderType
|
|
||||||
import org.springframework.data.domain.Sort
|
|
||||||
import org.springframework.data.mongodb.core.query.Criteria
|
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
|
||||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
|
||||||
import java.lang.reflect.Field
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 声明了Mongo查询的特有方法
|
|
||||||
*/
|
|
||||||
interface IMongoQuery {
|
|
||||||
/**
|
|
||||||
* 日志组件
|
|
||||||
*/
|
|
||||||
var logger: ILogger?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统类型
|
|
||||||
*/
|
|
||||||
private fun systemClass() = arrayOf(
|
|
||||||
"String",
|
|
||||||
"Date",
|
|
||||||
"Int",
|
|
||||||
"Double",
|
|
||||||
"Float",
|
|
||||||
"BigDecimal",
|
|
||||||
"Decimal")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取ID查询条件
|
|
||||||
*
|
|
||||||
* @param id 业务ID
|
|
||||||
*/
|
|
||||||
fun <TKey> idQuery(id: TKey): Query = Query(Criteria("_id").isEqualTo(id))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取视图对象的字段列表
|
|
||||||
*
|
|
||||||
* @param clazz 视图对象类型
|
|
||||||
*/
|
|
||||||
fun <TView> fields(clazz: Class<TView>): List<String> {
|
|
||||||
return analyseFields(clazz.declaredFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取查询条件
|
|
||||||
*
|
|
||||||
* @param query 查询条件
|
|
||||||
* @param fields 字段列表
|
|
||||||
*/
|
|
||||||
fun select(query: Query, fields: Array<String>): Query {
|
|
||||||
fields.forEach {
|
|
||||||
query.fields().include(it)
|
|
||||||
}
|
|
||||||
return query
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据参数获取查询条件
|
|
||||||
*
|
|
||||||
* @param query 查询条件
|
|
||||||
* @param params 参数列表
|
|
||||||
* @param clazz 视图类对象
|
|
||||||
*/
|
|
||||||
fun <TView> where(query: Query, params: Map<String, Any>?, clazz: Class<TView>): Query {
|
|
||||||
val criteria = Criteria()
|
|
||||||
if (params != null) {
|
|
||||||
for (param in params) {
|
|
||||||
val value = this.changeFieldType(param.key, param.value, clazz)
|
|
||||||
criteria.and(param.key).isEqualTo(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return query.addCriteria(criteria)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取排序对象
|
|
||||||
*
|
|
||||||
* @param orders 排序条件字段
|
|
||||||
*/
|
|
||||||
fun order(orders: Map<String, OrderType>?): Sort {
|
|
||||||
val orderList = mutableListOf<Sort.Order>()
|
|
||||||
orders?.forEach {
|
|
||||||
orderList.add(Sort.Order(Sort.Direction.valueOf(it.value.name), it.key))
|
|
||||||
}
|
|
||||||
return if (orderList.size == 0)
|
|
||||||
Sort.by("_id")
|
|
||||||
else
|
|
||||||
Sort.by(orderList)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分析视图字段对象,获取深层字段列表
|
|
||||||
*
|
|
||||||
* @param fields 需要分析的视图字段
|
|
||||||
*/
|
|
||||||
fun analyseFields(fields: Array<Field>): List<String> {
|
|
||||||
val names = mutableListOf<String>()
|
|
||||||
fields.forEach { field ->
|
|
||||||
names.add(field.name)
|
|
||||||
if (!field.type.isPrimitive
|
|
||||||
&& !field.type.isArray
|
|
||||||
&& !this.systemClass().contains(field.type.simpleName))
|
|
||||||
names.addAll(this.analyseFields(field.type.declaredFields).map { "${field.name}.$it" })
|
|
||||||
}
|
|
||||||
return names
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换查询条件指定字段的类型
|
|
||||||
*
|
|
||||||
* @param key 字段名称
|
|
||||||
* @param value 字段值
|
|
||||||
* @param clazz 视图类对象
|
|
||||||
*/
|
|
||||||
fun <TView> changeFieldType(key: String, value: Any, clazz: Class<TView>): Any? {
|
|
||||||
val getter = clazz.getMethod("get${key.substring(0, 1).toUpperCase()}${key.substring(1)}")
|
|
||||||
return this.convertType(value.toString(), getter.returnType)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换String到指定类型
|
|
||||||
*
|
|
||||||
* @param value 字段值
|
|
||||||
* @param clazz 视图类对象
|
|
||||||
*/
|
|
||||||
fun convertType(value: String, clazz: Class<*>): Any? {
|
|
||||||
if (!clazz.isPrimitive) { // 判断基本类型
|
|
||||||
if (clazz == String::class.java) { // 如果是string则直接返回
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
// 如果不为null 则通过反射实例一个对象返回
|
|
||||||
return if ("" == value) null else clazz.getConstructor(String::class.java).newInstance(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下面处理基本类型,返回包装类
|
|
||||||
return when (clazz.name) {
|
|
||||||
"int" -> Integer.parseInt(value)
|
|
||||||
"byte" -> java.lang.Byte.parseByte(value)
|
|
||||||
"boolean" -> java.lang.Boolean.parseBoolean(value)
|
|
||||||
"double" -> java.lang.Double.parseDouble(value)
|
|
||||||
"float" -> java.lang.Float.parseFloat(value)
|
|
||||||
"long" -> java.lang.Long.parseLong(value)
|
|
||||||
"short" -> java.lang.Short.parseShort(value)
|
|
||||||
else -> value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package com.synebula.gaea.repository.mongo
|
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.query.Criteria
|
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
|
||||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
|
||||||
|
|
||||||
interface IMongoRepository {
|
|
||||||
/**
|
|
||||||
* 获取ID查询条件
|
|
||||||
*
|
|
||||||
* @param id 业务ID
|
|
||||||
*/
|
|
||||||
fun <TKey> idQuery(id: TKey): Query = Query(Criteria("_id").isEqualTo(id))
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package com.synebula.gaea.repository.mongo
|
|
||||||
|
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
|
||||||
import com.synebula.gaea.domain.repository.IRepository
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate
|
|
||||||
import org.springframework.data.mongodb.core.query.Criteria
|
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
|
||||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现IAggregateRoot的mongo仓储类
|
|
||||||
* @param repo MongoRepo对象
|
|
||||||
*/
|
|
||||||
class MongoRepository<TAggregateRoot : IAggregateRoot<String>>(private var repo: MongoTemplate)
|
|
||||||
: IRepository<TAggregateRoot, String>, IMongoRepository {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 仓储的对象类
|
|
||||||
*/
|
|
||||||
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(idQuery(id), this.clazz!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(id: String): TAggregateRoot {
|
|
||||||
return this.repo.findOne(idQuery(id), clazz!!) as TAggregateRoot
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
|
||||||
return this.repo.findOne(idQuery(id.toString()), clazz) as TAggregateRoot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.synebula.gaea.repository.mongo
|
|
||||||
|
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
|
||||||
import com.synebula.gaea.domain.repository.IRepositoryTyped
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate
|
|
||||||
import org.springframework.data.mongodb.core.query.Criteria
|
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
|
||||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现ITypedRepository的mongo仓储类
|
|
||||||
* @param repo MongoRepo对象
|
|
||||||
*/
|
|
||||||
open class MongoRepositoryTyped(private var repo: MongoTemplate)
|
|
||||||
: IRepositoryTyped, IMongoRepository {
|
|
||||||
|
|
||||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> remove(id: TKey, clazz: Class<TAggregateRoot>) {
|
|
||||||
this.repo.remove(idQuery(id), clazz)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
|
||||||
return this.repo.findOne(idQuery(id), clazz) as TAggregateRoot
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
|
||||||
this.repo.save(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
|
||||||
this.repo.save(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
mavenJava(MavenPublication) {
|
publish(MavenPublication) {
|
||||||
group 'com.synebula'
|
group 'com.synebula'
|
||||||
artifactId 'gaea'
|
artifactId 'gaea'
|
||||||
version "$version"
|
version "$version"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.synebula.gaea.data.date
|
package com.synebula.gaea.data.date
|
||||||
|
|
||||||
import com.synebula.gaea.data.type.TimeUnit
|
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -73,8 +72,6 @@ class DateTime : Comparable<DateTime> {
|
|||||||
return DateTime(instance)
|
return DateTime(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从Date格式转化
|
* 从Date格式转化
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.synebula.gaea.data.date
|
package com.synebula.gaea.data.date
|
||||||
|
|
||||||
import com.synebula.gaea.data.type.TimeUnit
|
|
||||||
|
|
||||||
object TimeExchanger {
|
object TimeExchanger {
|
||||||
/**
|
/**
|
||||||
* 转换率。分别对应:毫秒、秒、分、时、日
|
* 转换率。分别对应:毫秒、秒、分、时、日
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.synebula.gaea.data.type
|
package com.synebula.gaea.data.date
|
||||||
|
|
||||||
enum class TimeUnit {
|
enum class TimeUnit {
|
||||||
Millisecond,
|
Millisecond,
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.synebula.gaea.data.type
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据操作类型。包括创建、更新和删除。
|
|
||||||
* @author alex
|
|
||||||
* @version 0.0.1
|
|
||||||
* @since 2016年8月17日 下午2:48:29
|
|
||||||
*/
|
|
||||||
enum class DataOperateType {
|
|
||||||
Create,
|
|
||||||
|
|
||||||
Update,
|
|
||||||
|
|
||||||
Remove
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.synebula.gaea.data.type
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 排序枚举
|
|
||||||
*/
|
|
||||||
enum class SortDirectionEnum {
|
|
||||||
/*
|
|
||||||
* 升序
|
|
||||||
*/
|
|
||||||
ASC,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 降序
|
|
||||||
*/
|
|
||||||
DESC
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,6 @@ import java.util.*
|
|||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 2020-05-15
|
* @since 2020-05-15
|
||||||
*/
|
*/
|
||||||
class Command : ICommand {
|
open class Command : ICommand {
|
||||||
override var timestamp = 0L
|
override var timestamp = 0L
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.synebula.gaea.extension
|
||||||
|
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统类型
|
||||||
|
*/
|
||||||
|
val SystemClasses = arrayOf(
|
||||||
|
"String",
|
||||||
|
"Date",
|
||||||
|
"Int",
|
||||||
|
"Double",
|
||||||
|
"Float",
|
||||||
|
"BigDecimal",
|
||||||
|
"Decimal")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 深度获取所有字段信息字符串列表。
|
||||||
|
* @param prefix 前缀字符串
|
||||||
|
*/
|
||||||
|
fun Class<*>.fields(prefix: String = ""): List<String> {
|
||||||
|
val names = mutableListOf<String>()
|
||||||
|
this.declaredFields.forEach { field ->
|
||||||
|
val fullName = if (prefix.isNotEmpty()) "$prefix.${field.name}" else field.name
|
||||||
|
names.add(fullName)
|
||||||
|
if (!field.type.isPrimitive && !field.type.isArray && !SystemClasses.contains(field.type.simpleName)) {
|
||||||
|
names.addAll(field.type.fields(fullName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.synebula.gaea.data.date
|
package com.synebula.gaea.extension
|
||||||
|
|
||||||
|
import com.synebula.gaea.data.date.TimeSpan
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ interface IQueryTyped {
|
|||||||
* @param params 查询条件。
|
* @param params 查询条件。
|
||||||
* @return list
|
* @return list
|
||||||
*/
|
*/
|
||||||
fun <TView, TKey> list(params: Map<String, Any>?, clazz: Class<TView>): List<TView>
|
fun <TView> list(params: Map<String, Any>?, clazz: Class<TView>): List<TView>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据条件查询符合条件记录的数量
|
* 根据条件查询符合条件记录的数量
|
||||||
@@ -28,7 +28,7 @@ interface IQueryTyped {
|
|||||||
* @param params 查询条件。
|
* @param params 查询条件。
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
fun <TView, TKey> count(params: Map<String, Any>?, clazz: Class<TView>): Int
|
fun <TView> count(params: Map<String, Any>?, clazz: Class<TView>): Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据实体类条件查询所有符合条件记录(分页查询)
|
* 根据实体类条件查询所有符合条件记录(分页查询)
|
||||||
@@ -36,5 +36,5 @@ interface IQueryTyped {
|
|||||||
* @param params 分页条件
|
* @param params 分页条件
|
||||||
* @return 分页数据
|
* @return 分页数据
|
||||||
*/
|
*/
|
||||||
fun <TView, TKey> paging(params: PagingParam, clazz: Class<TView>): PagingData<TView>
|
fun <TView> paging(params: PagingParam, clazz: Class<TView>): PagingData<TView>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user