针对Model类的代码修剪器
直接用Mybatis Generator生成的Model类大概是这样的
package com.spldeolin.demoapp.po; import java.util.Date;
import javax.persistence.*; @Table(name = "a_table")
public class ATable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; @Column(name = "inserted_at")
private Date insertedAt; @Column(name = "updated_at")
private Date updatedAt; @Column(name = "deleted_at")
private Date deletedAt; @Column(name = "a_name")
private String aName; /**
* @return id
*/
public Long getId() {
return id;
} /**
* @param id
*/
public void setId(Long id) {
this.id = id;
} /**
* @return inserted_at
*/
public Date getInsertedAt() {
return insertedAt;
} /**
* @param insertedAt
*/
public void setInsertedAt(Date insertedAt) {
this.insertedAt = insertedAt;
} /**
* @return updated_at
*/
public Date getUpdatedAt() {
return updatedAt;
} /**
* @param updatedAt
*/
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
} /**
* @return deleted_at
*/
public Date getDeletedAt() {
return deletedAt;
} /**
* @param deletedAt
*/
public void setDeletedAt(Date deletedAt) {
this.deletedAt = deletedAt;
} /**
* @return a_name
*/
public String getaName() {
return aName;
} /**
* @param aName
*/
public void setaName(String aName) {
this.aName = aName;
}
}
在项目配置了lombok的情况下,里面的getter和setter都是不必要的。同时,作为一个Model类,每一个的对象都是很有可能存入到Redis之类缓存里面的,所以为让每一个Model类都实现Serializable接口也是不错的注意。可以写一个“代码修剪器”应对这样的需求。
/**
* 代码修剪器,对通过代码生成器生成代码,进行简化<br>
* 这个工具类适合在Mybatis Generator使用完之后直接运行,不适合处理被开发人员修改的model类。
*
* @author Deolin
*/
public class CodeTrimmer { /**
* 【1】model类所在包的绝对路径
*/
private static final String MODEL_PACKAGE_ABSOLUTE_PATH =
""; public static void main(String[] args) {
/**
* 【2】需要被处理的model类名,不填则处理所有
*/
trimModels();
} private static void trimModels(String... targetFilenames) {
List<String> filenames = Arrays.asList(targetFilenames);
// 遍历文件
File folder = new File(MODEL_PACKAGE_ABSOLUTE_PATH);
List<File> files = new ArrayList<>();
interceptFiles(files, folder);
for (File file : files) {
if (filenames.size() != 0 && !filenames.contains(fileName(file))) {
continue;
}
try {
trimOneModel(file);
} catch (Exception ignored) {}
}
} private static void interceptFiles(List<File> files, File folder) {
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
interceptFiles(files, file);
} else if ("java".equals(fileExtension(file))) {
files.add(file);
} else {
// nothing
}
}
} private static void trimOneModel(File file) throws Exception {
// 读java文件
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
List<String> inputLines = new ArrayList<>();
String tempLine;
while ((tempLine = br.readLine()) != null) {
inputLines.add(tempLine);
}
br.close();
fr.close();
// 读完毕,开始处理
Collections.reverse(inputLines);
List<String> outputLines = new ArrayList<>();
boolean meetPublicClassEver = false;
boolean meetImportEver = false;
outputLines.add("}");
for (String inputLine : inputLines) {
// public class
if (StringUtils.trimToEmpty(inputLine).startsWith("public class")) {
outputLines.add("");
outputLines.add(" private static final long serialVersionUID = 1L;");
outputLines.add(addImplements(inputLine));
addTableAnnouncement(inputLine, outputLines);
addClassAnnotation(outputLines);
addImport(outputLines);
meetPublicClassEver = true;
continue;
}
// @Table
if (StringUtils.trimToEmpty(inputLine).startsWith("@Table")) {
// 遇到@Table则不要
continue;
}
// Getter, Setter 方法签名与方法体
if (isMethodSignOrBody(inputLine)) {
continue;
}
// 如果ignoreJavaDoc未被改变过(遇到类声明之前),且第一次遇到private,则都不再处理JavaDoc
if (!meetPublicClassEver) {
String lineContent = StringUtils.trimToEmpty(inputLine);
if (!lineContent.startsWith("private") && !lineContent.startsWith("*/") &&
!lineContent.startsWith("*") && !lineContent.startsWith("/**") &&
!lineContent.equals("")) {
throw new RuntimeException("java文件中存在非getter、setter方法,跳过处理。");
}
if (lineContent.startsWith("private")) {
meetPublicClassEver = true;
}
}
// Getter, Setter 方法注释
if (!meetPublicClassEver && isJavaDoc(inputLine)) {
continue;
}
outputLines.add(inputLine);
}
Collections.reverse(outputLines);
// 处理完毕,开始写。
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
for (String outputLine : outputLines) {
bw.write(outputLine + System.getProperty("line.separator"));
}
bw.close();
fw.close();
} private static boolean isMethodSignOrBody(String line) {
line = StringUtils.trimToEmpty(line);
if (StringUtils.startsWithIgnoreCase(line, "public")) {
if (!StringUtils.startsWithIgnoreCase(line, "public class")) {
return true;
}
}
if (StringUtils.startsWithIgnoreCase(line, "return")) {
return true;
}
if (StringUtils.startsWithIgnoreCase(line, "this.")) {
return true;
}
if (StringUtils.startsWithIgnoreCase(line, "}")) {
return true;
}
return false;
} private static boolean isJavaDoc(String line) {
line = StringUtils.trimToEmpty(line);
if (StringUtils.startsWithIgnoreCase(line, "/**") || StringUtils.startsWithIgnoreCase(line, "*") ||
StringUtils.startsWithIgnoreCase(line, "*/")) {
return true;
}
return false;
} private static void addClassAnnotation(List<String> lines) {
lines.add("@NoArgsConstructor");
lines.add("@EqualsAndHashCode");
lines.add("@ToString");
lines.add("@Setter");
lines.add("@Getter");
} private static void addImport(List<String> lines) {
lines.add("import lombok.ToString;");
lines.add("import lombok.Setter;");
lines.add("import lombok.NoArgsConstructor;");
lines.add("import lombok.Getter;");
lines.add("import lombok.EqualsAndHashCode;");
lines.add("import java.io.Serializable;");
} private static String addImplements(String line) {
line = StringUtils.stripEnd(line, "{");
line += "implements Serializable {";
return line;
} private static void addTableAnnouncement(String line, List<String> lines) {
String className = StringUtils.trimToEmpty(line).replace("public class ", "").replace(" {", "");
String tableAnnouncement = "@Table(name = \"" + camelToUnderline(className) + "\")";
lines.add(tableAnnouncement);
} private static String fileName(File file) {
String fileFullName = file.getName();
return fileFullName.substring(0, fileFullName.lastIndexOf("."));
} private static String fileExtension(File file) {
String fileFullName = file.getName();
return fileFullName.substring(fileFullName.lastIndexOf(".") + 1);
} private static String camelToUnderline(String camelCaseName) {
StringBuilder result = new StringBuilder();
if (camelCaseName != null && camelCaseName.length() > 0) {
result.append(camelCaseName.substring(0, 1).toLowerCase());
for (int i = 1; i < camelCaseName.length(); i++) {
char ch = camelCaseName.charAt(i);
if (Character.isUpperCase(ch)) {
result.append("_");
result.append(Character.toLowerCase(ch));
} else {
result.append(ch);
}
}
}
return result.toString();
} }
处理完的类中会有很多不必要的空行,只有在IDEA选中model包,Reformat Code即可。
最终效果是这样的。
package com.spldeolin.demoapp.po; import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString; @Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@Table(name = "a_table")
public class ATable implements Serializable { private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; @Column(name = "inserted_at")
private Date insertedAt; @Column(name = "updated_at")
private Date updatedAt; @Column(name = "deleted_at")
private Date deletedAt; @Column(name = "a_name")
private String aName; }
针对Model类的代码修剪器的更多相关文章
- iOS开发——model类模板(过滤null和ID)
说明:model类模板已默认过滤null值,附加特殊情况的关键字ID名的冲突(需手动去掉注释代码).MyMessageModel为示例的名字.可以自己随便起. 1.自己创建一个继承与N ...
- odoo 基于SQL View视图的model类
在做odoo的过程中,会涉及到多表的查询, 尤其是做报表的时候这种情况更甚,这样下来会做很多的关联,不是很方便.odoo提供了一种机制,即基于视图的model类.代码地址在这里. 具体过程如下: 1. ...
- .NET技术-1.0.使用反射、特性简化代码(验证Model类)
使用反射.特性简化代码 参考项目:利用反射验证Model类/AssemblyVerification 假设现在有一个学生类(Student) /// <summary> /// 学生类 / ...
- 使用mybatis-generator在自动生成Model类和Mapper文件
使用mybatis-generator插件可以很轻松的实现mybatis的逆向工程,即,能通过表结构自动生成对应的java类及mapper文件,可以大大提高工作效率,并且它提供了很多自定义的设置可以应 ...
- iOS开发之遍历Model类的属性并完善使用Runtime给Model类赋值
在上篇博客<iOS开发之使用Runtime给Model类赋值>中介绍了如何使用运行时在实体类的基类中添加给实体类的属性赋值的方法,这个方法的前提是字典的Key必须和实体类的Property ...
- iOS开发之使用Runtime给Model类赋值
本篇博客算是给网络缓存打个基础吧,本篇博客先给出简单也是最容易使用的把字典转成实体类的方法,然后在给出如何使用Runtime来给Model实体类赋值.本篇博客会介绍一部分,主要是字典的key与Mode ...
- 构建自己的PHP框架--实现Model类(3)
在之前的博客中,我们实现并完善了Model类的findOne方法,下面我们来实现其中的其他方法. 先来看findAll方法,这个方法和findOne很相似. public static functio ...
- 构建自己的PHP框架--实现Model类(1)
在之前的博客中,我们定义了ORM的接口,以及决定了使用PDO去实现.最后我们提到会有一个Model类实现ModelInterface接口. 现在我们来实现这个接口,如下: <?php names ...
- 为测试框架model类自动生成xml结果集
问题:有大量类似于theProductId这样名字的字符串需要转换成the_product_id这种数据库column名的形式. 思路:见到(见)大写字母(缝)就插入(插)一个“_”字符(针)进去,最 ...
随机推荐
- c#中冒泡排序算法描述
int temp = 0; int b = 0; int[] arr = { 23, 44, 66, 76, 98, 11, 3, 99, 7 };# region该段与排序无关Console.Wri ...
- wc命令——Linux系统高效数据统计工具
wc(world count)是一个统计文件字词,字节,行数的Linux命令,它可以帮我们非常方便的统计以上信息. 主要参数 常见参数如下: -c 统计字节数. -l 统计行数. -m 统计字符数.这 ...
- kubernetes第六章--如何访问pod
- ES6- - Map与Set
Map和Set 是 ES6 中新增的一种数据结构.Map为类似于Object的键值对结构,Set为成员唯一的类数组结构.以Map为例介绍两种数据结构的遍历方法.for...of var map = n ...
- JS权威指南读书笔记(五)
第十三章 Web浏览器中的JavaScript 1 在Html文档中嵌入客户端4种JS代码方法 a 内联方式,放置在<script>标签之间 b 放置在<script ...
- 设置body样式问题
如果我给body设置成一个宽高为200px的正方形,背景为红色,但是整个html也变成了红色,而且是整个浏览器屏幕都是红的,怎么来处理,如下 给html单独设置一个背景颜色,比如为白色#fff,在给b ...
- 设置 SQL*Plus 的运行环境
SQL*Plus 的运行环境是用来输入.执行 SQL*Plus 命令和显示返回结果的场所,设置合适的 SQL*Plus 运行环境,可以使 SQL*Plus 按照用户的要求运行和执行各种操作.set 命 ...
- 【sqoop】安装配置测试sqoop1
3.1.1 下载sqoop1:sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz 3.1.2 解压并查看目录: [hadoop@hadoop01 ~]$ tar -zxvf sq ...
- linux下载并安装redis
1 到http://redis.io/download 官网下下载最新稳定的redis 2 下载的redis安装包移动到要安装的位置 3 解压安装包 tar zxvf redis-3.0.5.tar. ...
- python的continue和break
continue:表示终止当前循环,开始下一次循环 break:终止所有循环 s = 0 while s < 3: s += 1 print(s) continue#'@' print(abc) ...