针对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名的形式. 思路:见到(见)大写字母(缝)就插入(插)一个“_”字符(针)进去,最 ...
随机推荐
- elasticsearch授权访问
1.search guard插件 https://www.cnblogs.com/shifu204/p/6376683.html 2.Elasticsearch-http-basic 不支持es5,忽 ...
- Windows10 安装VirtualBox出现2502、2503错误解决方法
先来到VirtualBox的下载位置,如图,笔者位置在D:/vb文件夹下 下载目录 然后按住win+R(win就是左下角ctrl和alt之间那个键),输入cmd,然后回车 如果在C盘的话,就直接c ...
- 什么是SAP Graph
今年九月份刚刚过去的SAP TechEd Las Vegas会议上,SAP CTO Juergen Mueller向外界宣布了SAP一些持续进行的技术创新和改进,其中之一就是SAP Graph,大家可 ...
- Laravel5.6---搜索查询 自带paginate()分页 get传参
laravel的paginate()分页,如果用post传参,点击第二页时会默认使用get,就会返回原始数据了 需要把查询数据get方式也放到paginate()分页参数中 一.路由 Route::g ...
- react-router-dom下的BrowserRouter和HashRouter
奇思妙想的
- SQL SERVER-Extendevent捕获执行慢的语句
USE MASTER; GO /* Conditionally drop the session if it already exists */ IF EXISTS (SELECT * FROM sy ...
- linux ssh_config和sshd_config配置文件学习
在远程管理linux系统基本上都要使用到ssh,原因很简单:telnet.FTP等传输方式是以明文传送用户认证信息,本质上是不安全的,存在被网络窃听的危险.SSH(Secure Shell)目前较可 ...
- Luogu P1970 花匠
Luogu P1970 花匠 本质上就是找最长的波浪序列. 因为考虑到第一个必选,所以可以让$lst=h[1]$. 此外,注意到$n=1$是要特判,其他情况下显然$ans\geq 2$,所以把$dir ...
- [software test - 001] Why we need software test?
/* This is a conclusion about the software testing job. */ /* Scope: middle level software tasks, ...
- “挂起”bug处理执行方案
目的:避免bug状态改为挂起后,就无人问津,导致一直未得到解决.因而影响用户的使用与产品质量较差.