添加文件
This commit is contained in:
11
build.gradle
11
build.gradle
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
jvm_version = '21'
|
||||
@@ -7,6 +9,7 @@ buildscript {
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
|
||||
maven { url 'https://maven.aliyun.com/repository/central' }
|
||||
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||
mavenCentral()
|
||||
@@ -52,10 +55,14 @@ subprojects {
|
||||
sourceCompatibility = "$jvm_version"
|
||||
targetCompatibility = "$jvm_version"
|
||||
compileKotlin {
|
||||
kotlinOptions.jvmTarget = "$jvm_version"
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.valueOf("JVM_$jvm_version")
|
||||
}
|
||||
}
|
||||
compileTestKotlin {
|
||||
kotlinOptions.jvmTarget = "$jvm_version"
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.valueOf("JVM_$jvm_version")
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
||||
@@ -24,7 +24,7 @@ open class Cache<K, V>(expire: Int) : ICache<K, V> {
|
||||
}
|
||||
|
||||
override fun add(key: K, value: V) {
|
||||
this.guavaCache.put(key, value)
|
||||
this.guavaCache.put(key!!, value!!)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,10 +3,10 @@ package com.synebula.gaea.app.controller
|
||||
import com.synebula.gaea.app.controller.cmd.ICommandApp
|
||||
import com.synebula.gaea.app.controller.query.IQueryApp
|
||||
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.domain.service.ICommand
|
||||
import com.synebula.gaea.domain.service.IService
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
|
||||
/**
|
||||
@@ -17,7 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired
|
||||
* @param query 业务查询服务
|
||||
* @param logger 日志组件
|
||||
*/
|
||||
open class Application<TCommand : ICommand, TView, ID>(
|
||||
open class DomainApplication<TCommand : ICommand, TView, ID>(
|
||||
override var name: String,
|
||||
override var service: IService<ID>,
|
||||
override var query: IQuery<TView, ID>,
|
||||
@@ -3,10 +3,10 @@ package com.synebula.gaea.app.controller
|
||||
import com.synebula.gaea.app.controller.cmd.ISimpleCommandApp
|
||||
import com.synebula.gaea.app.controller.query.IQueryApp
|
||||
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.service.ISimpleService
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.record.service.IService
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
|
||||
/**
|
||||
@@ -17,14 +17,13 @@ import org.springframework.beans.factory.annotation.Autowired
|
||||
* @param query 业务查询服务
|
||||
* @param logger 日志组件
|
||||
*/
|
||||
open class SimpleApplication<TRoot : IAggregateRoot<ID>, ID>(
|
||||
open class RecordApplication<TRoot : IAggregateRoot<ID>, ID>(
|
||||
override var name: String,
|
||||
override var service: ISimpleService<TRoot, ID>,
|
||||
override var service: IService<TRoot, ID>,
|
||||
override var query: IQuery<TRoot, ID>,
|
||||
override var logger: ILogger,
|
||||
) : ISimpleCommandApp<TRoot, ID>, IQueryApp<TRoot, ID> {
|
||||
|
||||
|
||||
@Autowired
|
||||
override lateinit var httpMessageFactory: HttpMessageFactory
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.synebula.gaea.app.controller.IApplication
|
||||
import com.synebula.gaea.data.message.HttpMessage
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.service.ISimpleService
|
||||
import com.synebula.gaea.record.service.IService
|
||||
import com.synebula.gaea.spring.aop.annotation.Method
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@@ -16,12 +16,13 @@ import org.springframework.web.bind.annotation.*
|
||||
* @since 2020-05-15
|
||||
*/
|
||||
interface ISimpleCommandApp<TRoot : IAggregateRoot<ID>, ID> : IApplication {
|
||||
var service: ISimpleService<TRoot, ID>
|
||||
var service: IService<TRoot, ID>
|
||||
|
||||
@PostMapping
|
||||
@Method("添加")
|
||||
fun add(@RequestBody entity: TRoot): HttpMessage {
|
||||
return this.httpMessageFactory.create(service.add(entity))
|
||||
val id = service.add(entity)
|
||||
return this.httpMessageFactory.create(id!!)
|
||||
}
|
||||
|
||||
@PutMapping("/{id:.+}")
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.synebula.gaea.app.controller.cmd
|
||||
|
||||
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.service.ISimpleService
|
||||
import com.synebula.gaea.record.service.IService
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
|
||||
@@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired
|
||||
*/
|
||||
open class SimpleCommandApp<TRoot : IAggregateRoot<ID>, ID>(
|
||||
override var name: String,
|
||||
override var service: ISimpleService<TRoot, ID>,
|
||||
override var service: IService<TRoot, ID>,
|
||||
override var logger: ILogger,
|
||||
) : ISimpleCommandApp<TRoot, ID> {
|
||||
@Autowired
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.synebula.gaea.app.controller.query
|
||||
|
||||
import com.synebula.gaea.app.controller.IApplication
|
||||
import com.synebula.gaea.data.message.HttpMessage
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.Params
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.db.query.Params
|
||||
import com.synebula.gaea.spring.aop.annotation.Method
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.synebula.gaea.app.controller.query
|
||||
|
||||
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.synebula.gaea.jpa
|
||||
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.Page
|
||||
import com.synebula.gaea.query.Params
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.db.query.Page
|
||||
import com.synebula.gaea.db.query.Params
|
||||
import jakarta.persistence.EntityManager
|
||||
import org.springframework.data.jpa.repository.support.SimpleJpaRepository
|
||||
|
||||
@@ -14,7 +14,7 @@ class JpaQuery<TView, ID>(override var clazz: Class<TView>, entityManager: Entit
|
||||
}
|
||||
|
||||
override operator fun get(id: ID): TView? {
|
||||
val view = this.repo.findById(id)
|
||||
val view = this.repo.findById(id!!)
|
||||
return if (view.isPresent) view.get() else null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.synebula.gaea.jpa
|
||||
|
||||
import com.synebula.gaea.data.date.DateTime
|
||||
import com.synebula.gaea.query.Operator
|
||||
import com.synebula.gaea.query.Where
|
||||
import com.synebula.gaea.db.query.Operator
|
||||
import com.synebula.gaea.db.query.Where
|
||||
import jakarta.persistence.criteria.*
|
||||
import org.springframework.data.jpa.domain.Specification
|
||||
import java.lang.reflect.Field
|
||||
|
||||
@@ -5,13 +5,13 @@ import org.springframework.beans.factory.FactoryBean
|
||||
import org.springframework.cglib.proxy.Enhancer
|
||||
import org.springframework.data.repository.Repository
|
||||
|
||||
class JpaRepositoryFactory(
|
||||
class JpaDbContextFactory(
|
||||
private val beanFactory: BeanFactory,
|
||||
private val interfaceType: Class<*>,
|
||||
private val implBeanNames: List<String>
|
||||
) : FactoryBean<Any> {
|
||||
override fun getObject(): Any {
|
||||
val handler: JpaRepositoryProxy<*, *, *> = JpaRepositoryProxy<Repository<Any, Any>, Any, Any>(
|
||||
val handler: JpaDbContextProxy<*, *, *> = JpaDbContextProxy<Repository<Any, Any>, Any, Any>(
|
||||
beanFactory,
|
||||
interfaceType, implBeanNames
|
||||
)
|
||||
@@ -26,7 +26,7 @@ import java.lang.reflect.Method
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class JpaRepositoryProxy<T : Repository<S, ID>?, S, ID>(
|
||||
class JpaDbContextProxy<T : Repository<S, ID>?, S, ID>(
|
||||
beanFactory: BeanFactory,
|
||||
interfaceType: Class<*>,
|
||||
implementBeanNames: List<String>?
|
||||
@@ -8,5 +8,5 @@ import kotlin.reflect.KClass
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MustBeDocumented
|
||||
@Inherited
|
||||
@Import(JpaRepositoryRegister::class)
|
||||
annotation class JpaRepositoryProxyScan(val basePackages: Array<String> = [], val scanInterfaces: Array<KClass<*>> = [])
|
||||
@Import(JpaDbContextRegister::class)
|
||||
annotation class JpaDbContextProxyScan(val basePackages: Array<String> = [], val scanInterfaces: Array<KClass<*>> = [])
|
||||
@@ -24,17 +24,20 @@ import org.springframework.util.ClassUtils
|
||||
import java.util.*
|
||||
import java.util.stream.Collectors
|
||||
|
||||
class JpaRepositoryRegister : ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware,
|
||||
class JpaDbContextRegister : ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware,
|
||||
EnvironmentAware,
|
||||
BeanFactoryAware {
|
||||
|
||||
private lateinit var environment: Environment
|
||||
private lateinit var resourceLoader: ResourceLoader
|
||||
private var classLoader: ClassLoader? = null
|
||||
private var beanFactory: BeanFactory? = null
|
||||
|
||||
|
||||
override fun registerBeanDefinitions(metadata: AnnotationMetadata, registry: BeanDefinitionRegistry) {
|
||||
val attributes = AnnotationAttributes(
|
||||
metadata.getAnnotationAttributes(
|
||||
JpaRepositoryProxyScan::class.java.name
|
||||
JpaDbContextProxyScan::class.java.name
|
||||
) ?: mapOf()
|
||||
)
|
||||
val basePackages = attributes.getStringArray("basePackages")
|
||||
@@ -55,7 +58,7 @@ class JpaRepositoryRegister : ImportBeanDefinitionRegistrar, ResourceLoaderAware
|
||||
val implClazzDefinitions = scan(basePackages, arrayOf(beanClazzTypeFilter))
|
||||
for (definition in implClazzDefinitions) {
|
||||
definition.isAutowireCandidate = false
|
||||
registry.registerBeanDefinition(Objects.requireNonNull(definition.beanClassName), definition)
|
||||
registry.registerBeanDefinition(Objects.requireNonNull(definition.beanClassName!!), definition)
|
||||
}
|
||||
// 构建bean定义
|
||||
// 1 bean参数
|
||||
@@ -66,7 +69,7 @@ class JpaRepositoryRegister : ImportBeanDefinitionRegistrar, ResourceLoaderAware
|
||||
builder.addConstructorArgValue(beanClazz)
|
||||
builder.addConstructorArgValue(implBeanNames)
|
||||
val definition = builder.rawBeanDefinition as GenericBeanDefinition
|
||||
definition.beanClass = JpaRepositoryFactory::class.java
|
||||
definition.beanClass = JpaDbContextFactory::class.java
|
||||
definition.autowireMode = GenericBeanDefinition.AUTOWIRE_BY_TYPE
|
||||
registry.registerBeanDefinition(beanClazz.name, definition)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import com.synebula.gaea.jpa.proxy.method.resolver.AbstractMethodResolver
|
||||
import com.synebula.gaea.jpa.proxy.method.resolver.DefaultMethodResolver
|
||||
import com.synebula.gaea.jpa.proxy.method.resolver.FindMethodResolver
|
||||
import com.synebula.gaea.jpa.proxy.method.resolver.PageMethodResolver
|
||||
import com.synebula.gaea.query.Params
|
||||
import com.synebula.gaea.db.query.Params
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.jpa.domain.Specification
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.synebula.gaea.jpa.proxy.method.resolver
|
||||
|
||||
import com.synebula.gaea.jpa.toSpecification
|
||||
import com.synebula.gaea.query.Order
|
||||
import com.synebula.gaea.query.Params
|
||||
import com.synebula.gaea.db.query.Order
|
||||
import com.synebula.gaea.db.query.Params
|
||||
import jakarta.persistence.EmbeddedId
|
||||
import jakarta.persistence.Id
|
||||
import org.springframework.data.domain.Page
|
||||
@@ -10,7 +10,7 @@ import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import java.util.*
|
||||
import com.synebula.gaea.query.Page as QueryPage
|
||||
import com.synebula.gaea.db.query.Page as QueryPage
|
||||
|
||||
/**
|
||||
* 分页方法参数映射
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.synebula.gaea.mongodb
|
||||
|
||||
import com.synebula.gaea.data.date.DateTime
|
||||
import com.synebula.gaea.query.Operator
|
||||
import com.synebula.gaea.query.Order
|
||||
import com.synebula.gaea.query.Where
|
||||
import com.synebula.gaea.db.query.Operator
|
||||
import com.synebula.gaea.db.query.Order
|
||||
import com.synebula.gaea.db.query.Where
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
|
||||
@@ -4,11 +4,11 @@ import com.synebula.gaea.spring.autoconfig.Factory
|
||||
import com.synebula.gaea.spring.autoconfig.Proxy
|
||||
import org.springframework.beans.factory.BeanFactory
|
||||
|
||||
class MongodbRepositoryFactory(
|
||||
class MongoDbContextFactory(
|
||||
supertype: Class<*>,
|
||||
var beanFactory: BeanFactory,
|
||||
) : Factory(supertype) {
|
||||
override fun createProxy(): Proxy {
|
||||
return MongodbRepositoryProxy(supertype, this.beanFactory)
|
||||
return MongoDbContextProxy(supertype, this.beanFactory)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.synebula.gaea.mongodb.autoconfig
|
||||
|
||||
import com.synebula.gaea.db.context.IDbContext
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import com.synebula.gaea.mongodb.db.query.MongodbQuery
|
||||
import com.synebula.gaea.mongodb.repository.MongodbRepository
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.reflect.getGenericInterface
|
||||
import com.synebula.gaea.spring.autoconfig.Proxy
|
||||
import org.springframework.beans.factory.BeanFactory
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class MongoDbContextProxy(
|
||||
private var supertype: Class<*>, private var beanFactory: BeanFactory
|
||||
) : Proxy() {
|
||||
|
||||
/**
|
||||
* 实际的执行类
|
||||
*/
|
||||
private var context: Any?
|
||||
|
||||
init {
|
||||
if (this.supertype.interfaces.any { it == IDbContext::class.java }) {
|
||||
this.context = beanFactory.getBean(IDbContext::class.java)
|
||||
if (context == null) {
|
||||
val constructor = IDbContext::class.java.getConstructor(Class::class.java, MongoTemplate::class.java)
|
||||
this.context = constructor.newInstance(this.beanFactory.getBean(MongoTemplate::class.java))
|
||||
|
||||
}
|
||||
} else {
|
||||
// 判断接口类型
|
||||
val clazz: Class<*> // 代理服务类型
|
||||
val interfaceClazz: Class<*> // 代理服务接口
|
||||
|
||||
if (this.supertype.interfaces.any { it == IQuery::class.java }) {
|
||||
clazz = MongodbQuery::class.java
|
||||
interfaceClazz = IQuery::class.java
|
||||
} else {
|
||||
clazz = MongodbRepository::class.java
|
||||
interfaceClazz = IRepository::class.java
|
||||
}
|
||||
val constructor = clazz.getConstructor(Class::class.java, MongoTemplate::class.java)
|
||||
this.context = constructor.newInstance(
|
||||
this.supertype.getGenericInterface(interfaceClazz)!!.actualTypeArguments[0],
|
||||
this.beanFactory.getBean(MongoTemplate::class.java)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行代理方法
|
||||
*
|
||||
* @param proxy 代理对象
|
||||
* @param method 需要执行的方法
|
||||
* @param args 参数列表
|
||||
* @return 方法执行结果
|
||||
*/
|
||||
override fun exec(proxy: Any, method: Method, args: Array<Any>): Any? {
|
||||
try {
|
||||
val proxyMethod: Method = this.context!!.javaClass.getMethod(method.name, *method.parameterTypes)
|
||||
return proxyMethod.invoke(this.context, *args)
|
||||
} catch (ex: NoSuchMethodException) {
|
||||
throw NoSuchMethodException("method [${method.toGenericString()}] not implements in class [${this.context!!.javaClass}], you must implements interface [${this.supertype.name}] ")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.synebula.gaea.mongodb.autoconfig
|
||||
|
||||
import com.synebula.gaea.db.context.IDbContext
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.spring.autoconfig.Register
|
||||
import org.springframework.beans.factory.config.BeanDefinition
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder
|
||||
@@ -9,20 +10,20 @@ import org.springframework.beans.factory.support.GenericBeanDefinition
|
||||
import org.springframework.core.annotation.AnnotationAttributes
|
||||
import org.springframework.core.type.AnnotationMetadata
|
||||
|
||||
class MongodbRepositoryRegister : Register() {
|
||||
class MongoDbContextRegister : Register() {
|
||||
override fun scan(metadata: AnnotationMetadata): Map<String, BeanDefinition> {
|
||||
val result = mutableMapOf<String, BeanDefinition>()
|
||||
|
||||
// 获取注解参数信息:basePackages
|
||||
val attributes = AnnotationAttributes(
|
||||
metadata.getAnnotationAttributes(
|
||||
MongodbRepositoryScan::class.java.name
|
||||
MongoDbRepositoryScan::class.java.name
|
||||
) ?: mapOf()
|
||||
)
|
||||
val basePackages = attributes.getStringArray("basePackages")
|
||||
val beanDefinitions = this.doScan(
|
||||
basePackages,
|
||||
arrayOf(this.interfaceFilter(arrayOf(IRepository::class.java, IQuery::class.java)))
|
||||
arrayOf(this.interfaceFilter(arrayOf(IDbContext::class.java, IQuery::class.java, IRepository::class.java)))
|
||||
)
|
||||
beanDefinitions.forEach { beanDefinition ->
|
||||
// 获取实际的bean类型
|
||||
@@ -44,7 +45,7 @@ class MongodbRepositoryRegister : Register() {
|
||||
builder.addConstructorArgValue(beanClazz)
|
||||
builder.addConstructorArgValue(this._beanFactory)
|
||||
val definition = builder.rawBeanDefinition as GenericBeanDefinition
|
||||
definition.beanClass = MongodbRepositoryFactory::class.java
|
||||
definition.beanClass = MongoDbContextFactory::class.java
|
||||
definition.autowireMode = GenericBeanDefinition.AUTOWIRE_BY_TYPE
|
||||
result[beanClazz.name] = definition
|
||||
}
|
||||
@@ -59,7 +60,7 @@ class MongodbRepositoryRegister : Register() {
|
||||
builder.addConstructorArgValue(this._beanFactory)
|
||||
builder.addConstructorArgValue(emptyArray<String>())
|
||||
val definition = builder.rawBeanDefinition as GenericBeanDefinition
|
||||
definition.beanClass = MongodbRepositoryFactory::class.java
|
||||
definition.beanClass = MongoDbContextFactory::class.java
|
||||
definition.autowireMode = GenericBeanDefinition.AUTOWIRE_BY_TYPE
|
||||
result[IRepository::class.java.name] = definition
|
||||
}
|
||||
@@ -8,5 +8,5 @@ import java.lang.annotation.Inherited
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MustBeDocumented
|
||||
@Inherited
|
||||
@Import(MongodbRepositoryRegister::class)
|
||||
annotation class MongodbRepositoryScan(val basePackages: Array<String> = [])
|
||||
@Import(MongoDbContextRegister::class)
|
||||
annotation class MongoDbRepositoryScan(val basePackages: Array<String> = [])
|
||||
@@ -1,55 +0,0 @@
|
||||
package com.synebula.gaea.mongodb.autoconfig
|
||||
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import com.synebula.gaea.mongodb.query.MongodbQuery
|
||||
import com.synebula.gaea.mongodb.repository.MongodbRepository
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.reflect.getGenericInterface
|
||||
import com.synebula.gaea.spring.autoconfig.Proxy
|
||||
import org.springframework.beans.factory.BeanFactory
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class MongodbRepositoryProxy(
|
||||
private var supertype: Class<*>, private var beanFactory: BeanFactory
|
||||
) : Proxy() {
|
||||
|
||||
private var mongodbRepo: Any
|
||||
|
||||
init {
|
||||
// 判断接口类型
|
||||
val clazz: Class<*> // 代理服务类型
|
||||
val interfaceClazz: Class<*> // 代理服务接口
|
||||
if (this.supertype.interfaces.any { it == IRepository::class.java }) {
|
||||
clazz = MongodbRepository::class.java
|
||||
interfaceClazz = IRepository::class.java
|
||||
} else {
|
||||
clazz = MongodbQuery::class.java
|
||||
interfaceClazz = IQuery::class.java
|
||||
}
|
||||
|
||||
val constructor = clazz.getConstructor(Class::class.java, MongoTemplate::class.java)
|
||||
this.mongodbRepo = constructor.newInstance(
|
||||
this.supertype.getGenericInterface(interfaceClazz)!!.actualTypeArguments[0],
|
||||
this.beanFactory.getBean(MongoTemplate::class.java)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行代理方法
|
||||
*
|
||||
* @param proxy 代理对象
|
||||
* @param method 需要执行的方法
|
||||
* @param args 参数列表
|
||||
* @return 方法执行结果
|
||||
*/
|
||||
override fun exec(proxy: Any, method: Method, args: Array<Any>): Any? {
|
||||
try {
|
||||
val proxyMethod: Method = this.mongodbRepo.javaClass.getMethod(method.name, *method.parameterTypes)
|
||||
return proxyMethod.invoke(this.mongodbRepo, *args)
|
||||
} catch (ex: NoSuchMethodException) {
|
||||
throw NoSuchMethodException("method [${method.toGenericString()}] not implements in class [${this.mongodbRepo.javaClass}], you must implements interface [${this.supertype.name}] ")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.synebula.gaea.mongodb.db.context
|
||||
|
||||
import com.synebula.gaea.db.IEntity
|
||||
import com.synebula.gaea.db.context.IDbContext
|
||||
import com.synebula.gaea.mongodb.where
|
||||
import com.synebula.gaea.mongodb.whereId
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
|
||||
class MongodbContext(
|
||||
protected var template: MongoTemplate
|
||||
) : IDbContext {
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> add(entity: TEntity, clazz: Class<TEntity>) {
|
||||
this.template.save(entity)
|
||||
}
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> add(entities: List<TEntity>, clazz: Class<TEntity>) {
|
||||
this.template.insert(entities, clazz)
|
||||
}
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> remove(id: ID, clazz: Class<TEntity>) {
|
||||
this.template.remove(whereId(id), clazz)
|
||||
}
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> get(id: ID, clazz: Class<TEntity>): TEntity? {
|
||||
return this.template.findOne(whereId(id), clazz)
|
||||
}
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> update(entity: TEntity, clazz: Class<TEntity>) {
|
||||
this.template.save(entity)
|
||||
}
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> update(entities: List<TEntity>, clazz: Class<TEntity>) {
|
||||
this.template.save(entities)
|
||||
}
|
||||
|
||||
override fun <TEntity : IEntity<ID>, ID> count(params: Map<String, String>?, clazz: Class<TEntity>): Int {
|
||||
val query = Query()
|
||||
return this.template.count(query.where(params, clazz), clazz).toInt()
|
||||
}
|
||||
|
||||
override val isCommitted=true
|
||||
|
||||
override fun commit() {
|
||||
}
|
||||
|
||||
override fun rollback() {
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,20 @@
|
||||
package com.synebula.gaea.mongodb.query
|
||||
package com.synebula.gaea.mongodb.db.query
|
||||
|
||||
|
||||
import com.synebula.gaea.ext.firstCharLowerCase
|
||||
import com.synebula.gaea.mongodb.order
|
||||
import com.synebula.gaea.mongodb.select
|
||||
import com.synebula.gaea.mongodb.where
|
||||
import com.synebula.gaea.mongodb.whereId
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.Page
|
||||
import com.synebula.gaea.query.Params
|
||||
import com.synebula.gaea.query.Table
|
||||
import com.synebula.gaea.db.query.IQuery
|
||||
import com.synebula.gaea.db.query.Page
|
||||
import com.synebula.gaea.db.query.Params
|
||||
import com.synebula.gaea.db.query.Table
|
||||
import com.synebula.gaea.reflect.fieldNames
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
|
||||
/**
|
||||
* 实现IQuery的Mongodb查询类
|
||||
* @param template MongodbRepo对象
|
||||
*/
|
||||
|
||||
open class MongodbQuery<TView, ID>(override var clazz: Class<TView>, var template: MongoTemplate) :
|
||||
IQuery<TView, ID> {
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.synebula.gaea.mongodb.query
|
||||
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.IQueryFactory
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
|
||||
class MongodbQueryFactory(var template: MongoTemplate) : IQueryFactory {
|
||||
|
||||
/**
|
||||
* 创建IQuery接口类型
|
||||
*/
|
||||
override fun createRawQuery(clazz: Class<*>): IQuery<*, *> {
|
||||
val constructor = MongodbQuery::class.java.getConstructor(Class::class.java, MongoTemplate::class.java)
|
||||
return constructor.newInstance(clazz, this.template)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建IQuery接口类型
|
||||
*/
|
||||
override fun <T, I> createQuery(clazz: Class<T>): IQuery<T, I> {
|
||||
return MongodbQuery(clazz, template)
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.synebula.gaea.mongodb.query
|
||||
|
||||
|
||||
import com.synebula.gaea.ext.firstCharLowerCase
|
||||
import com.synebula.gaea.mongodb.order
|
||||
import com.synebula.gaea.mongodb.select
|
||||
import com.synebula.gaea.mongodb.where
|
||||
import com.synebula.gaea.mongodb.whereId
|
||||
import com.synebula.gaea.query.IUniversalQuery
|
||||
import com.synebula.gaea.query.Page
|
||||
import com.synebula.gaea.query.Params
|
||||
import com.synebula.gaea.query.Table
|
||||
import com.synebula.gaea.reflect.fieldNames
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
|
||||
/**
|
||||
* 实现IQuery的Mongodb查询类
|
||||
* @param template MongodbRepo对象
|
||||
*/
|
||||
open class MongodbUniversalQuery(var template: MongoTemplate) : IUniversalQuery {
|
||||
|
||||
/**
|
||||
* 使用View解析是collection时是否校验存在,默认不校验
|
||||
*/
|
||||
var validViewCollection = false
|
||||
|
||||
override fun <TView, ID> get(id: ID, clazz: Class<TView>): TView? {
|
||||
return this.template.findOne(whereId(id), clazz, this.collection(clazz))
|
||||
}
|
||||
|
||||
override fun <TView> list(params: Map<String, String>?, clazz: Class<TView>): List<TView> {
|
||||
val fields = this.fields(clazz)
|
||||
val query = Query()
|
||||
query.where(params, clazz)
|
||||
query.select(fields)
|
||||
return this.find(query, clazz)
|
||||
}
|
||||
|
||||
override fun <TView> count(params: Map<String, String>?, clazz: Class<TView>): Int {
|
||||
val query = Query()
|
||||
return this.template.count(query.where(params, clazz), this.collection(clazz)).toInt()
|
||||
}
|
||||
|
||||
override fun <TView> paging(params: Params, clazz: Class<TView>): Page<TView> {
|
||||
val query = Query()
|
||||
val fields = this.fields(clazz)
|
||||
val result = Page<TView>(params.page, params.size)
|
||||
result.total = this.count(params.parameters, clazz)
|
||||
//如果总数和索引相同,说明该页没有数据,直接跳到上一页
|
||||
if (result.total == result.index) {
|
||||
params.page -= 1
|
||||
result.page -= 1
|
||||
}
|
||||
query.select(fields)
|
||||
query.where(params.parameters, clazz)
|
||||
query.with(order(params.orders))
|
||||
query.skip(params.index).limit(params.size)
|
||||
result.data = this.find(query, clazz)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun <TView> range(field: String, params: List<Any>, clazz: Class<TView>): List<TView> {
|
||||
return this.find(Query.query(Criteria.where(field).`in`(params)), clazz)
|
||||
}
|
||||
|
||||
protected fun <TView> find(query: Query, clazz: Class<TView>): List<TView> {
|
||||
return this.template.find(query, clazz, this.collection(clazz))
|
||||
}
|
||||
|
||||
fun <TView> fields(clazz: Class<TView>): Array<String> {
|
||||
return clazz.fieldNames().toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取collection
|
||||
*/
|
||||
fun <TView> collection(clazz: Class<TView>): String {
|
||||
val table = clazz.getDeclaredAnnotation(Table::class.java)
|
||||
return if (table != null) table.name
|
||||
else {
|
||||
val name = clazz.simpleName.removeSuffix("View").firstCharLowerCase()
|
||||
if (!validViewCollection || this.template.collectionExists(name)) name
|
||||
else throw RuntimeException("找不到名为[${clazz.name}]的集合")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.synebula.gaea.mongodb.repository
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IUniversalRepository
|
||||
import com.synebula.gaea.mongodb.where
|
||||
import com.synebula.gaea.mongodb.whereId
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
|
||||
/**
|
||||
* 实现ITypedRepository的Mongodb仓储类
|
||||
* @param repo MongodbRepo对象
|
||||
*/
|
||||
open class MongodbUniversalRepository(private var repo: MongoTemplate) : IUniversalRepository {
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> remove(id: ID, clazz: Class<TAggregateRoot>) {
|
||||
this.repo.remove(whereId(id), clazz)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> get(
|
||||
id: ID,
|
||||
clazz: Class<TAggregateRoot>,
|
||||
): TAggregateRoot? {
|
||||
return this.repo.findOne(whereId(id), clazz)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(
|
||||
root: TAggregateRoot,
|
||||
clazz: Class<TAggregateRoot>,
|
||||
) {
|
||||
this.repo.save(root)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新多个个对象。
|
||||
*
|
||||
* @param roots 需要更新的对象。
|
||||
*/
|
||||
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(
|
||||
roots: List<TAggregateRoot>,
|
||||
clazz: Class<TAggregateRoot>
|
||||
) {
|
||||
this.repo.save(roots)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(root: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
||||
this.repo.save(root)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(
|
||||
roots: List<TAggregateRoot>,
|
||||
clazz: Class<TAggregateRoot>,
|
||||
) {
|
||||
this.repo.insert(roots, clazz)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot> count(params: Map<String, String>?, clazz: Class<TAggregateRoot>): Int {
|
||||
val query = Query()
|
||||
return this.repo.count(query.where(params, clazz), clazz).toInt()
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
||||
|
||||
class HttpMessage(private var serializer: IJsonSerializer) : DataMessage<Any>() {
|
||||
|
||||
|
||||
constructor(data: Any, serializer: IJsonSerializer) : this(serializer) {
|
||||
this.data = data
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.domain.model
|
||||
package com.synebula.gaea.db
|
||||
|
||||
/**
|
||||
* 继承本接口,说明对象为实体类型。
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.synebula.gaea.db.context
|
||||
|
||||
import com.synebula.gaea.db.IEntity
|
||||
|
||||
/**
|
||||
* 继承自IUnitOfWork,表示实现了工作单元模式的上下文接口。
|
||||
*
|
||||
* @author alex
|
||||
*/
|
||||
interface IDbContext : IUnitOfWork {
|
||||
/**
|
||||
* 插入单个对象。
|
||||
*
|
||||
* @param entity 需要插入的对象。
|
||||
* @return 返回原对象,如果对象ID为自增,则补充自增ID。
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> add(entity: TEntity, clazz: Class<TEntity>)
|
||||
|
||||
/**
|
||||
* 插入多个个对象。
|
||||
*
|
||||
* @param entities 需要插入的对象。
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> add(entities: List<TEntity>, clazz: Class<TEntity>)
|
||||
|
||||
/**
|
||||
* 更新对象。
|
||||
*
|
||||
* @param entity 需要更新的对象。
|
||||
* @return
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> update(entity: TEntity, clazz: Class<TEntity>)
|
||||
|
||||
/**
|
||||
* 更新多个个对象。
|
||||
*
|
||||
* @param entities 需要更新的对象。
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> update(entities: List<TEntity>, clazz: Class<TEntity>)
|
||||
|
||||
/**
|
||||
* 通过id删除该条数据
|
||||
*
|
||||
* @param id id
|
||||
* @param clazz 操作数据的类型
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> remove(id: ID, clazz: Class<TEntity>)
|
||||
|
||||
/**
|
||||
* 根据ID获取对象。
|
||||
*
|
||||
* @param id id
|
||||
* @param clazz 操作数据的类型
|
||||
* @return 聚合根
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> get(id: ID, clazz: Class<TEntity>): TEntity?
|
||||
|
||||
|
||||
/**
|
||||
* 根据条件查询符合条件记录的数量
|
||||
*
|
||||
* @param params 查询条件。
|
||||
* @return int
|
||||
*/
|
||||
fun <TEntity : IEntity<ID>, ID> count(params: Map<String, String>?, clazz: Class<TEntity>): Int
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.domain.repository.context
|
||||
package com.synebula.gaea.db.context
|
||||
|
||||
/**
|
||||
* 表示所有继承于该接口的类型都是Unit Of Work的一种实现。
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
/**
|
||||
* 查询基接口, 其中方法都指定了查询的视图类型。
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
enum class Operator {
|
||||
/**
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
/**
|
||||
* class OrderType
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
/**
|
||||
* 分页数据。
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
/**
|
||||
* class 分页参数信息
|
||||
@@ -1,3 +1,3 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
annotation class Table(val name: String = "")
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.query
|
||||
package com.synebula.gaea.db.query
|
||||
|
||||
/**
|
||||
* 字段注解,规定字段的查询方式
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.synebula.gaea.domain.event
|
||||
|
||||
import com.synebula.gaea.data.message.IEvent
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.db.IEntity
|
||||
|
||||
class AfterRemoveEvent<T : IAggregateRoot<I>, I>(var id: I? = null) : IEvent
|
||||
class AfterRemoveEvent<T : IEntity<I>, I>(var id: I? = null) : IEvent
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.synebula.gaea.domain.event
|
||||
|
||||
import com.synebula.gaea.data.message.IEvent
|
||||
import com.synebula.gaea.db.IEntity
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
|
||||
class BeforeRemoveEvent<T : IAggregateRoot<I>, I>(var id: I? = null) : IEvent
|
||||
class BeforeRemoveEvent<T : IEntity<I>, I>(var id: I? = null) : IEvent
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.synebula.gaea.domain.model
|
||||
|
||||
abstract class AggregateRoot<ID> : Entity<ID>(), IAggregateRoot<ID> {
|
||||
override var alive: Boolean = true
|
||||
override var avalible: Boolean = true
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
package com.synebula.gaea.domain.model
|
||||
|
||||
import com.synebula.gaea.db.IEntity
|
||||
|
||||
abstract class Entity<ID> : IEntity<ID>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.synebula.gaea.domain.model
|
||||
|
||||
import com.synebula.gaea.db.IEntity
|
||||
|
||||
/**
|
||||
* 继承本接口,说明对象为聚合根。
|
||||
*
|
||||
@@ -10,5 +12,5 @@ interface IAggregateRoot<ID> : IEntity<ID> {
|
||||
/**
|
||||
* 实体对象是否有效。
|
||||
*/
|
||||
var alive: Boolean
|
||||
var avalible: Boolean
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.synebula.gaea.domain.model
|
||||
|
||||
/**
|
||||
* 继承本接口,说明对象为值类型。
|
||||
* @author alex
|
||||
*/
|
||||
interface IValue
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.synebula.gaea.domain.repository
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
|
||||
/**
|
||||
* 定义了提供增删改的仓储接口。
|
||||
* 本接口泛型放置到方法上,并需要显式提供聚合根的class对象
|
||||
*/
|
||||
interface IUniversalRepository {
|
||||
/**
|
||||
* 插入单个对象。
|
||||
*
|
||||
* @param root 需要插入的对象。
|
||||
* @return 返回原对象,如果对象ID为自增,则补充自增ID。
|
||||
*/
|
||||
fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(root: TAggregateRoot, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 插入多个个对象。
|
||||
*
|
||||
* @param roots 需要插入的对象。
|
||||
*/
|
||||
fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(roots: List<TAggregateRoot>, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 更新对象。
|
||||
*
|
||||
* @param root 需要更新的对象。
|
||||
* @return
|
||||
*/
|
||||
fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(root: TAggregateRoot, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 更新多个个对象。
|
||||
*
|
||||
* @param roots 需要更新的对象。
|
||||
*/
|
||||
fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(roots: List<TAggregateRoot>, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 通过id删除该条数据
|
||||
*
|
||||
* @param id id
|
||||
* @param clazz 操作数据的类型
|
||||
*/
|
||||
fun <TAggregateRoot : IAggregateRoot<ID>, ID> remove(id: ID, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 根据ID获取对象。
|
||||
*
|
||||
* @param id id
|
||||
* @param clazz 操作数据的类型
|
||||
* @return 聚合根
|
||||
*/
|
||||
fun <TAggregateRoot : IAggregateRoot<ID>, ID> get(id: ID, clazz: Class<TAggregateRoot>): TAggregateRoot?
|
||||
|
||||
|
||||
/**
|
||||
* 根据条件查询符合条件记录的数量
|
||||
*
|
||||
* @param params 查询条件。
|
||||
* @return int
|
||||
*/
|
||||
fun <TAggregateRoot> count(params: Map<String, String>?, clazz: Class<TAggregateRoot>): Int
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.synebula.gaea.domain.repository.context
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
|
||||
/**
|
||||
* 继承自IUnitOfWork,表示实现了工作单元模式的上下文接口。
|
||||
*
|
||||
* @author alex
|
||||
*/
|
||||
interface IContext : IUnitOfWork {
|
||||
/**
|
||||
* 将指定的聚合根标注为“新建”状态。
|
||||
* @param obj 聚合根
|
||||
*/
|
||||
fun <T : IAggregateRoot<ID>, ID> add(obj: T)
|
||||
|
||||
/**
|
||||
* 将指定的聚合根标注为“更改”状态。
|
||||
*
|
||||
* @param obj 聚合根
|
||||
*/
|
||||
fun <T : IAggregateRoot<ID>, ID> update(obj: T)
|
||||
|
||||
/**
|
||||
* 将指定的聚合根标注为“删除”状态。
|
||||
*
|
||||
* @param obj 聚合根
|
||||
*/
|
||||
fun <T : IAggregateRoot<ID>, ID> remove(obj: T)
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package com.synebula.gaea.domain.service
|
||||
|
||||
import com.synebula.gaea.bus.IBus
|
||||
import com.synebula.gaea.data.message.DataMessage
|
||||
import com.synebula.gaea.domain.event.AfterRemoveEvent
|
||||
import com.synebula.gaea.domain.event.BeforeRemoveEvent
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
|
||||
/**
|
||||
* 依赖了IRepository仓储借口的服务实现类 GenericsService
|
||||
* 该类依赖仓储接口 @see IGenericsRepository, 需要显式提供聚合根的class对象
|
||||
*
|
||||
* @param repository 仓储对象
|
||||
* @param clazz 聚合根类对象
|
||||
* @param logger 日志组件
|
||||
* @author alex
|
||||
* @version 0.1
|
||||
* @since 2020-05-17
|
||||
*/
|
||||
open class SimpleService<TRoot : IAggregateRoot<ID>, ID>(
|
||||
protected open var clazz: Class<TRoot>,
|
||||
protected open var repository: IRepository<TRoot, ID>,
|
||||
override var logger: ILogger,
|
||||
protected open var bus: IBus<Any>? = null
|
||||
) : ISimpleService<TRoot, ID> {
|
||||
|
||||
override fun add(root: TRoot): DataMessage<ID> {
|
||||
val msg = DataMessage<ID>()
|
||||
this.repository.add(root)
|
||||
msg.data = root.id
|
||||
return msg
|
||||
}
|
||||
|
||||
override fun update(id: ID, root: TRoot) {
|
||||
root.id = id
|
||||
this.repository.update(root)
|
||||
}
|
||||
|
||||
override fun remove(id: ID) {
|
||||
val beforeRemoveEvent = BeforeRemoveEvent<TRoot, ID>(id)
|
||||
this.bus?.publish(beforeRemoveEvent.topic(this.clazz), beforeRemoveEvent)
|
||||
this.repository.remove(id)
|
||||
val afterRemoveEvent = AfterRemoveEvent<TRoot, ID>(id)
|
||||
this.bus?.publish(afterRemoveEvent.topic(this.clazz), afterRemoveEvent)
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加对象
|
||||
*
|
||||
* @param roots 增加对象命令列表
|
||||
*/
|
||||
override fun add(roots: List<TRoot>) {
|
||||
this.repository.add(roots)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新对象
|
||||
*
|
||||
* @param roots 更新对象命令列表
|
||||
*/
|
||||
override fun update(roots: List<TRoot>) {
|
||||
this.repository.update(roots)
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.synebula.gaea.query
|
||||
|
||||
|
||||
/**
|
||||
* Query 工厂接口。 定义了Query的创建方法。
|
||||
*/
|
||||
interface IQueryFactory {
|
||||
|
||||
/**
|
||||
* 创建原始类型的IQuery接口类型
|
||||
*/
|
||||
fun createRawQuery(clazz: Class<*>): IQuery<*, *>
|
||||
|
||||
/**
|
||||
* 创建指定类型的IQuery接口类型
|
||||
*/
|
||||
fun <T, I> createQuery(clazz: Class<T>): IQuery<T, I>
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.synebula.gaea.query
|
||||
|
||||
/**
|
||||
* 查询基接口, 其中方法都指定了查询的视图类型。
|
||||
*
|
||||
* @author alex
|
||||
*/
|
||||
interface IUniversalQuery {
|
||||
/**
|
||||
* 根据Key获取对象。
|
||||
*
|
||||
* @param id 对象Key。
|
||||
* @return 视图结果
|
||||
*/
|
||||
fun <TView, ID> get(id: ID, clazz: Class<TView>): TView?
|
||||
|
||||
/**
|
||||
* 根据实体类条件查询所有符合条件记录
|
||||
*
|
||||
* @param params 查询条件。
|
||||
* @return 视图列表
|
||||
*/
|
||||
fun <TView> list(params: Map<String, String>?, clazz: Class<TView>): List<TView>
|
||||
|
||||
/**
|
||||
* 根据条件查询符合条件记录的数量
|
||||
*
|
||||
* @param params 查询条件。
|
||||
* @return 数量
|
||||
*/
|
||||
fun <TView> count(params: Map<String, String>?, clazz: Class<TView>): Int
|
||||
|
||||
/**
|
||||
* 根据实体类条件查询所有符合条件记录(分页查询)
|
||||
*
|
||||
* @param params 分页条件
|
||||
* @return 分页数据
|
||||
*/
|
||||
fun <TView> paging(params: Params, clazz: Class<TView>): Page<TView>
|
||||
|
||||
/**
|
||||
* 查询条件范围内数据。
|
||||
* @param field 查询字段
|
||||
* @param params 查询条件
|
||||
*
|
||||
* @return 视图列表
|
||||
*/
|
||||
fun <TView> range(field: String, params: List<Any>, clazz: Class<TView>): List<TView>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.synebula.gaea.record.model
|
||||
|
||||
import com.synebula.gaea.db.IEntity
|
||||
|
||||
interface IRecord<ID> : IEntity<ID>
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.domain.record
|
||||
package com.synebula.gaea.record.model
|
||||
|
||||
import java.util.*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.synebula.gaea.domain.service
|
||||
package com.synebula.gaea.record.service
|
||||
|
||||
import com.synebula.gaea.data.message.DataMessage
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.db.IEntity
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.synebula.gaea.log.ILogger
|
||||
* @version 0.0.1
|
||||
* @since 2016年9月18日 下午2:23:15
|
||||
*/
|
||||
interface ISimpleService<TAggregateRoot : IAggregateRoot<ID>, ID> {
|
||||
interface IService<Entity : IEntity<ID>, ID> {
|
||||
/**
|
||||
* 日志组件。
|
||||
*/
|
||||
@@ -20,31 +20,31 @@ interface ISimpleService<TAggregateRoot : IAggregateRoot<ID>, ID> {
|
||||
/**
|
||||
* 增加对象
|
||||
*
|
||||
* @param root 增加对象命令
|
||||
* @param entity 增加对象命令
|
||||
*/
|
||||
fun add(root: TAggregateRoot): DataMessage<ID>
|
||||
fun add(entity: Entity): ID?
|
||||
|
||||
/**
|
||||
* 增加对象
|
||||
*
|
||||
* @param roots 增加对象命令列表
|
||||
* @param entities 增加对象命令列表
|
||||
*/
|
||||
fun add(roots: List<TAggregateRoot>)
|
||||
fun add(entities: List<Entity>)
|
||||
|
||||
/**
|
||||
* 更新对象
|
||||
*
|
||||
* @param id 对象ID
|
||||
* @param root 更新对象命令
|
||||
* @param entity 更新对象命令
|
||||
*/
|
||||
fun update(id: ID, root: TAggregateRoot)
|
||||
fun update(id: ID, entity: Entity)
|
||||
|
||||
/**
|
||||
* 批量更新对象
|
||||
*
|
||||
* @param roots 更新对象命令列表
|
||||
* @param entities 更新对象命令列表
|
||||
*/
|
||||
fun update(roots: List<TAggregateRoot>)
|
||||
fun update(entities: List<Entity>)
|
||||
|
||||
/**
|
||||
* 增加对象
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.synebula.gaea.record.service
|
||||
|
||||
import com.synebula.gaea.bus.IBus
|
||||
import com.synebula.gaea.data.message.DataMessage
|
||||
import com.synebula.gaea.db.context.IDbContext
|
||||
import com.synebula.gaea.domain.event.AfterRemoveEvent
|
||||
import com.synebula.gaea.domain.event.BeforeRemoveEvent
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.record.model.IRecord
|
||||
|
||||
|
||||
/**
|
||||
* 依赖了IRepository仓储借口的服务实现类 GenericsService
|
||||
* 该类依赖仓储接口 @see IGenericsRepository, 需要显式提供聚合根的class对象
|
||||
*
|
||||
* @param context 仓储对象
|
||||
* @param clazz 聚合根类对象
|
||||
* @param logger 日志组件
|
||||
* @author alex
|
||||
* @version 0.1
|
||||
* @since 2020-05-17
|
||||
*/
|
||||
open class Service<TEntity : IRecord<ID>, ID>(
|
||||
protected open var clazz: Class<TEntity>,
|
||||
protected open var context: IDbContext,
|
||||
protected open var bus: IBus<Any>? = null,
|
||||
override var logger: ILogger
|
||||
) : IService<TEntity, ID> {
|
||||
|
||||
override fun add(entity: TEntity): ID? {
|
||||
this.context.add(entity, clazz)
|
||||
return entity.id
|
||||
}
|
||||
|
||||
override fun update(id: ID, entity: TEntity) {
|
||||
entity.id = id
|
||||
this.context.update(entity, clazz)
|
||||
}
|
||||
|
||||
override fun remove(id: ID) {
|
||||
val beforeRemoveEvent = BeforeRemoveEvent<TEntity, ID>(id)
|
||||
this.bus?.publish(beforeRemoveEvent.topic(this.clazz), beforeRemoveEvent)
|
||||
this.context.remove(id, clazz)
|
||||
val afterRemoveEvent = AfterRemoveEvent<TEntity, ID>(id)
|
||||
this.bus?.publish(afterRemoveEvent.topic(this.clazz), afterRemoveEvent)
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加对象
|
||||
*
|
||||
* @param entitys 增加对象命令列表
|
||||
*/
|
||||
override fun add(entitys: List<TEntity>) {
|
||||
this.context.add(entitys, clazz)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新对象
|
||||
*
|
||||
* @param entitys 更新对象命令列表
|
||||
*/
|
||||
override fun update(entitys: List<TEntity>) {
|
||||
this.context.update(entitys, clazz)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user