mybatis-generator通过JavaParser工具实现Java代码合并

mybatis-generator默认不支持Java代码合并,本文介绍了如何通过扩展ShellCallback接口并利用JavaParser工具实现这一功能。首先分析mybatis-generator源代码,然后引入并升级JavaParser库版本,接着重写mergeJavaFile方法,使用JavaParser解析新旧Java文件的 CompilationUnit,合并package、import、class、field和method等内容,从而完成代码合并。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先附上我扩展后项目的github地址 点击打开链接
用过mybatis-generator的人应该都清楚,它默认是不支持Java代码合并的,只支持XML合并,这给我们的开发工作带来了一些麻烦。查看源代码
它默认的代码是这样的:
    /* (non-Javadoc)
     * @see org.mybatis.generator.api.ShellCallback#mergeJavaFile(java.lang.String, java.lang.String, java.lang.String[], java.lang.String)
     */
    public String mergeJavaFile(String newFileSource,
            String existingFileFullPath, String[] javadocTags, String fileEncoding)
            throws ShellException {
        throw new UnsupportedOperationException();
    }
仅仅是抛出了一个不支持的异常。如是我试着去扩展了这个接口,中间借助了JavaParser这个用于解析Java文件的工具,附上它的github地址:点击打开链接
在引用它的maven包的时候我发现,原来mybatis-generator中也对它有使用,只是版本比较低,我将其改成了高版本的,修改后如下:
<!-- TODO: Raising above 2.4.0 required jdk 8 usage -->
            <dependency>
                <groupId>com.github.javaparser</groupId>
                <artifactId>javaparser-core</artifactId>
                <version>3.2.10</version>
                <!--<scope>test</scope>-->
            </dependency>
最后我重写了mergeJavaFile方法,这个代码如下:
public String mergeJavaFile(String newFileSource,
                                String existingFileFullPath)
            throws ShellException, FileNotFoundException {
        return new JavaFileMergerJaxp().getNewJavaFile(newFileSource,existingFileFullPath);
    }

 public String getNewJavaFile(String newFileSource, String existingFileFullPath) throws FileNotFoundException {
        CompilationUnit newCompilationUnit = JavaParser.parse(newFileSource);
        CompilationUnit existingCompilationUnit = JavaParser.parse(new File(existingFileFullPath));
        return mergerFile(newCompilationUnit,existingCompilationUnit);
    }

public String mergerFile(CompilationUnit newCompilationUnit,CompilationUnit existingCompilationUnit){

        StringBuilder sb = new StringBuilder(newCompilationUnit.getPackageDeclaration().get().toString());
        newCompilationUnit.removePackageDeclaration();

        //合并imports
        NodeList<ImportDeclaration> imports = newCompilationUnit.getImports();
        imports.addAll(existingCompilationUnit.getImports());
        Set importSet = new HashSet<ImportDeclaration>();
        importSet.addAll(imports);

        NodeList<ImportDeclaration> newImports = new NodeList<>();
        newImports.addAll(importSet);
        newCompilationUnit.setImports(newImports);
        for (ImportDeclaration i:newCompilationUnit.getImports()) {
            sb.append(i.toString());
        }
        newLine(sb);
        NodeList<TypeDeclaration<?>> types = newCompilationUnit.getTypes();
        NodeList<TypeDeclaration<?>> oldTypes = existingCompilationUnit.getTypes();

        for (int i = 0;i<types.size();i++) {
            //截取Class
            String classNameInfo = types.get(i).toString().substring(0, types.get(i).toString().indexOf("{")+1);
            sb.append(classNameInfo);
            newLine(sb);
            newLine(sb);
            //合并fields
            List<FieldDeclaration> fields = types.get(i).getFields();
            List<FieldDeclaration> oldFields = oldTypes.get(i).getFields();
            List<FieldDeclaration> newFields = new ArrayList<>();
            HashSet<FieldDeclaration> fieldDeclarations = new HashSet<>();
            fieldDeclarations.addAll(fields);
            fieldDeclarations.addAll(oldFields);
            newFields.addAll(fieldDeclarations);
            for (FieldDeclaration f: newFields){
                sb.append(f.toString());
                newLine(sb);
                newLine(sb);
            }

            //合并methods
            List<MethodDeclaration> methods = types.get(i).getMethods();
            List<MethodDeclaration> existingMethods = oldTypes.get(i).getMethods();
            for (MethodDeclaration f: methods){
                sb.append(f.toString());
                newLine(sb);
                newLine(sb);
            }
            for (MethodDeclaration m:existingMethods){
                boolean flag = true;
                for (String tag : MergeConstants.OLD_ELEMENT_TAGS) {
                    if (m.toString().contains(tag)) {
                        flag = false;
                        break;
                    }
                }
                if (flag){
                    sb.append(m.toString());
                    newLine(sb);
                    newLine(sb);
                }
            }

            //判断是否有内部类
            types.get(i).getChildNodes();
            for (Node n:types.get(i).getChildNodes()){
                if (n.toString().contains("static class")){
                    sb.append(n.toString());
                }
            }

        }

        return sb.append(System.getProperty("line.separator")+"}").toString();
    }

希望能给大家带来一些参考
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值