/* * ********************************************************************************************************************* * * !! * .F88X * X8888Y * .}888888N; * i888888N; .:! .I$WI: * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8& * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I * +888888N; .8888888Y "&&8Y.}8, * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$* * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~ * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi' * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/ * .:R888888I * .&888888I Copyright (c) 2016-2020. 博锐尚格科技股份有限公司 * ~8888' * .!88~ All rights reserved. * * ********************************************************************************************************************* */ package com.persagy.service import com.persagy.base.extensions.getAllDeclaredField import com.persagy.base.extensions.toJson import com.persagy.database.* import com.persagy.database.extensions.keyFieldList import com.persagy.database.extensions.keyValue import com.persagy.service.models.SCascadeQuery import com.persagy.service.models.annotations.SCascade import com.persagy.service.models.annotations.SCascadeCount import java.lang.reflect.Field import java.lang.reflect.ParameterizedType /** * 服务类基类 * * @author 庞利祥 */ open class SBaseService { /** 数据访问对象 */ protected var baseDao: SAbstractDao /** 实体类类型 */ val entityClass: Class get() = baseDao.entityClass /** * 构造函数 * * @param entityClazz 实体类 */ constructor(entityClazz: Class) { baseDao = daoFactory(entityClazz) } // Constructor() /** * 构造函数 * * @param daoObject 数据访问对象 */ constructor(daoObject: SAbstractDao) { baseDao = daoObject } // Constructor() /** * Dao对象工厂类 * * @param entityClazz 实体类 * @return 访问实体的Dao对象 */ private fun daoFactory(entityClazz: Class): SAbstractDao { @Suppress("UNCHECKED_CAST") val factory = Class.forName("com.persagy.mybatis.SDaoFactory").newInstance() as SAbstractDaoFactory return factory.createDao(entityClazz) } // Fun daoFactory /** * 在数据库中插入实体 * * @param entity 插入数据库的实体 * @return 插入是否成功 */ open fun insert(entity: ENTITY): Boolean { return baseDao.insert(entity) } // Fun insert() /** * 在数据库中插入实体 * * @param entity 插入数据库的实体 * @return 插入是否成功 */ open fun replace(entity: ENTITY): Boolean { return baseDao.replace(entity) } // Fun replace() /** * 删除实体 * * @param entity 被删除的实体 * @return 删除是否成功 */ open fun delete(entity: ENTITY): Boolean { return baseDao.delete(entity) } // Fun delete() /** * 根据条件删除 * * @param args 删除条件 * @return 删除是否成功 */ open fun delete(vararg args: Pair): Boolean { return baseDao.delete(*args) } // Fun delete() /** * 根据条件删除 * * @param args 删除条件 * @return 删除是否成功 */ open fun delete(vararg args: SFilter): Boolean { return baseDao.delete(*args) } // Fun delete() /** * 根据条件删除 * * @param args 删除条件 * @return 删除是否成功 */ open fun delete(args: List): Boolean { return baseDao.delete(args) } // Fun delete() /** * 根据条件删除 * * @param query 删除条件 * @return 删除是否成功 */ open fun delete(query: String): Boolean { return baseDao.delete(query) } // Fun delete() /** * 删除所有记录 * * @return 删除是否成功 */ open fun deleteAll(): Boolean { return baseDao.deleteAll() } // Fun deleteAll() /** * 更新实体 * * @param entity 更新实体 * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段 * @return 更新是否成功 */ open fun update(entity: ENTITY, projection: ArrayList? = null): Boolean { return baseDao.update(entity, projection) } // Fun update() /** * 根据条件更新 * * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段 * @param args 更新条件 * @return 更新是否成功 */ open fun update(entity: ENTITY, projection: ArrayList?, vararg args: Pair): Boolean { return baseDao.update(entity, projection, *args) } // Fun update() /** * 根据条件更新 * * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段 * @param args 更新条件 * @return 更新是否成功 */ open fun update(entity: ENTITY, projection: ArrayList?, vararg args: SFilter): Boolean { return baseDao.update(entity, projection, *args) } // Fun update() /** * 根据条件更新 * * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段 * @param args 更新条件 * @return 更新是否成功 */ open fun update(entity: ENTITY, projection: ArrayList?, args: List): Boolean { return baseDao.update(entity, projection, args) } // Fun update() /** * 根据条件更新 * * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段 * @param query 更新条件 * @return 更新是否成功 */ open fun update(entity: ENTITY, projection: ArrayList?, query: String): Boolean { return baseDao.update(entity, projection, query) } // Fun update() /** * 根据条件查询一条记录 * * @param args 查询条件 */ open fun select(vararg args: Pair): SQueryBuilder { return baseDao.select(*args) } // Fun select() /** * 根据条件查询记录 * * @param args 查询条件 * @return 查询构造器 */ open fun select(vararg args: SFilter): SQueryBuilder { return baseDao.select(*args) } // Fun select() /** * 根据条件查询记录 * * @param args 查询条件 * @return 查询构造器 */ open fun select(args: List): SQueryBuilder { return baseDao.select(args) } // Fun select() /** * 根据条件查询记录 * * @param query 查询条件 * @return 查询构造器 */ open fun select(query: String?): SQueryBuilder { return baseDao.select(query) } // Fun select() /** * 根据条件查询所有记录 * * @return 查找的记录 */ open fun selectAll(): SQueryBuilder { var builder = baseDao.selectAll() builder.limit(9999999) return builder } // Fun selectAll() /** * 执行查询操作 * * @param builder 查询查询构造器 * @return 查询到的记录 */ open fun execQuery(builder: SQueryBuilder): ArrayList { return baseDao.execQuery(builder) } // Fun execQuery() /** * 执行查询操作 * * @param builder 查询查询构造器 * @return 查询到的记录数 */ open fun execCount(builder: SQueryBuilder): Long { return baseDao.execCount(builder) } // Fun execQuery() //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 回调函数 /** * 创建对象前回调函数 * * @param entity 创建前的回调函数 * @return 返回true,可以创建对象 */ protected open fun onCreateBefore(entity: ENTITY): Boolean { return true } // Fun onCreateBefore() /** * 创建成功后回调函数 * * @param entityList 创建成功对象列表 */ protected open fun onCreateSuccess(entityList: ArrayList) { } // Fun onCreateSuccess() /** * 创建失败回调函数 * * @param entityList 创建失败对象列表 */ protected open fun onCreateFailure(entityList: ArrayList) { } // Fun onCreateFailure() /** * 删除前回调函数 * * @param entity 创建前的回调函数 * @return 返回true,可以删除对象 */ protected open fun onDeleteBefore(entity: ENTITY): Boolean { return true } // Fun onCreateEntity() /** * 删除成功回调函数 * * @param entityList 删除成功对象列表 */ protected open fun onDeleteSuccess(entityList: ArrayList) { } // Fun onDeleteSuccess() /** * 删除失败回调函数 * * @param entityList 删除失败对象列表 */ protected open fun onDeleteFailure(entityList: ArrayList) { } // Fun onDeleteFailure() /** * 更新前回调函数 * * @param entity 创建前的回调函数 */ protected open fun onUpdateBefore(entity: ENTITY): Boolean { return true } // Fun onCreateEntity() /** * 更新成功能回调函数 * * @param entityList 更新成功对象列表 */ protected open fun onUpdateSuccess(entityList: ArrayList) { } // Fun onUpdateSuccess() /** * 更新失败回调函数 * * @param entityList 更新失败对象列表 */ protected open fun onUpdateFailure(entityList: ArrayList) { } // Fun onUpdateFailure() /** * 查询前回调函数 * * @param queryBuilder 查询构造器 */ protected open fun onQueryBefore(queryBuilder: SQueryBuilder) { } // Fun onQueryBefore() /** * 查询成功回调函数 * * @param pageInfo 页面信息 */ protected open fun onQuerySuccess(pageInfo: SPageQueryInfo) { } // Fun onQuerySuccess() /** * 统计个数前回调函数 * * @param queryBuilder 查询构造器 */ protected open fun onCountBefore(queryBuilder: SQueryBuilder) { } // Fun onQueryBefore() /** * 统计个数成功回调函数 * * @param count 统计结果 */ protected open fun onCountSuccess(count: Long) { } // Fun onCountSuccess() //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 级联操作相关 /** * 进行级联查询处理 * * @param entityList 实体列表 * @param cascadeList 级联请求列表 */ fun processCascadeQuery(entityList: ArrayList, cascadeList: ArrayList) { val entityMap = entityListToMap(entityList) for (cascade in cascadeList) { if (cascade.name == null) { continue } // 获得级联相关信息。如果信息不完整,则退出 val cascadeField = entityClass.getAllDeclaredField(cascade.name!!) ?: continue val cascadeQueryAnno = cascadeField.getAnnotation(SCascade::class.java) val cascadeCountAnno = cascadeField.getAnnotation(SCascadeCount::class.java) if (cascadeQueryAnno != null) { cascadeQuery(entityMap, cascadeQueryAnno, cascadeField, cascade) } else if (cascadeCountAnno != null) { cascadeCount(entityMap, cascadeCountAnno, cascadeField, cascade) } } return } // Fun cascadeQuery() /** * 进行级联查询 * * @param entityMap 实体Map * @param cascadeAnno 级联查询注解 * @param cascadeField 级联查询对应的属性 * @param cascade 级联请求 */ private fun cascadeQuery(entityMap: HashMap, cascadeAnno: SCascade, cascadeField: Field, cascade: SCascadeQuery) { val cascadeClass = if (List::class.java.isAssignableFrom(cascadeField.type)) { // 如果是1对多,或多对多。取列表的泛型 (cascadeField.genericType as ParameterizedType).actualTypeArguments[0] as Class<*> } else { // 如果为1对1,直接取对象类型 cascadeField.type } val idList = entityIdList(entityMap) val relationList = baseDao.relationQuery(cascadeAnno.table, cascadeAnno.idColumn, cascadeAnno.childIdColumn, cascadeAnno.self, cascadeAnno.filter, idList) // 如果未取到关联数据,则开始取下一个关联对象 if (relationList.size <= 0) { return } val relationMap = relationListToMap(relationList) ///////////////////////////////// // 开始构造级联查询 val service = SBaseService(cascadeClass) val sqlBuilder = service.select(cascade.filters) sqlBuilder.filter(SFilter.inList(cascadeClass.keyFieldList()[0].name, relationMap.keys.toList())) /** 排序条件 */ if (null != cascade.orders) { sqlBuilder.order(cascade.orders!!) } /** 去重 */ if (null != cascade.distinct && cascade.distinct!!) { sqlBuilder.distinct() } /** 映射标志 */ if (null != cascade.projection) { sqlBuilder.projection(cascade.projection!!) } /** 分组统计 */ if (null != cascade.group && !cascade.group!!.nameList.isNullOrEmpty()) { // 分组属性名列表 sqlBuilder.group(*cascade.group!!.nameList.toArray(emptyArray())) // 是否统计个数 sqlBuilder.count(cascade.group!!.count ?: false) // 求和 if (!cascade.group!!.sumList.isNullOrEmpty()) { sqlBuilder.sum(*cascade.group!!.sumList.toArray(emptyArray())) } // 求平均值 if (!cascade.group!!.avgList.isNullOrEmpty()) { sqlBuilder.avg(*cascade.group!!.avgList.toArray(emptyArray())) } // 取最大值 if (!cascade.group!!.maxList.isNullOrEmpty()) { sqlBuilder.max(*cascade.group!!.maxList.toArray(emptyArray())) } // 取最小值 if (!cascade.group!!.minList.isNullOrEmpty()) { sqlBuilder.min(*cascade.group!!.minList.toArray(emptyArray())) } } val childrenList = sqlBuilder.exec() for (child in childrenList) { val childKey = child::class.java.keyFieldList()[0].name val id2 = child.keyValue(childKey) @Suppress("UNCHECKED_CAST") val id1List = relationMap[id2] as ArrayList? id1List ?: continue for (id1 in id1List) { if (entityMap[id1] != null) { fillCascadeObject(entityMap[id1]!!, child, cascadeField) } } } /** 如果需要进行级联查询 */ if (cascade.cascade != null && cascade.cascade!!.size > 0 && childrenList.size > 0) { @Suppress("UNCHECKED_CAST") service.processCascadeQuery(childrenList as ArrayList, cascade.cascade!!) } return } // Fun cascadeQuery() /** * 进行级联查询 * * @param entityMap 实体Map * @param cascadeAnno 级联查询注解 * @param cascadeField 级联查询对应的属性 * @param cascade 级联请求 */ private fun cascadeCount(entityMap: HashMap, cascadeAnno: SCascadeCount, cascadeField: Field, cascade: SCascadeQuery) { val idList = entityIdList(entityMap) val relationList = baseDao.relationQuery(cascadeAnno.table, cascadeAnno.idColumn, cascadeAnno.childIdColumn, cascadeAnno.self, cascadeAnno.filter, idList) // 如果未取到关联数据,则开始取下一个关联对象 if (relationList.size <= 0) { return } val relationMap = relationListToMap(relationList) ///////////////////////////////// // 开始构造级联查询 val service = SBaseService(cascadeAnno.childClass.java) val sqlBuilder = service.select(cascade.filters) sqlBuilder.filter(SFilter.inList(cascadeAnno.childClass.java.keyFieldList()[0].name, relationMap.keys.toList())) /** 排序条件 */ if (null != cascade.orders) { sqlBuilder.order(cascade.orders!!) } /** 去重 */ if (null != cascade.distinct && cascade.distinct!!) { sqlBuilder.distinct() } /** 映射标志 */ if (null != cascade.projection) { sqlBuilder.projection(cascade.projection!!) } /** 分组统计 */ if (null != cascade.group && !cascade.group!!.nameList.isNullOrEmpty()) { // 分组属性名列表 sqlBuilder.group(*cascade.group!!.nameList.toArray(emptyArray())) // 是否统计个数 sqlBuilder.count(cascade.group!!.count ?: false) // 求和 if (!cascade.group!!.sumList.isNullOrEmpty()) { sqlBuilder.sum(*cascade.group!!.sumList.toArray(emptyArray())) } // 求平均值 if (!cascade.group!!.avgList.isNullOrEmpty()) { sqlBuilder.avg(*cascade.group!!.avgList.toArray(emptyArray())) } // 取最大值 if (!cascade.group!!.maxList.isNullOrEmpty()) { sqlBuilder.max(*cascade.group!!.maxList.toArray(emptyArray())) } // 取最小值 if (!cascade.group!!.minList.isNullOrEmpty()) { sqlBuilder.min(*cascade.group!!.minList.toArray(emptyArray())) } } val childrenList = sqlBuilder.exec() for (child in childrenList) { val childKey = child::class.java.keyFieldList()[0].name val id2 = child.keyValue(childKey) @Suppress("UNCHECKED_CAST") val id1List = relationMap[id2] as ArrayList? id1List ?: continue for (id1 in id1List) { if (entityMap[id1] != null) { fillCascadeCount(entityMap[id1]!!, child, cascadeField) } } } return } // Fun cascadeCount() /** * 为加速填充级联对象,将实体列表转换为map。 * * @param entityList 实体列表 * @return 以Map形式存储的实体 */ private fun entityListToMap(entityList: ArrayList): HashMap { val map = HashMap() val key = entityClass.keyFieldList()[0] for (entity in entityList) { map[entity.keyValue(key.name)!!] = entity } return map } // Fun entityMap() /** * 获得实体的Id列表 * * @param entityMap 实体Map * @return ID列表 */ private fun entityIdList(entityMap: HashMap): ArrayList { val idList = ArrayList() for (entity in entityMap) { val keyField = entity.value.javaClass.keyFieldList()[0] val keyValue = entity.value.keyValue(keyField.name)!! println("keyField=${keyField.toJson()}") println("keyValue=${keyValue.toJson()}") idList.add(keyValue) } return idList } // Fun entityIdList() /** * 将关系列表转换为Map * * @param cascadeList 被转换的列表 * @return 转换后的Map */ private fun relationListToMap(cascadeList: List>): HashMap> { val map = HashMap>() for (item in cascadeList) { item["id2"] ?: continue var list = map[item["id2"]!!] if (list == null) { list = ArrayList() } list.add(item["id1"]!!) map[item["id2"]!!] = list } return map } // Fun cascadeToMap() /** * 填级联对象 * * @param entity 实体 * @param child 填入的对象 * @param field 填入的对象对应的实体类属性 */ private fun fillCascadeObject(entity: Any, child: Any?, field: Field) { // 如果child为空,则返回 child ?: return // 保存访问权限 val accessible = field.isAccessible field.isAccessible = true // 如果field是列表 if (List::class.java.isAssignableFrom(field.type)) { @Suppress("UNCHECKED_CAST") var children = field.get(entity) as ArrayList? if (children == null) { children = ArrayList() } children.add(child) field.set(entity, children) } else { // 如果field是对象 if (field.get(entity) == null) { field.set(entity, child) } } // 恢复访问权限 field.isAccessible = accessible return } // Fun fillCascadeObject() /** * 填级联对象 * * @param entity 实体 * @param child 填入的对象 * @param field 填入的对象对应的实体类属性 */ private fun fillCascadeCount(entity: Any, child: Any?, field: Field) { // 如果child为空,则返回 child ?: return // 保存访问权限 val accessible = field.isAccessible field.isAccessible = true @Suppress("UNCHECKED_CAST") var count = field.get(entity) as? Int if (count == null) { count = 0 } count++ field.set(entity, count) // 恢复访问权限 field.isAccessible = accessible return } // Fun fillCascadeCount() } // Class SBaseService