mybatis代碼生成+自定義注解+自定義注釋實例
更新時間:2021年10月09日 08:53:00 作者:ziyue7575
這篇文章主要介紹了mybatis代碼生成+自定義注解+自定義注釋實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
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文件夾中創(chuàng)建文件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"> <!-- 自動識別數(shù)據(jù)庫關(guān)鍵字,默認false,如果設(shè)置為true,根據(jù)SqlReservedWords中定義的關(guān)鍵字列表; 一般保留默認值,遇到數(shù)據(jù)庫關(guān)鍵字(Java關(guān)鍵字),使用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:指明數(shù)據(jù)庫的用于標記數(shù)據(jù)庫對象名的符號,比如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 數(shù)據(jù)庫鏈接URL、用戶名、密碼 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/project1?useUnicode=true&useSSL=false&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的基礎(chǔ)上,根據(jù)數(shù)據(jù)庫的schema再生成一層package,最終生成的類放在這個package下,默認為false --> <property name="enableSubPackages" value="true"/> <!-- 從數(shù)據(jù)庫返回的值被清理前后的空格,對String類型字段調(diào)用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="數(shù)據(jù)表2" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>--> <!--<table tableName="數(shù)據(jù)表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; } /** * 設(shè)置get set方法(使用lombok不需要,直接返回false) */ @Override public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { return false; } /** * 設(shè)置set方法 */ @Override public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { return false; } /** * 設(shè)置lombok注解 <br> */ private void addAnnotations(TopLevelClass topLevelClass) { for (Annotations annotation : annotations) { topLevelClass.addImportedType(annotation.javaType); topLevelClass.addAnnotation(annotation.asAnnotation()); } } /** * entity類設(shè)置 * @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類設(shè)置注解 */ @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字段設(shè)置 */ @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(); } } }
代碼注釋配置
代碼生成時,使用數(shù)據(jù)控的注釋給字段添加文檔注釋
效果
/** * 編號 */ 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) { } /** * 實體類對應(yīng)的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(); } } /** * 設(shè)置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("/**"); //設(shè)置數(shù)據(jù)庫的備注 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(" */"); } /** * 實體類的靜態(tài)字段 */ @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(" */"); } }
調(diào)用
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; //如果這里出現(xiàn)空指針,直接寫絕對路徑即可。 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(); } } }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java應(yīng)用占用內(nèi)存過高排查的解決方案
這篇文章主要介紹了java應(yīng)用占用內(nèi)存過高排查的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03搭建MyBatis開發(fā)環(huán)境及基本的CURD介紹
這篇文章主要介紹了搭建MyBatis開發(fā)環(huán)境及基本的CURD,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08Java實現(xiàn)優(yōu)雅停止線程的有效方法詳解
這篇文章主要為大家詳細如何安全有效停止 Java 線程的,確保多線程應(yīng)用程序平穩(wěn)運行并實現(xiàn)最佳資源管理,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12