项目源码地址: github
背景
利用 plantuml
绘制架构评审图时,发现数据库 ER 图手写字段信息成本太大,想要一个把表结构转换为 plantuml
格式的工具。
搜索了一番,没有发现支持工具,所以准备手撸一个,并记录下设计及编码实现的过程。
需求
一句话需求: 读取数据库结构,转换为 plantuml 格式的 ER 图。
设计
根据需求抽象出下列概念
基础元素(一个输入一个输出)
ER
->plantuml
格式er
图db_schema
-> 数据库结构,ddl 语句是其中一种实现形式
扩展概念
table
-> 表结构信息template
-> 模板,定义er
图输出格式
操作行为
reader
-> 读取数据库结构,识别table
parser
-> 根据table
和template
转换为ER
图writer
-> 输出ER
图文件
整体交互
选型
都是基本的文件及 String 操作,通过 druid 进行 sql 解析
编码实现
Reader
读取 ddl.sql 文件,解析成 table
interface Reader {
fun read(dbType: String? = DEFAULT_DB_TYPE): Iterable<Table>
fun extract(dbType: String, sql: String): Table {
...
}
}
class FileReader(private val path: String) : Reader {
override fun read(dbType: String?): Iterable<Table> {
return Files.readAllLines(Paths.get(path))
.filter { !it.startsWith("#") }
.joinToString("")
.split(";")
.filter { it.isNotBlank() }
.map { extract(dbType?: DEFAULT_DB_TYPE, it) }
.toList()
}
}
Writer
template
通过 resource 文件管理,接收 table
输出 plantuml 格式 ER
图
interface Writer {
fun write(tables: Iterable<Table>)
fun parse(tables: Iterable<Table>): String {
val template = Thread.currentThread().contextClassLoader.getResource("dot.template")!!.readText()
val content = tables.joinToString("") { table ->
val columns = table.columnList.joinToString("\n") { "${it.notNullNameWrapper()} ${it.type} ${it.defaultValue} ${it.comment}" }
"Table(${table.name}, \"${table.name}\\n(${table.comment})\"){ \n $columns + \n } \n"
}
return template.replace("__content__", content)
}
private fun Column.notNullNameWrapper(): String {
return if (this.notNull) {
"not_null(${this.name})"
} else {
this.name
}
}
}
class FileWriter(private val path: String) : Writer {
override fun write(tables: Iterable<Table>) {
Files.write(Paths.get(path), parse(tables).toByteArray())
}
}
Main
fun main(args: Array<String>) {
val inPath = args[0]
val outPath = args[1]
val dbType = args.getOrNull(2)
FileReader(inPath).read(dbType)
.apply { FileWriter(outPath).write(this) }
}
效果
java -jar ddl2plantuml.jar ddl.sql er.puml
程序会读取当前目录下的 ddl.sql 文件,并转换生成 er.puml 文件。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于