针对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名的形式. 思路:见到(见)大写字母(缝)就插入(插)一个“_”字符(针)进去,最 ...
随机推荐
- 易百教程人工智能python修正-人工智能数据准备-标记数据
我们已经知道,某种格式的数据对于机器学习算法是必需的. 另一个重要的要求是,在将数据作为机器学习算法的输入发送之前,必须正确标记数据. 例如,如果所说的分类,那么数据上会有很多标记. 这些标记以文字, ...
- z7z8记录
http://www.ypppt.com/ ppt模板地址
- 【转载】Javascript使用Math.floor方法向下取整
在Javascript的数值运算中,很多时候需要对最后计算结果向下取整,Math.floor是javascript中对计算结果向下取整的函数,它总是将数值向下舍入为最接近的整数.此外Math.ceil ...
- 1+x学习日志——js获取随机颜色的几种实现方式
因为学习时间比较紧,所以也没多少时间发博客了.后续会慢慢补齐的,下面是代码 /// function randomColor(){ var r = parseInt(Math.random() * 2 ...
- 多个echarts图自适应屏幕大小
当一个echarts图时,可以这样做 //下面my_charts是html中echarts的ID var myChart= echarts.init(document.getElementById(& ...
- JAVA基础之ServletContext应用
创建一个登陆的界面,并且统计次数! 导入jar包; 1. driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/java0603?u ...
- SVN commit:remains in tree-conflict错误的解决办法
转自:https://chenjinbo1983.iteye.com/blog/2005123 昨天在提交一个新类包的时候,出错了,重新提交了几次也不行. 错误是:Aborting commit: ‘ ...
- 【代码片段】定时记录CPU使用率并保存为CSV
原文链接 : [https://blog.zhoutao123.com/#/blog/article/64])(https://blog.zhoutao123.com/#/blog/article/6 ...
- ceph 剔除osd
先将osd.2移出集群 root@ceph-monster:~# ceph osd out osd.2 marked out osd.2. root@ceph-monster:~# ceph osd ...
- 2013.4.26 - KDD第八天
下午上Android课,我看中秋也选这个课了,然后在上半节的时候速补了一下秦海龙师兄的那篇文章.中间休息的时候窜到了中秋那里,然后讨论了半节课现在的情况. 现在的情况是这样的: 中 秋开始是没有进行主 ...