SAbstractDao.kt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * *********************************************************************************************************************
  3. *
  4. * !!
  5. * .F88X
  6. * X8888Y
  7. * .}888888N;
  8. * i888888N; .:! .I$WI:
  9. * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
  10. * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I
  11. * +888888N; .8888888Y "&&8Y.}8,
  12. * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i
  13. * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$*
  14. * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I
  15. * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
  16. * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
  17. * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I
  18. * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/
  19. * .:R888888I
  20. * .&888888I Copyright (c) 2009-2020. 博锐尚格科技股份有限公司
  21. * ~8888'
  22. * .!88~ All rights reserved.
  23. *
  24. * *********************************************************************************************************************
  25. */
  26. package com.persagy.database
  27. import com.persagy.base.exceptions.SFieldNotFoundException
  28. import com.persagy.base.extensions.toJson
  29. import com.persagy.base.extensions.*
  30. import com.persagy.database.extensions.filterListByKeys
  31. import com.persagy.database.parser.SSyntaxParser
  32. import java.io.ByteArrayInputStream
  33. import java.lang.reflect.Field
  34. import java.lang.reflect.ParameterizedType
  35. import javax.persistence.Column
  36. import javax.persistence.Table
  37. /**
  38. * 数据访问对象基类
  39. *
  40. * @author 庞利祥 <sybotan@126.com>
  41. */
  42. abstract class SAbstractDao<ENTITY: Any>(entityClazz: Class<ENTITY>) {
  43. companion object {
  44. /**
  45. * 获得表名,取实体类@Table注解的名称,如果没有注解,则取实体类类名。
  46. *
  47. * @param clz mapper类类型
  48. * @param keyEsc 转义符,用于避免与数据库关键词冲突
  49. * @return 表名
  50. */
  51. fun tableName(clz: Class<*>, keyEsc: String = ""): String {
  52. val tableAnno = clz.getAnnotation(javax.persistence.Table::class.java)
  53. // 如果有@Table注解,则取注解的表名;否则使用类名做为表名
  54. val tableName = tableAnno?.name ?: clz.simpleName
  55. val name = tableName.replace(".", "$keyEsc.$keyEsc")
  56. return "$keyEsc$name$keyEsc"
  57. } // Fun tableName()
  58. /**
  59. * 获得实体类属性对应的数据表字段名
  60. *
  61. * @param clazz 实体类类型
  62. * @param name 属性名
  63. * @return 对应的数据表字段名
  64. */
  65. fun columnName(clazz: Class<*>, name: String, keyEsc: String = ""): String {
  66. try {
  67. val field = clazz.getAllDeclaredField(name, true, true)
  68. val colName = field!!.getAnnotation(Column::class.java).name
  69. return "$keyEsc$colName$keyEsc"
  70. } catch (e: Exception) {
  71. throw SFieldNotFoundException(name)
  72. }
  73. } // Fun columnName()
  74. /**
  75. * 获得实体类属性名
  76. *
  77. * @param clazz 实体类类型
  78. * @param name 名称
  79. * @return 实体类属性名
  80. */
  81. fun propertyName(clazz: Class<*>, name: String): String {
  82. try {
  83. val field = clazz.getAllDeclaredField(name, true, true)
  84. return field!!.name
  85. } catch (e: Exception) {
  86. throw SFieldNotFoundException(name)
  87. }
  88. } // Fun propertyName()
  89. } // companion object
  90. /** 实体类类型 */
  91. val entityClass = entityClazz
  92. /**
  93. * 在数据库中插入实体
  94. *
  95. * @param entity 插入数据库的实体
  96. * @return 插入是否成功
  97. */
  98. abstract fun insert(entity: ENTITY): Boolean
  99. /**
  100. * 在数据库中插入/更新实体
  101. *
  102. * @param entity 插入/更新数据库的实体
  103. * @return 插入是否成功
  104. */
  105. abstract fun replace(entity: ENTITY): Boolean
  106. /**
  107. * 根据条件删除
  108. *
  109. * @param args 删除条件
  110. * @return 删除是否成功
  111. */
  112. abstract fun delete(args: List<SFilter>): Boolean
  113. /**
  114. * 删除所有记录
  115. *
  116. * @return 删除是否成功
  117. */
  118. abstract fun deleteAll(): Boolean
  119. /**
  120. * 根据条件更新
  121. *
  122. * @param entity 更新的值
  123. * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段
  124. * @param args 更新条件
  125. * @return 更新是否成功
  126. */
  127. abstract fun update(entity: ENTITY, projection: ArrayList<String>? = null, args: List<SFilter>? = null): Boolean
  128. /**
  129. * 根据条件查询记录
  130. *
  131. * @param args 查询条件
  132. * @return 查询构造器
  133. */
  134. abstract fun select(args: List<SFilter>): SQueryBuilder<ENTITY>
  135. /**
  136. * 根据条件查询所有记录
  137. *
  138. * @return 查找构建器
  139. */
  140. abstract fun selectAll(): SQueryBuilder<ENTITY>
  141. /**
  142. * 执行查询操作
  143. *
  144. * @param builder 查询查询构造器
  145. * @return 查询到的记录
  146. */
  147. abstract fun execQuery(builder: SQueryBuilder<ENTITY>): ArrayList<ENTITY>
  148. /**
  149. * 执行统计个数操作
  150. *
  151. * @param builder 查询查询构造器
  152. * @return 查询到的记录数
  153. */
  154. abstract fun execCount(builder: SQueryBuilder<ENTITY>): Long
  155. /**
  156. * 执行分页查询操作
  157. *
  158. * @param builder 查询查询构造器
  159. * @param pageNumber 第几页
  160. * @param pageSize 每页记录数
  161. * @return 查询到的记录
  162. */
  163. fun pageQuery(builder: SQueryBuilder<ENTITY>, pageNumber: Int, pageSize: Int): SPageQueryInfo<ENTITY> {
  164. val pageInfo = SPageQueryInfo<ENTITY>(pageNumber, pageSize)
  165. builder.limit((pageNumber - 1) * pageSize, pageSize)
  166. pageInfo.total = execCount(builder)
  167. pageInfo.content = execQuery(builder)
  168. return pageInfo
  169. } // Fun pageQuery()
  170. /**
  171. * 删除实体
  172. *
  173. * @param entity 被删除的实体
  174. * @return 删除是否成功
  175. */
  176. open fun delete(entity: ENTITY): Boolean {
  177. return delete(entity.filterListByKeys())
  178. } // Fun delete()
  179. /**
  180. * 根据条件删除
  181. *
  182. * @param args 删除条件
  183. * @return 删除是否成功
  184. */
  185. open fun delete(vararg args: Pair<String, Any>): Boolean {
  186. val filterList = ArrayList<SFilter>()
  187. for (arg in args) { // 同时取列表元素与下标
  188. filterList.add(SFilter.eq(arg.first, arg.second))
  189. }
  190. return delete(filterList)
  191. } // Fun delete()
  192. /**
  193. * 根据条件删除
  194. *
  195. * @param args 删除条件
  196. * @return 删除是否成功
  197. */
  198. open fun delete(vararg args: SFilter): Boolean {
  199. return delete(args.toList())
  200. } // Fun delete()
  201. /**
  202. * 根据条件删除
  203. *
  204. * @param query 删除条件
  205. * @return 删除是否成功
  206. */
  207. open fun delete(query: String): Boolean {
  208. val parser = SSyntaxParser(ByteArrayInputStream(query.toByteArray()))
  209. return delete(parser.parserFilters())
  210. } // Fun delete()
  211. /**
  212. * 更新实体
  213. *
  214. * @param entity 更新实体
  215. * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段
  216. * @return 更新是否成功
  217. */
  218. open fun update(entity: ENTITY, projection: ArrayList<String>? = null): Boolean {
  219. return update(entity, projection, entity.filterListByKeys())
  220. } // Fun update()
  221. /**
  222. * 根据条件更新
  223. *
  224. * @param entity 更新实体内容
  225. * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段
  226. * @param args 更新条件
  227. * @return 更新是否成功
  228. */
  229. open fun update(entity: ENTITY, projection: ArrayList<String>? = null, vararg args: Pair<String, Any>): Boolean {
  230. val filterList = ArrayList<SFilter>()
  231. for (arg in args) {
  232. filterList.add(SFilter.eq(arg.first, arg.second))
  233. }
  234. return update(entity, projection, filterList)
  235. } // Fun update()
  236. /**
  237. * 根据条件更新
  238. *
  239. * @param entity 更新实体内容
  240. * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段
  241. * @param args 更新条件
  242. * @return 更新是否成功
  243. */
  244. open fun update(entity: ENTITY, projection: ArrayList<String>? = null, vararg args: SFilter): Boolean {
  245. return update(entity, projection, args.toList())
  246. } // Fun update()
  247. /**
  248. * 根据条件更新
  249. *
  250. * @param entity 更新实体内容
  251. * @param projection 将被更新的字段列表(以逗号分隔),为空表示更新所有非空字段
  252. * @param query 更新条件
  253. * @return 更新是否成功
  254. */
  255. open fun update(entity: ENTITY, projection: ArrayList<String>? = null, query: String): Boolean {
  256. val parser = SSyntaxParser(ByteArrayInputStream(query.toByteArray()))
  257. return update(entity, projection, parser.parserFilters())
  258. } // Fun update()
  259. /**
  260. * 根据条件查询一条记录
  261. *
  262. * @param args 查询条件
  263. * @return 查询构造器
  264. */
  265. open fun select(vararg args: Pair<String, Any>): SQueryBuilder<ENTITY> {
  266. val filterList = ArrayList<SFilter>()
  267. for (arg in args) { // 同时取列表元素与下标
  268. filterList.add(SFilter.eq(arg.first, arg.second))
  269. }
  270. return select(filterList)
  271. } // Fun select()
  272. /**
  273. * 根据条件查询记录
  274. *
  275. * @param args 查询条件
  276. * @return 查询构造器
  277. */
  278. open fun select(vararg args: SFilter): SQueryBuilder<ENTITY> {
  279. return select(args.toList())
  280. } // Fun select()
  281. /**
  282. * 根据条件查询记录
  283. *
  284. * @param query 查询条件
  285. * @return 查询构造器
  286. */
  287. open fun select(query: String?): SQueryBuilder<ENTITY> {
  288. // 如果查询条件为空,则执行查询所有
  289. if (query == null) {
  290. return selectAll()
  291. }
  292. val queryParser = SSyntaxParser(ByteArrayInputStream(query.toByteArray()))
  293. val filters = queryParser.parserFilters()
  294. return select(filters)
  295. } // Fun select()
  296. /**
  297. * 获得表名
  298. */
  299. fun tableName(): String {
  300. val clz = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<*>
  301. if (clz.isAnnotationPresent(Table::class.java)) {
  302. val anno = clz.getAnnotation(Table::class.java)
  303. return anno!!.name
  304. }
  305. return clz.simpleName
  306. } // Fun tableName()
  307. /**
  308. * 实体的field转换为Pair结构
  309. *
  310. * @param entity 要转换的实体对象
  311. * @param field 实体对应的域
  312. */
  313. protected fun fieldToPair(entity: ENTITY, field: Field): Pair<String, Any?> {
  314. // 获得field对应的数据库表字段名
  315. val anno = field.getAnnotation(Column::class.java)
  316. return Pair<String, Any?>(anno.name, when (field.type.simpleName) {
  317. "byte", "Byte" -> field.getByte(entity)
  318. "double", "Double" -> field.getDouble(entity)
  319. "float", "Float" -> field.getFloat(entity)
  320. "int", "Integer", "Int" -> field.getInt(entity)
  321. "long", "Long" -> field.getLong(entity)
  322. "short", "Short" -> field.getShort(entity)
  323. "Boolean" -> field.getBoolean(entity)
  324. "String" -> field.get(entity)
  325. else ->{
  326. if (entity == null){
  327. null
  328. }else{
  329. if (field.get(entity) == null){
  330. null
  331. }else{
  332. field.get(entity).toJson()
  333. }
  334. }
  335. }
  336. })
  337. } // Fun fieldToPair()
  338. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  339. // 级联操作相关
  340. /**
  341. * 查询级联关系
  342. *
  343. * @param table 表名
  344. * @param id1 对象表ID字段名
  345. * @param id2 级联对象ID字段名
  346. * @param self 自身级联
  347. * @param filter 附加过滤条件
  348. * @param idList 对象ID列表
  349. * @return 关系列表
  350. */
  351. abstract fun relationQuery(table: String, id1: String, id2: String, self: Boolean, filter: String, idList: ArrayList<Any>): ArrayList<HashMap<String, Any>>
  352. } // Class SAbstractDao