vertx-pj/vertx-demo/src/main/kotlin/app/util/SqlAnnotationMapper.kt
2025-03-19 15:09:09 +08:00

187 lines
6.6 KiB
Kotlin

package app.util
import kotlin.reflect.KClass
/**
* SQL注解映射中间类
* 用于记录从哪些注解获取SQL生成所需的信息
*/
class SqlAnnotationMapper {
/**
* 表名映射信息
*/
var tableName: AnnotationMapping? = null
/**
* 列名映射信息列表
*/
var columnMappings: MutableList<ColumnMapping> = mutableListOf()
/**
* 主键映射信息
*/
var primaryKeyMapping: AnnotationMapping? = null
/**
* 其他自定义映射
*/
var customMappings: MutableMap<String, AnnotationMapping> = mutableMapOf()
/**
* 添加一个列映射
*/
fun addColumnMapping(columnMapping: ColumnMapping) {
columnMappings.add(columnMapping)
}
/**
* 添加一个自定义映射
*/
fun addCustomMapping(key: String, mapping: AnnotationMapping) {
customMappings[key] = mapping
}
}
/**
* 注解映射类
* 记录从哪个注解的哪个属性获取信息
*/
data class AnnotationMapping(
/** 注解类 */
val annotationClass: KClass<out Annotation>,
/** 注解属性名 */
val propertyName: String = "value"
)
/**
* 列映射信息
*/
data class ColumnMapping(
/** 字段名称映射 */
val nameMapping: AnnotationMapping,
/** 字段类型映射,可选 */
val typeMapping: AnnotationMapping? = null,
/** 是否可为空映射,可选 */
val nullableMapping: AnnotationMapping? = null,
/** 默认值映射,可选 */
val defaultValueMapping: AnnotationMapping? = null
)
/**
* SQL注解映射生成器
* 用于生成和使用SQL注解映射中间类
*/
class SqlAnnotationMapperGenerator {
companion object {
/**
* 从实体类获取SQL信息
* @param entityClass 实体类
* @param mapper 注解映射中间类
* @return SQL信息
*/
fun extractSqlInfo(entityClass: KClass<*>, mapper: SqlAnnotationMapper): SqlInfo {
val sqlInfo = SqlInfo()
// 获取表名
mapper.tableName?.let { tableNameMapping ->
val annotation = entityClass.annotations.find { it.annotationClass == tableNameMapping.annotationClass.java }
annotation?.let {
val method = it.javaClass.getMethod(tableNameMapping.propertyName)
sqlInfo.tableName = method.invoke(it) as String
}
}
// 获取实体类的所有字段
entityClass.java.declaredFields.forEach { field ->
// 获取列信息
val columnInfo = ColumnInfo()
// 处理每个列映射
mapper.columnMappings.forEach { columnMapping ->
val nameAnnotation = field.annotations.find {
it.annotationClass.java == columnMapping.nameMapping.annotationClass.java
}
if (nameAnnotation != null) {
val nameMethod = nameAnnotation.javaClass.getMethod(columnMapping.nameMapping.propertyName)
columnInfo.name = nameMethod.invoke(nameAnnotation) as String? ?: field.name
// 处理类型映射
columnMapping.typeMapping?.let { typeMapping ->
val typeAnnotation = field.annotations.find {
it.annotationClass.java == typeMapping.annotationClass.java
}
if (typeAnnotation != null) {
val typeMethod = typeAnnotation.javaClass.getMethod(typeMapping.propertyName)
columnInfo.type = typeMethod.invoke(typeAnnotation) as String
}
}
// 处理可空映射
columnMapping.nullableMapping?.let { nullableMapping ->
val nullableAnnotation = field.annotations.find {
it.annotationClass.java == nullableMapping.annotationClass.java
}
if (nullableAnnotation != null) {
val nullableMethod = nullableAnnotation.javaClass.getMethod(nullableMapping.propertyName)
columnInfo.nullable = nullableMethod.invoke(nullableAnnotation) as Boolean
}
}
// 处理默认值映射
columnMapping.defaultValueMapping?.let { defaultValueMapping ->
val defaultValueAnnotation = field.annotations.find {
it.annotationClass.java == defaultValueMapping.annotationClass.java
}
if (defaultValueAnnotation != null) {
val defaultValueMethod = defaultValueAnnotation.javaClass.getMethod(defaultValueMapping.propertyName)
columnInfo.defaultValue = defaultValueMethod.invoke(defaultValueAnnotation) as String
}
}
sqlInfo.columns.add(columnInfo)
}
}
// 处理主键
mapper.primaryKeyMapping?.let { pkMapping ->
val pkAnnotation = field.annotations.find {
it.annotationClass.java == pkMapping.annotationClass.java
}
if (pkAnnotation != null) {
val pkMethod = pkAnnotation.javaClass.getMethod(pkMapping.propertyName)
val isPk = pkMethod.invoke(pkAnnotation)
if (isPk is Boolean && isPk) {
columnInfo.isPrimaryKey = true
sqlInfo.primaryKeys.add(columnInfo.name)
}
}
}
}
return sqlInfo
}
}
}
/**
* SQL信息类
* 存储从实体类中提取的SQL相关信息
*/
data class SqlInfo(
var tableName: String = "",
val columns: MutableList<ColumnInfo> = mutableListOf(),
val primaryKeys: MutableList<String> = mutableListOf()
)
/**
* 列信息类
*/
data class ColumnInfo(
var name: String = "",
var type: String = "",
var nullable: Boolean = true,
var defaultValue: String = "",
var isPrimaryKey: Boolean = false
)