抽象思维实践——ddl2plantuml 开发记录

本贴最后更新于 1985 天前,其中的信息可能已经时异事殊

项目源码地址: github

背景

利用 plantuml 绘制架构评审图时,发现数据库 ER 图手写字段信息成本太大,想要一个把表结构转换为 plantuml 格式的工具。
搜索了一番,没有发现支持工具,所以准备手撸一个,并记录下设计及编码实现的过程。

需求

一句话需求: 读取数据库结构,转换为 plantuml 格式的 ER 图。

设计

根据需求抽象出下列概念

基础元素(一个输入一个输出)

  1. ER -> plantuml 格式 er
  2. db_schema -> 数据库结构,ddl 语句是其中一种实现形式

扩展概念

  1. table -> 表结构信息
  2. template -> 模板,定义 er 图输出格式

操作行为

  1. reader -> 读取数据库结构,识别 table
  2. parser -> 根据 tabletemplate 转换为 ER
  3. writer -> 输出 ER 图文件

整体交互

design

选型

都是基本的文件及 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 文件。

result

  • PlantUML
    4 引用 • 6 回帖 • 1 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    184 引用 • 1020 回帖
2 操作
crick77 在 2019-12-08 23:52:59 置顶了该帖
crick77 在 2019-12-08 23:52:47 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...