Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
query.select.SelectQueryImpl.kt Maven / Gradle / Ivy
package query.select
import ast.statement.select.SqlUnionType
import database.DBConnection
import dsl.QuerySub
import dsl.QueryTableColumn
import util.humpToLine
import java.math.BigDecimal
import java.sql.Connection
import java.util.*
import kotlin.reflect.KProperty
import kotlin.reflect.full.companionObjectInstance
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.declaredMembers
import kotlin.reflect.jvm.javaField
/**
* 查询dsl基类
*/
abstract class SelectQueryImpl : SelectQuery {
/**
* 生成union查询
* 例如:(Select() from Table1) union (Select() from Table2)
* @param select SelectQuery union右侧的查询dsl
* @return UnionSelect union查询dsl
*/
override infix fun union(select: SelectQuery): UnionSelect {
return UnionSelect(this, SqlUnionType.UNION, select, this.getDbType())
}
/**
* 生成union all查询
* 例如:(Select() from Table1) unionAll (Select() from Table2)
* @param select SelectQuery union右侧的查询dsl
* @return UnionSelect union查询dsl
*/
override infix fun unionAll(select: SelectQuery): UnionSelect {
return UnionSelect(this, SqlUnionType.UNION_ALL, select, this.getDbType())
}
/**
* 生成except查询
* 例如:(Select() from Table1) except (Select() from Table2)
* @param select SelectQuery union右侧的查询dsl
* @return UnionSelect union查询dsl
*/
override infix fun except(select: SelectQuery): UnionSelect {
return UnionSelect(this, SqlUnionType.EXCEPT, select, this.getDbType())
}
/**
* 生成intersect查询
* 例如:(Select() from Table1) interSect (Select() from Table2)
* @param select SelectQuery union右侧的查询dsl
* @return UnionSelect union查询dsl
*/
override infix fun interSect(select: SelectQuery): UnionSelect {
return UnionSelect(this, SqlUnionType.INTERSECT, select, this.getDbType())
}
/**
* 调用jdbc查询sql并返回结果
* @param sql String 查询sql语句
* @param isTransaction Boolean 是否是事务
* @param conn Connection 数据库连接
* @param dbConnection DBConnection? 基础查询类
* @return List> 返回查询结果
*/
fun query(
sql: String,
isTransaction: Boolean,
conn: Connection,
dbConnection: DBConnection?
): List> {
return if (isTransaction) {
database.query(conn, sql)
} else {
val connection = if (conn.isClosed) {
dbConnection?.getConnection()
} else {
conn
}
val tempResult = database.query(connection!!, sql)
connection.close()
tempResult
}
}
/**
* 调用jdbc查询sql并返回条数
* @param sql String 查询sql语句
* @param isTransaction Boolean 是否是事务
* @param conn Connection 数据库连接
* @param dbConnection DBConnection? 基础查询类
* @return Long 返回条数
*/
fun queryCount(
sql: String,
isTransaction: Boolean,
conn: Connection,
dbConnection: DBConnection?
): Long {
val result = if (isTransaction) {
database.queryCount(conn, sql)
} else {
val connection = if (conn.isClosed) {
dbConnection?.getConnection()
} else {
conn
}
val tempResult = database.queryCount(connection!!, sql)
connection.close()
tempResult
}
return result.toLong()
}
/**
* 将数据绑定到实体类中
* @param clazz Class 实体类的java class
* @param result List> 数据库查询结果集
* @return List 绑定结果集
*/
@Suppress("UNCHECKED_CAST")
fun bind(clazz: Class, result: List>): List {
when (clazz) {
Int::class.java, Long::class.java, Float::class.java, Double::class.java, String::class.java, Date::class.java, BigDecimal::class.java -> {
return result.map {
val keys = it.keys.toList()
val key = keys[0]
it[key] as T
}
}
Pair::class.java -> {
return result.map {
val keys = it.keys.toList()
(it[keys[0]] to it[keys[1]]) as T
}
}
Triple::class.java -> {
return result.map {
val keys = it.keys.toList()
Triple(it[keys[0]], it[keys[1]], it[keys[2]]) as T
}
}
}
val companion = clazz.kotlin.companionObjectInstance ?: throw Exception("实体类需要添加伴生对象")
val companionClass = companion::class
val columns = companionClass.declaredMemberProperties
.map { it.getter.call(companion) to it.name }
.filter { it.first is QueryTableColumn }
.map { (it.first as QueryTableColumn).column to it.second }
.toMap()
return result.map {
val row = clazz.newInstance()
columns.forEach { column ->
val fieldName = column.value
val field = (clazz.kotlin.declaredMembers.find { it.name == fieldName } as KProperty).javaField
field?.isAccessible = true
field?.set(row, it[column.key])
}
row
}
}
/**
* 将数据绑定到实体类中
* @param result List> 数据库查询结果集
* @return List 绑定结果集
*/
inline fun bind(result: List>): List {
when (T::class) {
Int::class, Long::class, Float::class, Double::class, String::class, Date::class, BigDecimal::class -> {
return result.map {
val keys = it.keys.toList()
val key = keys[0]
it[key] as T
}
}
Pair::class -> {
return result.map {
val keys = it.keys.toList()
(it[keys[0]] to it[keys[1]]) as T
}
}
Triple::class -> {
return result.map {
val keys = it.keys.toList()
Triple(it[keys[0]], it[keys[1]], it[keys[2]]) as T
}
}
}
val companion = T::class.companionObjectInstance ?: throw Exception("实体类需要添加伴生对象")
val companionClass = companion::class
val columns = companionClass.declaredMemberProperties
.map { it.getter.call(companion) to it.name }
.filter { it.first is QueryTableColumn }
.map { (it.first as QueryTableColumn).column to it.second }
.toMap()
return result.map {
val rowClass = T::class
val row = rowClass.java.newInstance()
columns.forEach { column ->
val fieldName = column.value
val field = (rowClass.declaredMembers.find { it.name == fieldName } as KProperty).javaField
field?.isAccessible = true
field?.set(row, it[column.key])
}
row
}
}
/**
* 将数据绑定到匿名对象中
* @param obj Any 匿名对象
* @param result List> 数据库查询结果集
* @return List 绑定结果集
*/
fun bindAnonymousObjects(obj: T, result: List>): List {
val clazz = obj::class
val properties = clazz.declaredMemberProperties
return result.map {
val constructor = clazz.java.getDeclaredConstructor()
constructor.isAccessible = true
val row = constructor.newInstance()
properties.forEach { property ->
if (it.containsKey(humpToLine(property.name))) {
val field = property.javaField
field?.isAccessible = true
field?.set(row, it[humpToLine(property.name)])
}
}
row
}
}
/**
* 将查询结果集作为Map列表返回
* @return List> 返回结果
*/
fun queryMap(): List> {
return query(sql(), isTransaction, conn!!, dbConnection)
}
/**
* 将查询结果集作为实体列表返回
* @param clazz Class 实体类的java class
* @return List 实体列表
*/
fun query(clazz: Class): List {
val list = query(this.sql(), isTransaction, conn!!, dbConnection)
return bind(clazz, list)
}
/**
* 将查询结果集作为实体列表返回
* @return List 实体列表
*/
inline fun query(): List {
val list = query(this.sql(), isTransaction, conn!!, dbConnection)
return bind(list)
}
/**
* 将查询结果集作为匿名对象列表返回
* @param obj T 匿名对象
* @return List 对象列表
*/
fun queryAnonymousObjects(obj: T): List {
val list = query(this.sql(), isTransaction, conn!!, dbConnection)
return bindAnonymousObjects(obj, list)
}
/**
* 获取条数
* @return Long 条数
*/
open fun fetchCount(): Long {
return queryCount(sql(), isTransaction, conn!!, dbConnection)
}
/**
* 结果是否存在
* @return Boolean
*/
open fun exist(): Boolean {
return fetchCount() > 0
}
/**
* @return String
*/
override fun toString(): String {
return sql()
}
/**
* 将查询dsl转换为表达式类型,以作为子查询带入其他外层查询dsl
* @return QuerySub 查询dsl用的子查询表达式
*/
override fun toExpr(): QuerySub {
return QuerySub(this)
}
}