一般我们的某个数据库表对象model,java bean对象如下:


package com.xxx.message.model;

import com.middol.common.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
* 邮件等消息发送历史表
*
* @author xxxx
*/
@Entity
@Table(name = "T_messageHistory")
@Data
@EqualsAndHashCode(callSuper=true)
public class MessageHistory extends BaseModel {

/**
* 工厂id
*/
@Column(name = "factoryId")
private String factoryId;

/**
* 原有的 messageId
*/
@Column(name = "messageId")
private String messageId;

/**
* 接收方
*/
@Column(name = "receiver")
private String receiver;

/**
* 抄送方
*/
@Column(name = "copy")
private String copy;

/**
* 标题
*/
@Column(name = "subject")
private String subject;

/**
* 内容
*/
@Column(name = "content", columnDefinition = "nvarchar(2000)")
private String content;

/**
* 发送类型
*/
@Column(name = "sendType")
private String sendType;
}

特殊情况下我们可能需要获取这个类的属性注释,比如JPA生成的表没有注释,我们希望通过java类中的属性注释来更新一下表中字段注释。

这里可以通过jdk自带的 tools.jar工具包进行获取,主要类似于生成javadoc文档那样。

pom.xml文件中导入:

        <dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/tools.jar</systemPath>
</dependency>

systemPath 可以指向磁盘具体的路径,tools.jar一般在 JAVA_HOM/lib 下。

具体测试类如下:


package com.xxx.doc;

import cn.hutool.core.util.ReflectUtil;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.RootDoc;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
* 获取某一个java文件代码中属性对应的注释
*
* @author guzt
*/
public class Doclet {

public static Logger logger = LoggerFactory.getLogger(Doclet.class);

private static RootDoc rootDoc;
private String javaBeanFilePath;

public static boolean start(RootDoc root) {
rootDoc = root;
return true;
}

public Doclet(String javaBeanFilePath) {
this.javaBeanFilePath = javaBeanFilePath;
}

public ModelClassDocVO exec() {
ModelClassDocVO modelClassDocVO = new ModelClassDocVO();
com.sun.tools.javadoc.Main.execute(new String[]{"-doclet", Doclet.class.getName(), "-docletpath",
Doclet.class.getResource("/").getPath(), "-encoding", "utf-8", javaBeanFilePath});
ClassDoc[] classes = rootDoc.classes();

if (classes == null || classes.length == 0) {
logger.warn(javaBeanFilePath + " 无ClassDoc信息");
return modelClassDocVO;
}

List<FildEntry> entrys = Lists.newArrayList();
ClassDoc classDoc = classes[0];
// 获取类的名称
modelClassDocVO.setModelClassName(classDoc.name());
// 获取类的注释
String classComment = ReflectUtil.getFieldValue(classDoc, "documentation").toString();
String spitStr = "\n";
for (String msg : classComment.split(spitStr)) {
if (!msg.trim().startsWith("@") && msg.trim().length() > 0) {
modelClassDocVO.setModelCommentText(msg);
break;
}
}
// 获取属性名称和注释
FieldDoc[] fields = classDoc.fields(false);
for (FieldDoc field : fields) {
entrys.add(new FildEntry(field.name(), field.type().typeName(), field.commentText()));
}

modelClassDocVO.setFildEntryList(entrys);
return modelClassDocVO;
}

// 测试一下
public static void main(String[] args) {
Doclet doclet = new Doclet(
"E:\\IDEA_HOME\\middol\\parent\\message\\src\\main\\java\\com\\middol\\message\\model\\MessageHistory.java");
ModelClassDocVO modelClassDocVO = doclet.exec();
logger.info("类注释:" + modelClassDocVO.getModelCommentText());
logger.info("属性字段注释如下:");
modelClassDocVO.getFildEntryList().forEach(System.out::println);
}
}

测试结果如下:

14:09:23.867 [main] INFO com.middol.doc.Doclet - 类注释: 邮件等消息发送历史表
14:09:23.871 [main] INFO com.middol.doc.Doclet - 属性字段注释如下:
Entry{fName='factoryId', fType='String', fExplain='工厂id'}
Entry{fName='messageId', fType='String', fExplain='原有的 messageId'}
Entry{fName='receiver', fType='String', fExplain='接收方'}
Entry{fName='copy', fType='String', fExplain='抄送方'}
Entry{fName='subject', fType='String', fExplain='标题'}
Entry{fName='content', fType='String', fExplain='内容'}
Entry{fName='sendType', fType='String', fExplain='发送类型'}

上述测试类需要用到的 POJO对象如下:

package com.xxx.doc;

/**
* 属性字段对应注释
*
* @author guzt
*/
public class FildEntry {

/**
* 参数名
*/
private String fName;
/**
* 类型
*/
private String fType;
/**
* 说明
*/
private String fExplain;

public FildEntry(String fName, String fType, String fExplain) {
super();
this.fName = fName;
this.fType = fType;
this.fExplain = fExplain;
}

@Override
public String toString() {
return "Entry{" +
"fName='" + fName + '\'' +
", fType='" + fType + '\'' +
", fExplain='" + fExplain + '\'' +
'}';
}

public String getfName() {
return fName;
}

public void setfName(String fName) {
this.fName = fName;
}

public String getfType() {
return fType;
}

public void setfType(String fType) {
this.fType = fType;
}

public String getfExplain() {
return fExplain;
}

public void setfExplain(String fExplain) {
this.fExplain = fExplain;
}
}


package com.xxx.doc;

import java.util.List;

/**
* model 类字段注释
* @author guzt
*/
public class ModelClassDocVO {


private String modelTableName;

private String modelClassName;

private String modelCommentText;

private List<FildEntry> fildEntryList;


public String getModelTableName() {
return modelTableName;
}

public void setModelTableName(String modelTableName) {
this.modelTableName = modelTableName;
}

public String getModelClassName() {
return modelClassName;
}

public void setModelClassName(String modelClassName) {
this.modelClassName = modelClassName;
}

public String getModelCommentText() {
return modelCommentText;
}

public void setModelCommentText(String modelCommentText) {
this.modelCommentText = modelCommentText;
}

public List<FildEntry> getFildEntryList() {
return fildEntryList;
}

public void setFildEntryList(List<FildEntry> fildEntryList) {
this.fildEntryList = fildEntryList;
}

@Override
public String toString() {
return "ModelClassDocVO{" +
"modelClassName='" + modelClassName + '\'' +
", modelCommentText='" + modelCommentText + '\'' +
", fildEntryList=" + fildEntryList +
'}';
}
}