数据库和实体类中的字段名称是首字母大写,JSONObject.toJSONString转换成字符串输出后,首字母变小写
解决办法:
把MyBatisGenerator 生成的数据库实体类的字段名称,按照数据库字段原样输出首字母大写,然后加上 @JsonProperty(value= "字段名称") 指定输出名称。
1、自定义mybaits插件,把MyBatisGenerator 生成的数据库实体类和mapper.xml文件的字段名称,按照数据库字段原样输出首字母大写。
并且在自动生成实体类属性加上 @JsonProperty(value= "字段名称") 指定输出名称。
import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.*;
import org.mybatis.generator.internal.util.StringUtility;
import java.text.SimpleDateFormat;
import java.util.*;
public class LombokPlugin extends PluginAdapter {
Map<String,String> columnMap = new HashMap<>();
@Override
public boolean validate(List<String> list) {
return true;
}
/**
* 为实体添加lombok的注解
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
//添加domain的import
//SpringBoot默认使用Jackson,所以用 @JsonProperty ,指定返回JSON字段名称
topLevelClass.addImportedType("com.fasterxml.jackson.annotation.JsonProperty");
topLevelClass.addImportedType("io.swagger.annotations.ApiModelProperty");
topLevelClass.addImportedType("lombok.Data");
topLevelClass.addImportedType("lombok.Builder");
topLevelClass.addImportedType("lombok.NoArgsConstructor");
topLevelClass.addImportedType("lombok.AllArgsConstructor");
//添加domain的注解
topLevelClass.addAnnotation("@Data");
topLevelClass.addAnnotation("@Builder");
topLevelClass.addAnnotation("@NoArgsConstructor");
topLevelClass.addAnnotation("@AllArgsConstructor");
//添加domain的注释
topLevelClass.addJavaDocLine("/**");
topLevelClass.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
topLevelClass.addJavaDocLine("*/");
return true;
}
/**
* 为实体类字段添加注释
* @param field
* @param topLevelClass
* @param introspectedColumn
* @param introspectedTable
* @param modelClassType
* @return
*/
@Override
public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
field.addJavaDocLine("/**");
String remarks = introspectedColumn.getRemarks();
if (StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
field.addJavaDocLine(" * " + remarkLine);
}
}
field.addJavaDocLine(" */");
// System.out.println(introspectedColumn);
// System.out.println(introspectedColumn.getActualColumnName());
// System.out.println(remarks);
//替换为数据库原生字段
field.setName(introspectedColumn.getActualColumnName());
//保存替换的对应map
columnMap.put(introspectedColumn.getJavaProperty(),introspectedColumn.getActualColumnName());
//生成字段注解
field.addAnnotation("@ApiModelProperty(value = \"" + remarks + "\")");
//SpringBoot默认使用Jackson,所以用 @JsonProperty ,指定返回JSON字段名称
field.addAnnotation("@JsonProperty(value= \"" + introspectedColumn.getActualColumnName() + "\")");
return true;
}
/**
* mapper.java的注释
* @param interfaze
* @param introspectedTable
* @return
*/
@Override
public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
// super.clientGenerated(interfaze, introspectedTable);
//Mapper文件的注释
interfaze.addJavaDocLine("/**");
interfaze.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
interfaze.addJavaDocLine("*/");
return true;
}
@Override
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
XmlElement rootElement = document.getRootElement();
changeJdbcTypefromXmlElement(rootElement);
// removeJdbcTypefromXmlElement(rootElement);
return super.sqlMapDocumentGenerated(document, introspectedTable);
}
/**
* 更换sqlMap 为数据库字段
*
* @author Aylven
* @date 2020-04-06
*/
private void changeJdbcTypefromXmlElement(XmlElement element) {
List<VisitableElement> visitableElements = element.getElements();
VisitableElement visitableElement;
for (int i = 0; i < visitableElements.size(); i++) {
visitableElement = visitableElements.get(i);
if (visitableElement instanceof XmlElement) {
if(((XmlElement) visitableElement).getName().equals("resultMap")){
//如果是resultMap的话,替换为数据库原生字段
XmlElement resultMapElem = getXmlElement((XmlElement) visitableElement,"resultMap");
visitableElements.set(i, resultMapElem);
}else{
changeJdbcTypefromXmlElement((XmlElement) visitableElement);
}
} else if (visitableElement instanceof TextElement) {
String content = ((TextElement) visitableElement).getContent();
if (content.contains("jdbcType")) {
for(Map.Entry<String,String> entry:columnMap.entrySet()){
String key = entry.getKey();
String value = entry.getValue();
//替换为数据库原生字段
content = content.replaceAll(key+",", value+",");
}
TextElement textElement = new TextElement(content);
visitableElements.set(i, textElement);
}
}
}
}
//如果是resultMap的话,替换为数据库原生字段
private XmlElement getXmlElement(XmlElement element,String elementName){
XmlElement resultMapElem = new XmlElement(elementName);
List<VisitableElement> visitableElements = element.getElements();
//添加原来的属性
List<Attribute> attr = element.getAttributes();
Attribute attrC;
for (int x = 0; x < attr.size(); x++) {
//这是原来的子元素 的子元素
attrC = attr.get(x);
attrC.getName();
//新建子属性
Attribute attributeNew = new Attribute(attrC.getName(),attrC.getValue());
resultMapElem.addAttribute(attributeNew);
}
//添加原来的子元素
VisitableElement visitableElement;
for (int i = 0; i < visitableElements.size(); i++) {
//这是原来的子元素
visitableElement = visitableElements.get(i);
if(visitableElement instanceof XmlElement){
XmlElement visitableElementXML = (XmlElement) visitableElement;
//新建子元素
XmlElement elementNew = new XmlElement(visitableElementXML.getName());
List<Attribute> attributes = visitableElementXML.getAttributes();
Attribute attrChild;
for (int x = 0; x < attributes.size(); x++) {
//这是原来的子元素 的子元素
attrChild = attributes.get(x);
attrChild.getName();
//替换为数据库原生字段
String value = attrChild.getValue();
if(attrChild.getName().equals("property")){
for(Map.Entry<String,String> entry:columnMap.entrySet()){
if(value.equals(entry.getKey())){
//替换字段名称
value = value.replaceAll(value, entry.getValue());
break;
}
}
}
//新建子属性
Attribute attributeNew = new Attribute(attrChild.getName(),value);
elementNew.addAttribute(attributeNew);
}
resultMapElem.addElement(elementNew);
}
}
return resultMapElem;
}
/**
* 去掉sqlMap中变量的jdbcType
*
* @author Aylven
* @date 2020-04-06
*/
private void removeJdbcTypefromXmlElement(XmlElement element) {
List<VisitableElement> visitableElements = element.getElements();
VisitableElement visitableElement;
for (int i = 0; i < visitableElements.size(); i++) {
visitableElement = visitableElements.get(i);
if (visitableElement instanceof XmlElement) {
removeJdbcTypefromXmlElement((XmlElement) visitableElement);
} else if (visitableElement instanceof TextElement) {
String content = ((TextElement) visitableElement).getContent();
if (content.contains("jdbcType")) {
TextElement textElement = new TextElement(content.replaceAll(",jdbcType=\\w+}", "}"));
visitableElements.set(i, textElement);
}
}
}
}
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
//不生成getter
return false;
}
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
//不生成setter
return false;
}
private String date2Str(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
return sdf.format(date);
}
}
mybatis使用该自定义插件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!--自定义插件-->
<plugin type="cn.m.www.common.mybatis.LombokPlugin" >
<property name="hasLombok" value="true"/>
</plugin>
</context>
</generatorConfiguration>
运行 MyBatisGenerator ,自动生成实体类和mapper文件。
最后使用 JSONObject.toJSONString() ,获取的字符串首字母按照实体类输出