zoukankan      html  css  js  c++  java
  • mybatis代码生成+自定义注解+自定义注释

    TOC

    mybatis代码生成

            <!--mybatis的包和反向生成的包__用来生成dao,entity层-->
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.4</version>
            </dependency>
            <!-- mybatis-generator-core 反向生成java代码-->
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.3.5</version>
            </dependency>

    配置文件

    resources文件夹中创建文件mbgConfiguration.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    <!-- 第一种mybatis逆向生成xml配置 -->
    <generatorConfiguration>
    
        <context id="sqlserverTables" targetRuntime="MyBatis3" defaultModelType="flat">
    
            <!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
                一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
             -->
            <!--<property name="autoDelimitKeywords" value="false"/>-->
            <!-- 生成的Java文件的编码 -->
            <property name="javaFileEncoding" value="UTF-8"/>
            <!-- 格式化java代码 -->
            <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
            <!-- 格式化XML代码 -->
            <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
    
            <!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
            <property name="beginningDelimiter" value="`"/>
            <property name="endingDelimiter" value="`"/>
    
    
            <!-- 使用自定义的插件:entity的lombok注解 -->
            <plugin type="net.cc.gen.utils.LombokPlugin"/>
            <!--todo 文件名替换-->
            <!-- 此处是将Example改名为Criteria 当然 想改成什么都行~    -->
            <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin">
                <property name="searchString" value="Example$" />
                <!-- 替换后 <property name="replaceString" value="Criteria" /> -->
                <property name="replaceString" value="Query" />
            </plugin>
            <!-- 此处是将UserMapper.xml改名为UserDao.xml 当然 想改成什么都行~ -->
            <!--<plugin type="org.mybatis.generator.plugins.rename.RenameSqlMapperPlugin">-->
                <!--<property name="searchString" value="Mapper" />-->
                <!--<property name="replaceString" value="Dao" />-->
            <!--</plugin>-->
    
            <!-- 此处是将UserMapper改名为UserDao 接口 当然 想改成什么都行~  -->
            <!--<plugin type="org.mybatis.generator.plugins.rename.RenameJavaMapperPlugin">-->
                <!--<property name="searchString" value="Mapper$" />-->
                <!--<property name="replaceString" value="Dao" />-->
            <!--</plugin>-->
            <!--  通过type指定自定义的注释 -->
            <commentGenerator type="net.cc.gen.utils.MyCommentGenerator"/>
    
    
            <!--todo 数据库链接URL、用户名、密码 -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql://localhost:3306/project1?useUnicode=true&amp;useSSL=false&amp;characterEncoding=utf8"
                            userId="test"
                            password="123456"/>
    
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false"/>
            </javaTypeResolver>
    
    
            <!--todo entity包路径-->
            <javaModelGenerator targetPackage="com.cc.learn.entity" targetProject="src/main/java">
                <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
                <property name="enableSubPackages" value="true"/>
                <!-- 从数据库返回的值被清理前后的空格,对String类型字段调用trim()方法  -->
                <property name="trimStrings" value="true"/>
            </javaModelGenerator>
    
            <!--todo mapper的xml路径-->
            <sqlMapGenerator targetPackage="mappings" targetProject="src/main/resources">
                <property name="enableSubPackages" value="true"/>
            </sqlMapGenerator>
    
            <!--todo mapper的java文件路径-->
            <javaClientGenerator type="XMLMAPPER" targetPackage="com.cc.learn.dao.mysql.mapper"
                                 targetProject="src/main/java">
                <property name="enableSubPackages" value="true"/>
            </javaClientGenerator>
    
    
            <!--todo tableName需要生成的table名字
             useActualColumnNames 驼峰命名
             字段类型为text格式的字段需要专门配置
               <columnOverride column="AIRSPACE_DATA" javaType="java.lang.String" jdbcType="VARCHAR"/>
                <columnOverride column="AIRSPACES_DESC" javaType="java.lang.String" jdbcType="VARCHAR"/>
            -->
            <table tableName="User" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>
            <!--<table tableName="数据表2" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>-->
            <!--<table tableName="数据表3" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>-->
    
        </context>
    </generatorConfiguration>

    配置类

    自定义的lombok注解配置

    效果:

    在类上添加注解
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public class User {
        }
    在时间字段上自动添加注解
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date endTime;

    代码

    import org.mybatis.generator.api.IntrospectedColumn;
    import org.mybatis.generator.api.IntrospectedTable;
    import org.mybatis.generator.api.Plugin;
    import org.mybatis.generator.api.PluginAdapter;
    import org.mybatis.generator.api.dom.java.*;
    
    import java.util.*;
    
    /** 自定义的lombok注解配置
    * @author jingshiyu
    * @date 2019/9/17 12:04:47
    * @desc
    */
    public class LombokPlugin extends PluginAdapter {
    
        private final Collection<Annotations> annotations;
    
        /**
         * LombokPlugin constructor
         */
        public LombokPlugin() {
            annotations = new LinkedHashSet<>(Annotations.values().length);
        }
    
        /**
         * @param warnings list of warnings
         * @return always true
         */
        @Override
        public boolean validate(List<String> warnings) {
            return true;
        }
    
        /**
         * Intercepts base record class generation 获取表
         *
         * @param topLevelClass     the generated base record class
         * @param introspectedTable The class containing information about the table as
         *                          introspected from the database
         * @return always true
         */
        @Override
        public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
            addAnnotations(topLevelClass);
            return true;
        }
    
        /**
         * Intercepts primary key class generation
         *
         * @param topLevelClass     the generated primary key class
         * @param introspectedTable The class containing information about the table as
         *                          introspected from the database
         * @return always true
         */
        @Override
        public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
            addAnnotations(topLevelClass);
            return true;
        }
    
        /**
         * Intercepts "record with blob" class generation
         *
         * @param topLevelClass     the generated record with BLOBs class
         * @param introspectedTable The class containing information about the table as
         *                          introspected from the database
         * @return always true
         */
        @Override
        public boolean modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
            addAnnotations(topLevelClass);
            return true;
        }
    
        /**
         * 设置get set方法(使用lombok不需要,直接返回false)
         */
        @Override
        public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
            return false;
        }
    
        /**
         * 设置set方法
         */
        @Override
        public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
            return false;
        }
    
        /**
         * 设置lombok注解 <br>
         */
        private void addAnnotations(TopLevelClass topLevelClass) {
            for (Annotations annotation : annotations) {
                topLevelClass.addImportedType(annotation.javaType);
                topLevelClass.addAnnotation(annotation.asAnnotation());
            }
        }
    
        /**
         * entity类设置
         * @param properties
         */
        @Override
        public void setProperties(Properties properties) {
            super.setProperties(properties);
    
            //@Data is default annotation
            annotations.add(Annotations.DATA);
            annotations.add(Annotations.ALL_ARGS_CONSTRUCTOR);
            annotations.add(Annotations.NO_ARGS_CONSTRUCTOR);
            annotations.add(Annotations.BUILDER);
    
            for (String annotationName : properties.stringPropertyNames()) {
                if (annotationName.contains(".")) {
                    continue;
                }
                String value = properties.getProperty(annotationName);
                if (!Boolean.parseBoolean(value)) {
                    // The annotation is disabled, skip it
                    continue;
                }
                Annotations annotation = Annotations.getValueOf(annotationName);
                if (annotation == null) {
                    continue;
                }
                String optionsPrefix = annotationName + ".";
                for (String propertyName : properties.stringPropertyNames()) {
                    if (!propertyName.startsWith(optionsPrefix)) {
                        // A property not related to this annotation
                        continue;
                    }
                    String propertyValue = properties.getProperty(propertyName);
                    annotation.appendOptions(propertyName, propertyValue);
                    annotations.add(annotation);
                    annotations.addAll(Annotations.getDependencies(annotation));
                }
            }
        }
    
        /**
         * mapper类设置注解
         */
        @Override
        public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
            interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
            interfaze.addAnnotation("@Mapper");
            return true;
        }
    
        /**
         * entity字段设置
         */
        @Override
        public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, Plugin.ModelClassType modelClassType) {
            if (field.getType().getShortNameWithoutTypeArguments().equals("Date")) {
                field.getAnnotations().add(Annotations.DATE_TIME_FORMAT.asAnnotation());
                field.getAnnotations().add(Annotations.JSON_FORMAT.asAnnotation());
                topLevelClass.addImportedType(Annotations.DATE_TIME_FORMAT.javaType);
                topLevelClass.addImportedType(Annotations.JSON_FORMAT.javaType);
            }
            return true;
        }
    
        private enum Annotations {
    
            DATA("data", "@Data", "lombok.Data"),
            BUILDER("builder", "@Builder", "lombok.Builder"),
            ALL_ARGS_CONSTRUCTOR("allArgsConstructor", "@AllArgsConstructor", "lombok.AllArgsConstructor"),
            NO_ARGS_CONSTRUCTOR("noArgsConstructor", "@NoArgsConstructor", "lombok.NoArgsConstructor"),
            ACCESSORS("accessors", "@Accessors", "lombok.experimental.Accessors"),
            TO_STRING("toString", "@ToString", "lombok.ToString"),
            DATE_TIME_FORMAT("dateTimeFormat", "@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")", "org.springframework.format.annotation.DateTimeFormat"),
            JSON_FORMAT("jsonFormat", "@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")", "com.fasterxml.jackson.annotation.JsonFormat");
    
            private final String paramName;
            private final String name;
            private final FullyQualifiedJavaType javaType;
            private final List<String> options;
    
            Annotations(String paramName, String name, String className) {
                this.paramName = paramName;
                this.name = name;
                this.javaType = new FullyQualifiedJavaType(className);
                this.options = new ArrayList<String>();
            }
    
            private static Annotations getValueOf(String paramName) {
                for (Annotations annotation : Annotations.values()) {
                    if (String.CASE_INSENSITIVE_ORDER.compare(paramName, annotation.paramName) == 0) {
                        return annotation;
                    }
                }
    
                return null;
            }
    
            private static Collection<Annotations> getDependencies(Annotations annotation) {
                if (annotation == ALL_ARGS_CONSTRUCTOR) {
                    return Collections.singleton(NO_ARGS_CONSTRUCTOR);
                } else {
                    return Collections.emptyList();
                }
            }
    
            // A trivial quoting.
            // Because Lombok annotation options type is almost String or boolean.
            private static String quote(String value) {
                if (Boolean.TRUE.toString().equals(value) || Boolean.FALSE.toString().equals(value))
                // case of boolean, not passed as an array.
                {
                    return value;
                }
                return value.replaceAll("[\\w]+", ""$0"");
            }
    
            private void appendOptions(String key, String value) {
                String keyPart = key.substring(key.indexOf(".") + 1);
                String valuePart = value.contains(",") ? String.format("{%s}", value) : value;
                this.options.add(String.format("%s=%s", keyPart, quote(valuePart)));
            }
    
            private String asAnnotation() {
                if (options.isEmpty()) {
                    return name;
                }
                StringBuilder sb = new StringBuilder();
                sb.append(name);
                sb.append("(");
                boolean first = true;
                for (String option : options) {
                    if (first) {
                        first = false;
                    } else {
                        sb.append(", ");
                    }
                    sb.append(option);
                }
                sb.append(")");
                return sb.toString();
            }
        }
    }

    代码注释配置

    代码生成时,使用数据控的注释给字段添加文档注释

    效果

        /**
         * 编号
         */
        private String planId;

    代码

    import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    import org.mybatis.generator.api.CommentGenerator;
    import org.mybatis.generator.api.IntrospectedColumn;
    import org.mybatis.generator.api.IntrospectedTable;
    import org.mybatis.generator.api.dom.java.*;
    import org.mybatis.generator.api.dom.xml.XmlElement;
    import org.mybatis.generator.config.MergeConstants;
    import org.mybatis.generator.config.PropertyRegistry;
    import org.mybatis.generator.internal.util.StringUtility;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Properties;
    
    import static org.mybatis.generator.internal.util.StringUtility.isTrue;
    
    /**
    * mybatis逆向工程默认的注释修改(使用表的注释)
    *
    * @author jingshiyu
    * @date 2019/7/17 17:39:36
    * @desc
    */
    public class MyCommentGenerator implements CommentGenerator {
    
        /**
         * The properties.
         */
        private Properties properties;
    
        /**
         * The suppress date.
         */
        private boolean suppressDate;
    
        /**
         * The suppress all comments.
         */
        private boolean suppressAllComments;
    
        /**
         * 是否添加doc注释,true:不添加,false:添加<br>
         * The addition of table remark's comments.
         * If suppressAllComments is true, this option is ignored
         */
        private boolean addRemarkComments;
    
        private SimpleDateFormat dateFormat;
    
        public MyCommentGenerator() {
            super();
            properties = new Properties();
            suppressDate = false;
            suppressAllComments = false;
            addRemarkComments = false;
        }
    
        @Override
        public void addJavaFileComment(CompilationUnit compilationUnit) {
        }
    
        /**
         * 实体类对应的mapper.xml注释,mapper类不加注释,如有需要参考 DefaultCommentGenerator
         */
        @Override
        public void addComment(XmlElement xmlElement) {
            if (suppressAllComments) {
                return;
            }
        }
    
        @Override
        public void addRootComment(XmlElement rootElement) {
    
        }
    
        @Override
        public void addConfigurationProperties(Properties properties) {
            this.properties.putAll(properties);
    
            suppressDate = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
    
            suppressAllComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
    
            addRemarkComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_ADD_REMARK_COMMENTS));
    
            String dateFormatString = properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_DATE_FORMAT);
            if (StringUtility.stringHasValue(dateFormatString)) {
                dateFormat = new SimpleDateFormat(dateFormatString);
            }
        }
    
        protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
            javaElement.addJavaDocLine(" *");
            StringBuilder sb = new StringBuilder();
            sb.append(" * ");
            sb.append(MergeConstants.NEW_ELEMENT_TAG);
            if (markAsDoNotDelete) {
                sb.append(" do_not_delete_during_merge");
            }
            String s = getDateString();
            if (s != null) {
                sb.append(' ');
                sb.append(s);
            }
            javaElement.addJavaDocLine(sb.toString());
        }
    
        protected String getDateString() {
            if (suppressDate) {
                return null;
            } else if (dateFormat != null) {
                return dateFormat.format(new Date());
            } else {
                return new Date().toString();
            }
        }
    
        /**
         * 设置class的注解
         */
        @Override
        public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
            if (suppressAllComments) {
                return;
            }
    
            StringBuilder sb = new StringBuilder();
    
            innerClass.addJavaDocLine("/**");
    
    //        sb.append(" * This class corresponds to the database table ");
            sb.append(introspectedTable.getFullyQualifiedTable());
            innerClass.addJavaDocLine(sb.toString());
    
            addJavadocTag(innerClass, false);
    
            innerClass.addJavaDocLine(" */");
        }
    
        /**
         * 方法注释
         */
        @Override
        public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
            if (suppressAllComments || !addRemarkComments) {
                return;
            }
    
            StringBuilder sb = new StringBuilder();
    
            topLevelClass.addJavaDocLine("/**");
            //设置数据库的备注
            String remarks = introspectedTable.getRemarks();
            if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
                topLevelClass.addJavaDocLine(" * Database Table Remarks:");
                String[] remarkLines = remarks.split(System.getProperty("line.separator"));
                for (String remarkLine : remarkLines) {
                    topLevelClass.addJavaDocLine(" *   " + remarkLine);
                }
            }
            topLevelClass.addJavaDocLine(" *");
            sb.append(introspectedTable.getFullyQualifiedTable());
            topLevelClass.addJavaDocLine(sb.toString());
    
            addJavadocTag(topLevelClass, true);
    
            topLevelClass.addJavaDocLine(" */");
        }
    
        /**
         * 添加枚举的注释
         */
        @Override
        public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
            if (suppressAllComments) {
                return;
            }
    
            StringBuilder sb = new StringBuilder();
    
            innerEnum.addJavaDocLine("/**");
            sb.append(introspectedTable.getFullyQualifiedTable());
            innerEnum.addJavaDocLine(sb.toString());
    
            addJavadocTag(innerEnum, false);
    
            innerEnum.addJavaDocLine(" */");
        }
    
        /**
         * 实体类字段注释
         */
        @Override
        public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
            if (suppressAllComments || StringUtils.isEmpty(introspectedColumn.getRemarks())) {
                return;
            }
    
            field.addJavaDocLine("/**");
    
            StringBuilder sb = new StringBuilder();
            //  introspectedColumn.getRemarks() 就是获取字段注释
            sb.append(" * " + introspectedColumn.getRemarks());
            field.addJavaDocLine(sb.toString());
            field.addJavaDocLine(" */");
        }
    
        /**
         * 实体类的静态字段
         */
        @Override
        public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
            if (suppressAllComments) {
                return;
            }
        }
    
        /**
         * 实体类toString方法
         */
        @Override
        public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
            if (suppressAllComments) {
                return;
            }
        }
    
        /**
         * 实体类getter方法注释
         */
        @Override
        public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
            if (suppressAllComments) {
                return;
            }
        }
    
        /**
         * 实体类setter注释
         */
        @Override
        public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
            if (suppressAllComments) {
                return;
            }
        }
    
        /**
         * 类注释
         * @param innerClass
         * @param introspectedTable
         * @param markAsDoNotDelete
         */
        @Override
        public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
            if (suppressAllComments) {
                return;
            }
    
            StringBuilder sb = new StringBuilder();
    
            innerClass.addJavaDocLine("/**");
    
            sb.append(introspectedTable.getFullyQualifiedTable());
            innerClass.addJavaDocLine(sb.toString());
    
            addJavadocTag(innerClass, markAsDoNotDelete);
    
            innerClass.addJavaDocLine(" */");
        }
    }

    调用

    import org.mybatis.generator.api.MyBatisGenerator;
    import org.mybatis.generator.config.Configuration;
    import org.mybatis.generator.config.xml.ConfigurationParser;
    import org.mybatis.generator.exception.InvalidConfigurationException;
    import org.mybatis.generator.internal.DefaultShellCallback;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
    * java代码生成器(会生成example的entity)<br>
    * mybatis逆向工程
    *
    * @author jingshiyu
    * @date 2019/7/17 17:24
    * @desc java代码生成器(会生成example的entity)<br>
    */
    public class JavaExampleGenerator {
        public static void main(String[] args) {
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
            //如果这里出现空指针,直接写绝对路径即可。
            String genCfg = "/mbgConfiguration.xml";
            File configFile = new File(JavaExampleGenerator.class.getResource(genCfg).getFile());
            ConfigurationParser cp = new ConfigurationParser(warnings);
            Configuration config = null;
            try {
                config = cp.parseConfiguration(configFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = null;
            try {
                myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
            } catch (InvalidConfigurationException e) {
                e.printStackTrace();
            }
            try {
                myBatisGenerator.generate(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }




  • 相关阅读:
    Android -- junit测试框架,logcat获取log信息
    【Android】ADB常用指令与logcat日志
    Android -- UI布局管理,相对布局,线性布局,表格布局,绝对布局,帧布局
    Unicode的解救方案
    第一个程序
    Windows程序设计第五版
    愉快的开始
    图形用户界面入门:EasyGui
    丰富的else语句及简洁的with语句
    异常处理:你不可能总是对的2
  • 原文地址:https://www.cnblogs.com/ziyue7575/p/611b6f29ce5e7bcc8dd54291537972e6.html
Copyright © 2011-2022 走看看