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.
util.Util.kt Maven / Gradle / Ivy
package util
import database.DBConnection
import database.DB
import java.io.File
import kotlin.reflect.KProperty
import kotlin.reflect.full.declaredMembers
/**
* 根据实体类生成伴生对象代码
*/
inline fun convertClassToObject() {
val clazz = T::class
val name = clazz.simpleName
println("companion object : TableSchema(\"${humpToLine(name!!)}\") {")
clazz.declaredMembers.filterIsInstance>().forEach {
println(" val ${it.name} = column(\"${humpToLine(it.name)}\")")
}
println("}")
}
/**
* mysql和pgsql数据库自动生成实体类
* @receiver DBConnection 数据库查询类
* @param dbName String 数据库名
* @param path String 生成实体类的路径
*/
fun DBConnection.generateEntity(dbName: String, path: String) {
val dir = File(path)
if (!dir.exists()) {
dir.mkdir()
}
val packageName = path.replace(Regex("src/\\w+/\\w+/"), "").replace("/", ".").trim { it == '.' }
when (this.db) {
DB.MYSQL -> generateEntityForMysql(this, dbName, path, packageName)
DB.PGSQL -> generateEntityForPgsql(this, dbName, path, packageName)
// TODO
else -> throw TypeCastException("生成实体类功能暂不支持此类数据库")
}
}
/**
* mysql数据库自动生成实体类
* @param dbConnection DBConnection 数据库查询类
* @param dbName String 数据库名
* @param path String 生成实体类的路径
* @param packageName String 包名
*/
fun generateEntityForMysql(dbConnection: DBConnection, dbName: String, path: String, packageName: String) {
val tables = dbConnection.nativeSelect("SHOW TABLES").queryMap()
if (tables.isEmpty()) {
return
}
val tableNames = tables.map {
val key = it.keys.toList()[0]
it[key].toString()
}
tableNames.forEach {
val columnSql =
"SELECT COLUMN_NAME, DATA_TYPE, EXTRA, COLUMN_KEY FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION ASC"
val columns = dbConnection.nativeSelect(columnSql, dbName, it).queryMap()
val entityCode = StringBuilder()
var haveDate = false
var haveDecimal = false
entityCode.append("data class ${lineToHump(it)}(")
columns.forEachIndexed { index, item ->
val dataType = when (item["DATA_TYPE"].toString().toUpperCase()) {
"VARCHAR", "CHAR", "JSON", "TEXT", "LONGTEXT", "MEDIUMTEXT", "TINYTEXT" -> "String"
"INT", "TINYINT", "SMALLINT", "MEDIUMINT" -> "Int"
"INTEGER", "BIGINT", "ID" -> "Long"
"BIT" -> "Boolean"
"FLOAT" -> "Float"
"DOUBLE" -> "Double"
"DECIMAL", "NUMERIC" -> {
haveDecimal = true
"BigDecimal"
}
"DATE", "TIME", "DATETIME", "TIMESTAMP", "YEAR" -> {
haveDate = true
"Date"
}
else -> "Any"
}
entityCode.append("var ${lineToHump(item["COLUMN_NAME"].toString(), false)}: $dataType? = null")
if (index < columns.size - 1) {
entityCode.append(", ")
}
}
entityCode.append(") {\n")
entityCode.append(" companion object : TableSchema(\"$it\") {\n")
columns.forEach { item ->
entityCode.append(
" val ${
lineToHump(
item["COLUMN_NAME"].toString(),
false
)
} = column(\"${item["COLUMN_NAME"].toString()}\")"
)
if (item["COLUMN_KEY"].toString().toLowerCase() == "pri") {
entityCode.append(".primaryKey()")
}
if (item["EXTRA"].toString().toLowerCase() == "auto_increment") {
entityCode.append(".incr()")
}
entityCode.append("\n")
}
entityCode.append(" }\n")
entityCode.append("}")
val entity = StringBuilder()
entity.append("package $packageName")
entity.append("\n\n")
entity.append("import dsl.TableSchema")
if (haveDate) {
entity.append("\nimport java.util.Date")
}
if (haveDecimal) {
entity.append("\nimport java.math.BigDecimal")
}
entity.append("\n\n")
entity.append(entityCode)
File(path + lineToHump(it) + ".kt").writeText(entity.toString())
}
}
/**
* pgsql数据库自动生成实体类
* @param dbConnection DBConnection 数据库查询类
* @param dbName String 数据库名
* @param path String 生成实体类的路径
* @param packageName String 包名
*/
fun generateEntityForPgsql(dbConnection: DBConnection, dbName: String, path: String, packageName: String) {
val tables = dbConnection.nativeSelect(
"SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tableowner = ?",
dbName
).queryMap()
if (tables.isEmpty()) {
return
}
val tableNames = tables.map { it["tablename"].toString() }
tableNames.forEach {
val columnSql =
"SELECT column_name, udt_name, column_default FROM information_schema.\"columns\" WHERE table_catalog = ? AND table_name = ? ORDER BY ordinal_position ASC"
val columns = dbConnection.nativeSelect(columnSql, dbName, it).queryMap()
val pkColSql = """
SELECT
pg_attribute.attname AS pkname
FROM
pg_constraint
INNER JOIN pg_class ON
pg_constraint.conrelid = pg_class.oid
INNER JOIN pg_attribute ON
pg_attribute.attrelid = pg_class.oid
AND pg_attribute.attnum = pg_constraint.conkey[1]
WHERE
pg_class.relname = ?
AND pg_constraint.contype = 'p'
""".trimIndent()
val pkCols = dbConnection.nativeSelect(pkColSql, it).queryMap().map { pk -> pk["pkname"].toString() }
val entityCode = StringBuilder()
var haveDate = false
var haveDecimal = false
entityCode.append("data class ${lineToHump(it)}(")
columns.forEachIndexed { index, item ->
val dataType = when (item["udt_name"].toString().toUpperCase()) {
"VARCHAR", "CHAR", "JSON", "JSONB", "TEXT" -> "String"
"INT2", "INT4" -> "Int"
"INT8", "BIGINT", "ID" -> "Long"
"BIT", "BOOL" -> "Boolean"
"FLOAT4" -> "Float"
"FLOAT8", "MONEY" -> "Double"
"NUMERIC" -> {
haveDecimal = true
"BigDecimal"
}
"TIME", "TIMESTAMP" -> {
haveDate = true
"Date"
}
else -> "Any"
}
entityCode.append("var ${lineToHump(item["column_name"].toString(), false)}: $dataType? = null")
if (index < columns.size - 1) {
entityCode.append(", ")
}
}
entityCode.append(") {\n")
entityCode.append(" companion object : TableSchema(\"$it\") {\n")
columns.forEach { item ->
entityCode.append(
" val ${
lineToHump(
item["column_name"].toString(),
false
)
} = column(\"${item["column_name"].toString()}\")"
)
if (item["column_name"].toString() in pkCols) {
entityCode.append(".primaryKey()")
}
if (item["column_default"].toString().toLowerCase().contains("nextval")) {
entityCode.append(".incr()")
}
entityCode.append("\n")
}
entityCode.append(" }\n")
entityCode.append("}")
val entity = StringBuilder()
entity.append("package $packageName")
entity.append("\n\n")
entity.append("import dsl.TableSchema")
if (haveDate) {
entity.append("\nimport java.util.Date")
}
if (haveDecimal) {
entity.append("\nimport java.math.BigDecimal")
}
entity.append("\n\n")
entity.append(entityCode)
File(path + lineToHump(it) + ".kt").writeText(entity.toString())
}
}
/**
* 驼峰风格转下划线风格
* @param string String 待转换字符串
* @return String 转换后的字符串
*/
fun humpToLine(string: String): String {
val builder = StringBuilder()
string.forEachIndexed { index, it ->
if (it.isUpperCase() && index > 0) {
builder.append("_")
}
builder.append(it.toLowerCase())
}
return builder.toString()
}
/**
* 下划线风格转驼峰风格
* @param string String 待转换字符串
* @return String 转换后的字符串
*/
fun lineToHump(string: String, firstUpper: Boolean = true): String {
val builder = StringBuilder()
var upperCase = false
for (i in string.indices) {
if (string[i] == '_') {
upperCase = true
continue
}
if (upperCase || i == 0 && firstUpper) {
builder.append(string[i].toUpperCase())
upperCase = false
} else {
builder.append(string[i])
}
}
return builder.toString()
}