groovy自定义输出XML文件零基础学习&Generate POJOs.groovy:MultipleCompilationErrorsException解决&groovy注释中文乱码问题解决

前言

使用idea2021 导出数据库库表结构报错

Generate 2POJOs.groovy: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
			Script7.groovy: 99: unexpected token: } @ line 99, column 1.
			}
			^
			1 error
			at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:311)
			at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:151)
			at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:121)
			at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:133)
			at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:325)
			at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:224)
			at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:192)
			at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:226)
			at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:201)
			at org.codehaus.groovy.control.Compi... (show balloon)

解决方案:将原来的脚本删除,而后新建一个脚本,内容为:
参考文章:idea2022自动生成pojo报错解决方案

import com.intellij.database.model.DasTable
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */

packageName = "com.sample;"
typeMapping = [
        (~/(?i)int/)                      : "long",
        (~/(?i)float|double|decimal|real/): "double",
        (~/(?i)datetime|timestamp/)       : "java.sql.Timestamp",
        (~/(?i)date/)                     : "java.sql.Date",
        (~/(?i)time/)                     : "java.sql.Time",
        (~/(?i)/)                         : "String"
]

FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    SELECTION.filter { it instanceof DasTable }.each { generate(it, dir) }
}

def generate(table, dir) {
    def className = javaName(table.getName(), true)
    def fields = calcFields(table)
    new File(dir, className + ".java").withPrintWriter { out -> generate(out, className, fields) }
}

def generate(out, className, fields) {
    out.println "package $packageName"
    out.println ""
    out.println ""
    out.println "public class $className {"
    out.println ""
    fields.each() {
        if (it.annos != "") out.println "  ${it.annos}"
        out.println "  private ${it.type} ${it.name};"
    }
    out.println ""
    fields.each() {
        out.println ""
        out.println "  public ${it.type} get${it.name.capitalize()}() {"
        out.println "    return ${it.name};"
        out.println "  }"
        out.println ""
        out.println "  public void set${it.name.capitalize()}(${it.type} ${it.name}) {"
        out.println "    this.${it.name} = ${it.name};"
        out.println "  }"
        out.println ""
    }
    out.println "}"
}

def calcFields(table) {
    DasUtil.getColumns(table).reduce([]) { fields, col ->
        def spec = Case.LOWER.apply(col.getDataType().getSpecification())
        def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
        fields += [[
                           name : javaName(col.getName(), false),
                           type : typeStr,
                           annos: ""]]
    }
}

def javaName(str, capitalize) {
    def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
            .collect { Case.LOWER.apply(it).capitalize() }
            .join("")
            .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
    capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

处理中文乱码

最后输出文件的时候 任选一种方式即可解决中文注释乱码问题

 def generate(table, dir) {
    def className = javaName(table.getName(), true)
    def fields = calcFields(table)
    //设置输出格式 防止中文乱码1
    //PrintWriter output = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(dir, className + ".xml")), "utf-8"))
    //output.withPrintWriter { out -> generate(out, className, fields,table) }
    //处理乱码2
    new File(dir, className + ".xml").withPrintWriter("utf-8") { out -> generate(out, className, fields,table.getName()) }
}

参考文章1:groovy脚本编写, 处理中文乱码, 结合lombok+fastjson, 输出数据库生成实体类
参考文章2:IDEA的DATABASE自定义生成POJO、MAPPER、DAO(groovy)

groovy使用

连接好数据库后,直接单击右键打开,以idea2021.2举例子
在这里插入图片描述

image
Mac idea 2025.2
直接复制一个清空内容,粘贴需要的即可,创建好后,可以在单击右键直接显示,直接执行
image

自定义输出XML文件

先教会大家格式,看你想输出什么样的,觉得麻烦可以直接网上下一个,我是想输出成自定义的所以学习写了下

import com.intellij.database.model.DasTable
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

//自定义包路径 可以导出后手动拖拽到指定项目 自动改变
packageName = "com.sample."
//数据库类型转换枚举 可新增 一般够用
typeMapping = [
        (~/(?i)int/)                      : "long",
        (~/(?i)float|double|decimal|real/): "double",
        (~/(?i)datetime|timestamp/)       : "java.sql.Timestamp",
        (~/(?i)date/)                     : "java.sql.Date",
        (~/(?i)time/)                     : "java.sql.Time",
        (~/(?i)/)                         : "String"
]
//弹框
FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    SELECTION.filter { it instanceof DasTable }.each { generate(it, dir) }
}
//输出
def generate(table, dir) {
    def className = javaName(table.getName(), true)
    def fields = calcFields(table)
    //处理乱码
    new File(dir, className + ".xml").withPrintWriter("utf-8") { out -> generate(out, className, fields,table.getName()) }
}
/**
 * 拼接结果 以XML举例
 * @param out 输出
 * @param className 类名
 * @param fields 字段集合
 * @param tableName 数据库名
 * @return
 */
def generate(out, className, fields,tableName) {
    out.println "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
            "<!DOCTYPE hibernate-mapping PUBLIC \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
            "        \"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd\">"
    out.println "<hibernate-mapping>"
    out.println "<class name=\"$packageName$className\" table=\"$tableName\" >"
    out.println ""
    fields.each() {
        out.println ""
        //组装参数
        out.println "<property name=\"${it.name}\" type=\"${it.type}\">"
        out.println " <column name=\"${it.tName}\" length=\"${it.length}\" >"
        out.println "   <comment>${it.comment}</comment>\n</column>"
        out.println "</property>"
    }
    out.println "</class>\n</hibernate-mapping>"
}
/**
 * 读取字段
 * @param table
 * @return
 */
def calcFields(table) {
    DasUtil.getColumns(table).reduce([]) { fields, col ->
        //获取字段类型
        def spec = Case.LOWER.apply(col.getDataType().getSpecification())
        //正则获取类型长度 返回数组
        def length=spec.findAll(/\d+/)
        //从自定义数据库Java类型映射取值
        def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
        fields += [[
                           name : javaName(col.getName(), false),
                           tName :col.getName(),
                           type : typeStr,
                           length:length[0],
                           comment: col.getComment(),
                           annos: ""]]
    }
}
/**
 * 获取驼峰映射
 * @param str
 * @param capitalize
 * @return
 */
def javaName(str, capitalize) {
    def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
            .collect { Case.LOWER.apply(it).capitalize() }
            .join("")
            .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
    capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

输出结果

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.sample.BizProperty" table="biz_property" >


        <property name="id" type="String">
            <column name="id" length="64" >
                <comment>主键ID</comment>
            </column>
        </property>

        <property name="code" type="String">
            <column name="code" length="200" >
                <comment>编码</comment>
            </column>
        </property>

        <property name="value" type="String">
            <column name="value" length="null" >
                <comment>值</comment>
            </column>
        </property>
 
    </class>
</hibernate-mapping>


posted @ 2025-09-23 21:59  HezhezhiyuLe  阅读(18)  评论(0)    收藏  举报