Maison  >  Article  >  Java  >  Comment SpringBoot intègre freemarker pour implémenter le générateur de code

Comment SpringBoot intègre freemarker pour implémenter le générateur de code

WBOY
WBOYavant
2023-05-10 20:37:101143parcourir

    1. Introduction

    Dans le processus actuel de développement de projets logiciels, je peux vous dire de manière responsable que si vous avez réellement écrit du code depuis plus de 5 ans, vous ne serez pas familier avec du code simple tel que l'ajout, la suppression, modification et requête. On peut dire que le développement des exigences fonctionnelles a été complètement écrit, du moins je suis ce type.

    Cependant, il est indéniable que la grande majorité des fonctions du logiciel, jusqu'à l'unité la plus basique, sont essentiellement l'ajout, la suppression, la modification et l'interrogation d'une seule table !

    C'est juste qu'à mesure que les besoins des utilisateurs continuent d'augmenter, les choses qui pouvaient avoir été faites avec une seule table dans le passé peuvent désormais nécessiter plusieurs tables ou plusieurs bibliothèques. La couche de code est comme empiler des blocs, et plus ils sont empilés, plus. ils deviennent plus complexes.

    Je me souviens quand je travaillais sur un projet au début, chaque fois que j'ajoutais une seule table au projet, je devais réécrire un ensemble de CURD au niveau du code conformément aux idée du framework MVC. Pour écrire le code, il faut au moins 20 minutes pour écrire tous les ajouts, suppressions, modifications et vérifications de base. Si vous êtes rapide, cela peut prendre jusqu'à 10. minutes au plus vite. MVC框架的思想,重新编写一套CURD的代码,写完所有的基础的增删改查,至少需要20分钟,手快的情况下,最快也要10分钟。

    假如某个新开发的功能,要新增10张表,按照这个时间计算,至少要100分钟,仔细想想,其实你会发现大部分的时间都浪费在这些简单而又重复的编程圈子中去了。

    那有没有一个办法,将这些简单的CURD代码,全部都标准化、公共化呢?这样我们的可以省下很多时间来投入业务场景的开发。

    答案是肯定的,有!

    我记得早期我最先接触的是MybatisGenertor工具包,通过这个工具包,我们可以省去大部分的mybaitsxml文件的curd编写工作。

    还有我们所熟悉的JPA,里面有一套公共的持久层动态代理类,它可以自动根据名称生成SQL语句,能为开发省下不少的事情。

    但是我这个人比较懒,我想搞一个工具,从controllerserviceentity dao层,全部的crud代码,包括单元测试类,通过工具自动生成好。

    像这样的工具,现在网上也有不少,例如我们所熟悉的Mybatis-plus插件,它就可以做到这一点,也是非常好用。

    但是有的公司就不喜欢它,原因也很简单,里面的很多公共方法封装的过于深入,而且很多crudsql全部都是动态生成,你根本看不到。

    总之啊就是一句,不在自己掌控之内的,很多程序员总是带着各种疑虑~~

    当然,还有一个明显的疑虑,就是对微服务的开发,不能全面支持,比如你项目采用的是SpringBoot +Dubbo组合来开发,这个时候生成的controller,完全没啥用处,而且还很鸡肋。

    因此在这种情况下,你得基于当前的项目软件开发规则,自己开发一套代码生成器,以满足快速开发的需要。

    下面我就简单的介绍一下,如何自行开发一套代码生成器,过程如下!

    二、代码实践

    其实开发一套代码生成器,真没大家想象中的那么复杂,其中用的最重要一项技术,就是利用模板来生成代码,例如我们经常使用的模板引擎freemarker,它就可以帮助我们实现这一点。

    2.1、首先我们添加 freemarker 依赖包

    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.23</version>
    </dependency>

    2.2、然后创建一个代码模版

    下面我们以动态创建实体类为例,编写一个实体类的模板entity.java.ftl,其中${}里面定义的是动态变量。

    package ${package};
    
    import java.io.Serializable;
    
    /**
     * <p>
     * ${tableComment}
     * </p>
     *
     * @author ${author}
     * @since ${date}
     */
    public class ${entityClass} implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
        <#--属性遍历-->
        <#list columns as pro>
    
        /**
         * ${pro.comment}
         */
        private ${pro.propertyType} ${pro.propertyName};
        </#list>
    
        <#--属性get||set方法-->
        <#list columns as pro>
        public ${pro.propertyType} get${pro.propertyName?cap_first}() {
            return this.${pro.propertyName};
        }
    
        public ${entityClass} set${pro.propertyName?cap_first}(${pro.propertyType} ${pro.propertyName}) {
            this.${pro.propertyName} = ${pro.propertyName};
            return this;
        }
        </#list>
    }

    2.3、最后生成目标代码

    最后我们基于freemarker编写一个测试类!

    public class CodeGeneratorDemo {
    
        public static void main(String[] args) throws IOException, TemplateException {
            Map<String, Object> objectMap = new HashMap<>();
            //定义包路径
            objectMap.put("package", "com.example.test");
            //定义实体类
            objectMap.put("entityClass", "Student");
    
            //定义实体类属性
            List<Map<String, Object>> columns = new ArrayList<>();
            //姓名字段
            Map<String, Object> column1 = new HashMap<>();
            column1.put("propertyType", "String");
            column1.put("propertyName", "name");
            column1.put("comment", "姓名");
            columns.add(column1);
            //年龄字段
            Map<String, Object> column2 = new HashMap<>();
            column2.put("propertyType", "Integer");
            column2.put("propertyName", "age");
            column2.put("comment", "年龄");
            columns.add(column2);
    
            //定义类的属性
            objectMap.put("columns", columns);
            //定义作者
            objectMap.put("author", "张三");
            //定义创建时间
            objectMap.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            //定义类描述
            objectMap.put("tableComment", "学生信息");
    
            //生产目标代码
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
            configuration.setDefaultEncoding(Charset.forName("UTF-8").name());
            configuration.setClassForTemplateLoading(CodeGeneratorDemo.class, "/");
            Template template = configuration.getTemplate("/templates/entity.java.ftl");
            FileOutputStream fileOutputStream = new FileOutputStream(new File("../src/main/java/com/example/generator/Student.java"));
            template.process(objectMap, new OutputStreamWriter(fileOutputStream, Charset.forName("UTF-8").name()));
            fileOutputStream.close();
            System.out.println("文件创建成功");
    
        }
    }

    运行程序,输出的文件结果如下!

    package com.example.test;
    
    import java.io.Serializable;
    
    /**
     * <p>
     * 学生信息
     * </p>
     *
     * @author 张三
     * @since 2021-08-22
     */
    public class Student implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
        public String getName() {
            return this.name;
        }
    
        public Student setName(String name) {
            this.name = name;
            return this;
        }
        public Integer getAge() {
            return this.age;
        }
    
        public Student setAge(Integer age) {
            this.age = age;
            return this;
        }
    }

    与预期的效果一致,成功生成!

    例如小编我就是采用这种方式,首先把要通过工具生成的代码,全部通过模板方式定义好。

    Comment SpringBoot intègre freemarker pour implémenter le générateur de code

    然后通过连接数据库的方式,把需要自动生成的表结构查询出来,封装成数据渲染参数,最后传入到freemarker中去,非常简单、快速的生成与自己预期想要的代码,所有单表的crud全部一步到位!

    下面这个就是小编,基于当前项目定制开发的一款代码生成器,项目采用SpringBoot + Dubbo框架开发,没有Controller

    Si une fonction nouvellement développée nécessite l'ajout de 10 nouvelles tables, cela prendra au moins 100 minutes en fonction de ce temps. Si vous y réfléchissez bien, vous constaterez en fait que la plupart du temps est perdu dans ces cercles de programmation simples et répétitifs. . J'ai été touché.

    Comment SpringBoot intègre freemarker pour implémenter le générateur de codeExiste-t-il un moyen de standardiser et de faire connaître tous ces codes simples CURD ? De cette manière, nous pouvons gagner beaucoup de temps pour investir dans l’élaboration de scénarios commerciaux.

    🎜La réponse est oui, oui ! 🎜🎜Je me souviens que la première chose avec laquelle je suis entré en contact au début était la boîte à outils MybatisGenertor. Grâce à cette boîte à outils, nous pouvons enregistrer la plupart du xmldans . mybaits >caillé préparation des fichiers. 🎜🎜Il existe également JPA que nous connaissons, qui possède un ensemble de classes proxy dynamiques de couche de persistance publique. Il peut générer automatiquement des instructions SQL basées sur le nom, qui. peut gagner beaucoup de temps de développement. 🎜🎜Mais je suis une personne paresseuse. Je veux créer un outil à partir de controller, service, entity , dao. > couche, tous les codes crud, y compris les classes de tests unitaires, sont automatiquement générés par les outils. 🎜🎜Il existe désormais de nombreux outils de ce type sur Internet, tels que le plug-in familier Mybatis-plus, qui peut le faire et est très simple à utiliser. 🎜🎜Mais certaines entreprises ne l'aiment pas, et la raison est très simple. De nombreuses méthodes publiques y sont encapsulées trop profondément, et de nombreux sql de crud sont tous. généré dynamiquement, vous ne pouvez pas le voir du tout. 🎜🎜En bref, ce n'est pas sous leur contrôle. De nombreux programmeurs ont toujours divers doutes~~🎜🎜Bien sûr, il y a aussi un doute évident, c'est-à-dire que le développement de microservices ne peut pas être entièrement pris en charge. développé en utilisant une combinaison de SpringBoot + Dubbo Le contrôleur généré à cette époque était complètement inutile et de mauvais goût. 🎜🎜Donc, dans ce cas, vous devez développer votre propre générateur de code basé sur les règles actuelles de développement logiciel du projet pour répondre aux besoins d'un développement rapide. 🎜🎜Maintenant, je vais vous présenter brièvement comment développer un générateur de code par vous-même. Le processus est le suivant ! 🎜🎜2. Pratique du code🎜🎜En fait, développer un générateur de code n'est pas aussi compliqué que tout le monde le pense. La technologie la plus importante utilisée est d'utiliser des modèles pour générer du code. Par exemple, nous utilisons le moteur de modèles freemarker<.> peut nous aider à y parvenir. 🎜<h4>2.1. Tout d'abord, nous ajoutons le package de dépendances freemarker</h4>rrreee<h4>2.2, puis créons un modèle de code</h4>🎜Prenons la création dynamique d'une classe d'entité comme exemple et écrivons une classe d'entité. template<code>entity.java.ftl, où ${} définit des variables dynamiques. 🎜rrreee

    2.3. Enfin générer le code cible

    🎜Enfin nous écrivons une classe de test basée sur freemarker ! 🎜rrreee🎜Exécutez le programme et les résultats du fichier de sortie sont les suivants ! 🎜rrreee🎜L'effet est conforme à celui attendu et généré avec succès ! 🎜🎜Par exemple, l'éditeur utilise cette méthode. Dans un premier temps, tous les codes à générer par l'outil sont définis via des modèles. 🎜🎜Comment SpringBoot intègre-t-il freemarker pour implémenter le générateur de code🎜🎜Puis connectez-vous via En utilisant la méthode de base de données, interrogez la structure de table qui doit être générée automatiquement, encapsulez-la dans les paramètres de rendu des données et enfin transmettez-la dans freemarker. Il est très simple et rapide de générer le code souhaité. . Tout le crud pour une seule table se fait en une seule étape ! 🎜🎜Ce qui suit est un générateur de code personnalisé et développé par l'éditeur sur la base du projet actuel. Le projet est développé en utilisant le framework SpringBoot + Dubbo. Il n'y a pas de couche Controller. . Tout dans la capture d'écran Tous les codes sont générés à l'aide d'un générateur de code et peuvent être exécutés directement via des tests unitaires. Le développement est très rapide ! 🎜🎜🎜🎜

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer