xml生成2维码_MyBatis(2)之MyBatis-Generator最佳实践

自定义注释

自定义注解

指定xml文件模式

上一篇文章详细阐述了xml配置文件的各种标签及其含义。其实从标签开始,每一个标签都对应一个实体类。context.class对应标签,而每一个子标签都对应一个属性;如图:

e1c2b2cc6c41f1b9e6000e5f17eacc23.png

标签与实体类的对应关系

。有了实体类的关系,那么自定义起来还不是易如反掌。

自定义添加注释

以用数据库中字段的注释,作为Model属性的注释为例:

针对注解的标签是,对应的接口实体类是CommentGenerator,该类中封装了针对GetterComment、SetterComment、FieldComment、ClassComment以及xml中的注解,这些方法在生成实体类时,会通过Context被调用;该接口默认有默认的实现类DefaultCommentGenerator。切入点就是该DefaultCommentGenerator:

  1. 去除原始的Getter、Setter方法的默认注释,只要实现addSetterComment、addGetterComment方法,返回为空,原生注释就不会再生成;
  2. 实现addFieldComment方法(管控Model属性的注释内容),具体如下:
 @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { StringBuffer sb = new StringBuffer(); field.addJavaDocLine("/**"); field.addJavaDocLine("*"); // 获取表的名称 sb.append("* TableName: " + introspectedTable.getFullyQualifiedTable() + ""); //获取该表中属性的名称 sb.append("* ColumnName: " + introspectedColumn.getActualColumnName() + ""); sb.append("*
" + ""); //该字段的comment 信息 sb.append("*" + introspectedColumn.getRemarks()); field.addJavaDocLine(sb.toString()); field.addJavaDocLine("*
"); field.addJavaDocLine("**/"); }

解释:

  1. addFieldComment方法有重载,意思是是否标注当前属性对应数据库的那个字段,看个人需要选择性实现。
  2. IntrospectedTable实体类封装了数据库表对应的原始信息,相应的IntrospectedColumn则是封装了表中字段的原始信息,所有我们通过该对象获取到字段的注释,在添加到实体类的属性上.(我这个地方没有封装,源码中是封装了生成所有注释的通用方法,实际运用中可统一封装)。
  3. MyBatis将java中类、方法、接口、枚举、内部类、内部类枚举抽象成JavaElement对象,而Field则是针对类中属性的封装。
  4. 本人感觉xml文件中的注释多余,就实现addComment方法,不做任何的实现,去除xml中的原生注释;

自定义注解

在目前我们开发中,注解使用的非常广发,大大简化了我们的开发,比如:

  • LomBook针对实体类对象各种注解,最常用的@Data(@Setter,@Getter)、@NoArgsConstructor等。那能否再Model上自动添加上我们需要的注解呢?
  • 我们知道Spring Boot中Mapper接口对应的注解是@Repository注解,但原生生成时不会有该注解的,那要一个一个类手动添加吗?

针对以上需求,我们详细聊聊PluginAdapter。通过Idea查看该类的结构,可以看到该中方法非常之多,但可分为:

  • clientxxxx相关的方法控制Mapper接口生成规则,细粒度到每个能够生成的方法上
  • sqlMapxxxx相关方法控制xml文件生成的方式,细粒度到每个能够生成的方法上;
  • modelxxxx相关方法控制Model类的生成规则。model类的生成规则有三种,所以model相关的方法也是关于三种规则生成时的相关方法;
  • 针对以上需求,我们逐个击破:
  1. 生成的Model上增加Lombook相关的注释,继承PluginAdapter类,重写modelBaseRecordClassGenerated方法,具体如下:
@Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { javaTypes().forEach(item->topLevelClass.addImportedType(item)); addAnnons().forEach(item->topLevelClass.addAnnotation(item)); return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable); } //注解对应的完整的类路径 private List javaTypes(){ List javaTypes = new ArrayList<>(2); javaTypes.add(new FullyQualifiedJavaType("lombok.Data")); javaTypes.add(new FullyQualifiedJavaType("lombok.NoArgsConstructor")); return javaTypes; } //需要添加的注解 private List addAnnons(){ List annons = new ArrayList<>(2); annons.add("@Data"); annons.add("@NoArgsConstructor"); return annons; }

通过上面方法,在生成Model时会自动添加上相应的注解;再比如:Spring Boot的Swagger也是通过注解,如果返回前端的实体类也是通过Mybatis Generator自动生成,那么就可以将@ApiModel以及@ApiModelProperty注解添加到生成的类中;是不是特别的方便;

xml文件的两种模式

在MyBatis生成的xml默认是append的方式,比如:随着需求版本的迭代,数据库中的字段改变,对应的实体类以及xml需要重新生成,那么默认新生成的xml内容,会追加到旧的版本中,这时启动项目会报错(resultMap标签重复),所以这时需要将旧的覆盖掉;

此时我们要干预xml文件的生成方式,那么继承PluginAdaptor重写sqlMapGenerated方法。该方法中GeneratedXmlFile参数是封装xml文件的所有属性,其中私有属性isMergeable即是否合并的意思,默认为false,那么我们现在就要改变该属性的值。可惜的是该属性没有公开,需要通过反射改变,具体如下:

 @Override public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) { try { Field field = sqlMap.getClass().getDeclaredField("isMergeable"); field.setAccessible(true); field.setBoolean(sqlMap, false); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } return true; }

在生成时就会覆盖原来的旧文件。那如果自定义的sql也写在该文件,那么也会被覆盖,目前我实践的解决方案有两种:

  1. 通过版本管理工具控制。比如git,被覆盖掉的方法,都会有提示或者能够重新回退到最近的一个版本,方法就可以再找回来;
  2. 分两个xml文件,同一个Mapper接口对应两个xml,一个是自动生成的,永远保存自动生成的,另外在创建一个自定义的sql语句的xml文件。
  3. 个人推荐第二种,最不易出错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427323.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx 配置详解_Nginx 配置详解

序言Nginx是lgor Sysoev为俄罗斯访问量第二的http://rambler.ru站点设计开发的。从2004年发布至今&#xff0c;凭借开源的力量&#xff0c;已经接近成熟与完善。Nginx功能丰富&#xff0c;可作为HTTP服务器&#xff0c;也可作为反向代理服务器&#xff0c;邮件服务器。支持Fast…

推荐系统——GBDT+LR

[[逻辑回归模型]] 逻辑回归是在[[线性回归]]的基础上添加了一个Sigmoid函数&#xff08;非线形&#xff09;映射&#xff0c;从而可以使逻辑回归成为一个优秀的分类算法 逻辑回归假设数据服从[[伯努利分布]]&#xff0c;通过[[极大化似然函数]]的方法&#xff0c;运用[[梯度下降…

从燃尽图看项目管理:你的项目哪里出错了?(燃尽图类型全解析)

什么是燃尽图 燃尽图&#xff08;burn down chart&#xff09;是在项目完成之前&#xff0c;对需要完成的工作任务的一种可视化表示。理想情况下&#xff0c;该图表是一个向下的曲线&#xff0c;随着项目任务的逐渐完成“烧尽”至零。 燃尽图常常用于敏捷开发中&#xff0c;作为…

springtboot 引用子工程的文件_xmake从入门到精通11:如何组织构建大型工程

xmake是一个基于Lua的轻量级现代化c/c的项目构建工具&#xff0c;主要特点是&#xff1a;语法简单易上手&#xff0c;提供更加可读的项目维护&#xff0c;实现跨平台行为一致的构建体验。本文主要详细讲解下&#xff0c;如何通过配置子工程模块&#xff0c;来组织构建一个大规模…

依赖项出现感叹号怎么办_SpringBoot中如何对依赖进行管理?

SpringBoot中的起步依赖(starter)是一组特定功能的依赖项集合&#xff0c;SpringBoot通过starter来进行项目的依赖管理&#xff0c;而不是直接基于单独的依赖项来进行依赖管理。starter其实就是特殊的Maven依赖项或者Gradle依赖项&#xff0c;它把常用的库组合到一起构成了一个…

5g理论速度_5G是什么?5G速度有多快?

原标题&#xff1a;5G是什么&#xff1f;5G速度有多快&#xff1f;5G到底是什么东西&#xff1f;今年5G网络会普及吗&#xff1f;5G网速到底有多快&#xff0c;背后又有哪些黑科技&#xff1f;近日&#xff0c;全球首个5G火车站在上海虹桥火车站启动建设。而根据三大运营商的时…

c++ new一个结构体_「C/C++」构造类型及应用:数组、结构体、共用体、枚举类型...

3.1数组同类型、同性质、按顺序存放的一组数据集合&#xff0c;易于批量处理。3.1.1一维数组定义int 1.数组名为常量&#xff0c;指向首地址&#xff0c;由系统指定。2.数组长度为整型常量,但不能为03.上例取值image[0]-image[255]&#xff0c;取值可以修改。初始化int 输入for…

自动产生fsm代码的工具_代码自动生成工具

构建支持多种数据库类型的代码自动生成工具背景&#xff1a;一般的业务代码中写来写去&#xff0c;无外乎是先建好model&#xff0c;然后针对这个model做些CRUD的操作。(主要针对单表的业务操作)针对于数据库dao、mapper等的代码自动生成已经有了mybatisGenerator这种工具&…

gtest测试框架使用详解_测试框架TestNG使用介绍

近期接触到了一个比较全面的基于Java的接口自动化测试框架&#xff0c;作为一名Java小白&#xff0c;所以打算研究一下&#xff0c;顺带学习学习Java&#xff0c;该测试框架的逻辑控制层使用的HttpClient TestNG。在本期中&#xff0c;给大家分享一下TestNG测试框架的基础知识…

LOJ#6282. 数列分块入门 6

一个动态的插入过程&#xff0c;还需要带有查询操作。 我可以把区间先分块&#xff0c;然后每个块块用vector来维护它的插入和查询操作&#xff0c;但是如果我现在这个块里的vector太大了&#xff0c;我可能的操作会变的太大&#xff0c;所以这时候我需要把现在里面的数全部拿出…

fragment在activity中的静态和动态用法_使用Matlab修改压缩Gif动态图片制作微信表情...

脚本之家你与百万开发者在一起作者&#xff1a;theOwlAndPussyCat/焦旭光引言电脑里存了很多有意思的Gif动态图片&#xff0c;闲暇想把这些动图全导入微信表情&#xff0c;可是这些动图很多大小超过了微信表情大小1MB的限制&#xff0c;要制作成表情只能压缩图像文件大小。网上…

frontcon函数用不了_C++复制构造函数与析构函数

想用机器人赋能未来&#xff0c;少不了扎实的编程的基本功&#xff0c;让我们跟着清华大学的C语言程序设计课程一起过一遍C的语法知识吧&#xff01;当定义基本类型的变量时&#xff0c;经常会用已有的变量去初始化新定义的变量&#xff0c;当定义对象的时候也有类似的需求&…

软件项目立项书_2019年度上海市软件和集成电路产业发展专项资金项目立项

上海艾瑞德生物科技有限公司荣获2019年上海市软件和集成电路产业发展专项资金(集成电路和电子信息制造领域)项目立项&#xff01;上海艾瑞德生物科技有限公司的【医用体外诊断动态光场图像采集电子模块的研发及产业化】喜获2019年上海市软件和集成电路产业发展专项资金(集成电路…

mysql提供了表示日期和时间的数据类型_MySQL数据类型 - 日期和时间类型(1)

1.日期和时间数据类型语法用于表示时间值的日期和时间数据类型是DATE, TIME, DATETIME, TIMESTAMP和 YEAR。对于TIME, DATETIME和 TIMESTAMP值&#xff0c;MySQL支持小数秒&#xff0c;精度可达微秒(6位数)。要定义包含小数秒部分的列&#xff0c;请使用语法type_name(fsp)&…

软件质量保证计划_CMMI V2.0 精讲之“过程质量保证”

过程质量保证(PROCESS QUALITY ASSURANCE, PQA)目的&#xff1a;验证并改进已执行的过程和所产生的工作产品的质量。价值&#xff1a;增强过程使用和改进的一致性&#xff0c;以最大限度地提高业务效益和客户满意度。实践概述第1级PQA 1.1识别并解决过程和工作产品问题。第2级P…

mysql gzip_在mysql中存储GZIP:ed文本?

Is it a common thing for bigger applications and databases to GZIP text data before inserting it to the database?Ill guess that any full-text search on the actual text field will not be working before unzipping it again?解决方案Ive not seen this done muc…

html 分页_JQuery堪称完美的分页函数

演示效果&#xff1a;html部分&#xff08;引入jquery.js&#xff09;<!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>jQuery简单的分页插件</title> </head><link rel"stylesheet" href"…

mysql 8.0.12解压版安装教程_mysql 8.0.12 解压版安装教程

本文为大家分享了mysql 8.0.12 解压版安装教程&#xff0c;供大家参考&#xff0c;具体内容如下1、首先在官网上下载mysql8.0.12的压缩包&#xff1a;下载地址2、下载成功后解压到任意目录&#xff0c;比如我的是E:\download\mysql-8.0.12-winx64&#xff1b;3、配置环境变量&a…

简洁又快速地处理集合——Java8 Stream(下)

上一篇文章我讲解 Stream 流的基本原理&#xff0c;以及它与集合的区别关系&#xff0c;讲了那么多抽象的&#xff0c;本篇文章我们开始实战&#xff0c;讲解流的各个方法以及各种操作 没有看过上篇文章的可以先点击进去学习一下 简洁又快速地处理集合——Java8 Stream&#xf…

python入口函数的作用_python之函数中参数的作用域

学编程究竟学的是什么呢&#xff1f;在写文章的这几天也一直在思考这个问题——恐怕这也是接下来的几年一直会去思考的问题。这个问题的答案也会指导我的方法论&#xff0c;所以索性整顿一下。 现阶段我的回答是&#xff0c;发现需求&#xff0c;然后解决。 最大的需求无非是完…