package org.yeshi.utils.generater.mybatis;
|
|
import java.beans.Transient;
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.io.PrintWriter;
|
import java.lang.annotation.Annotation;
|
import java.lang.reflect.Field;
|
import java.util.ArrayList;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
|
import org.dom4j.DocumentHelper;
|
import org.dom4j.io.OutputFormat;
|
import org.dom4j.io.XMLWriter;
|
import org.yeshi.utils.generater.entity.MybatisColumnData;
|
|
public class MyBatisMapperUtil {
|
private static String basePath = "D:/mybatis";
|
|
static {
|
// 创建工作目录
|
if (!new File(basePath).exists())
|
new File(basePath).mkdirs();
|
}
|
|
// 获取dao所在的包名
|
private static String getDaoPackageName(Class<?> bean) {
|
String name = bean.getName();
|
String[] ns = name.split("\\.");
|
if (ns.length > 2) {
|
String pks = "";
|
for (int i = 0; i < ns.length - 2; i++) {
|
pks += ns[i] + ".";
|
}
|
return pks + "dao";
|
}
|
return "";
|
}
|
|
private static String getMapperPackageName(Class<?> bean) {
|
String name = bean.getName();
|
String[] ns = name.split("\\.");
|
if (ns.length > 2) {
|
String pks = "";
|
for (int i = 0; i < ns.length - 2; i++) {
|
pks += ns[i] + ".";
|
}
|
return pks + "mapper";
|
}
|
return "";
|
}
|
|
private static List<MybatisColumnData> createMapperDaoQuery(int importPosition, StringBuffer buffer, Class<?> clz) {
|
List<MybatisColumnData> queryColumnData = new ArrayList<>();
|
|
buffer.append("public static class DaoQuery{");
|
buffer.append("\n\t");
|
Field[] fields = clz.getDeclaredFields();
|
Set<String> imports = new HashSet<>();
|
for (Field fd : fields) {
|
String property = fd.getName();
|
Annotation[] as = fd.getAnnotations();
|
String columnName = fd.getName();
|
for (Annotation a : as) {
|
if (a instanceof Transient || a instanceof org.springframework.data.annotation.Transient) {
|
property = null;
|
break;
|
}
|
if (a instanceof Column) {
|
columnName = ((Column) a).name();
|
}
|
}
|
|
String type = null;
|
if (property != null) {
|
//加
|
String genericType = fd.getGenericType().getTypeName();
|
if (genericType.indexOf(".") > -1) {
|
imports.add(genericType);
|
type = genericType.split("\\.")[genericType.split("\\.").length - 1];
|
} else {
|
type = genericType;
|
}
|
if (type.equalsIgnoreCase("Date")) {
|
String tempProperty = "min" + property.substring(0, 1).toUpperCase() + property.substring(1);
|
buffer.append(String.format("\tpublic %s %s;", type, tempProperty));
|
queryColumnData.add(new MybatisColumnData(columnName, tempProperty, type));
|
buffer.append("\n\t");
|
tempProperty = "max" + property.substring(0, 1).toUpperCase() + property.substring(1);
|
buffer.append(String.format("\tpublic %s %s;", type, tempProperty));
|
queryColumnData.add(new MybatisColumnData(columnName, tempProperty, type));
|
buffer.append("\n\t");
|
} else {
|
buffer.append(String.format("\tpublic %s %s;", type, property));
|
queryColumnData.add(new MybatisColumnData(columnName, property, type));
|
buffer.append("\n\t");
|
}
|
}
|
}
|
buffer.append("\tpublic long start;");
|
buffer.append("\n\t");
|
buffer.append("\tpublic int count;");
|
buffer.append("\n\t");
|
buffer.append("\tpublic List<String> sortList;");
|
buffer.append("\n\t");
|
buffer.append("}");
|
buffer.append("\n");
|
|
imports.add("org.apache.ibatis.annotations.Param");
|
for (String im : imports) {
|
buffer.insert(importPosition, "\n" + String.format("import %s;", im));
|
}
|
return queryColumnData;
|
}
|
|
public static void createMapper(Class<?> clz) {
|
// 生成mapper java文件
|
String pks = getDaoPackageName(clz);
|
StringBuffer buffer = new StringBuffer("package " + pks + ";");
|
int importPosition = buffer.length();
|
buffer.append("\n\n");
|
buffer.append("import " + clz.getName() + ";");
|
buffer.append("\n\n");
|
buffer.append(String.format("public interface %sMapper extends BaseMapper<%s> {", clz.getSimpleName(), clz.getSimpleName()));
|
buffer.append("\n\n\t");
|
|
//TODO 确定ID类型
|
buffer.append(String.format("%s selectByPrimaryKeyForUpdate(@Param(\"id\") Long id);",clz.getSimpleName()));
|
buffer.append("\n\n\t");
|
|
buffer.append(String.format("List<%s> list(@Param(\"query\") DaoQuery query);", clz.getSimpleName()));
|
buffer.append("\n\n\t");
|
buffer.append("long count(@Param(\"query\") DaoQuery query);");
|
buffer.append("\n\n\t");
|
|
List<MybatisColumnData> queryColumnData = createMapperDaoQuery(importPosition, buffer, clz);
|
|
|
buffer.append("}");
|
String daoName = String.format("%sMapper.java", clz.getSimpleName());
|
String daoPath = basePath + "/dao/" + daoName;
|
try {
|
if (!new File(basePath + "/dao/").exists())
|
new File(basePath + "/dao/").mkdirs();
|
if (!new File(daoPath).exists())
|
new File(daoPath).createNewFile();
|
FileOutputStream fos = new FileOutputStream(new File(daoPath));
|
PrintWriter pw = new PrintWriter(fos);
|
pw.write(buffer.toString().toCharArray());
|
pw.flush();
|
pw.close();
|
fos.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
/**
|
* 生成Mapper xml文件
|
*/
|
// 获取需要映射的列
|
List<AttributeColumnMap> keysList = new ArrayList<>();
|
Field[] fields = clz.getDeclaredFields();
|
for (Field fd : fields) {
|
Annotation[] as = fd.getAnnotations();
|
for (Annotation a : as) {
|
if (a instanceof Column) {
|
Column c = (Column) a;
|
keysList.add(new AttributeColumnMap(fd.getName(), c.name(), fd.getType().getName()));
|
}
|
}
|
}
|
String tableName = "";
|
Annotation[] as = clz.getAnnotations();
|
for (Annotation a : as) {
|
if (a instanceof Table) {
|
Table t = (Table) a;
|
tableName = t.value();
|
}
|
}
|
|
try {
|
String mapperName = String.format("%sMapper.xml", clz.getSimpleName());
|
String mapperPath = basePath + "/mapper/" + mapperName;
|
|
org.dom4j.Document document = DocumentHelper.createDocument();
|
document.addDocType("mapper", "-//mybatis.org//DTD Mapper 3.0//EN",
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd");
|
org.dom4j.Element root = document.addElement("mapper");
|
root.addAttribute("namespace", pks + "." + mapperName.replace(".xml", ""));
|
|
org.dom4j.Element resultMap = root.addElement("resultMap");
|
resultMap.addAttribute("id", "BaseResultMap");
|
resultMap.addAttribute("type", clz.getName());
|
|
AttributeColumnMap idKeys = getAttributeColumnMapByAttribute("id", keysList);
|
if (idKeys != null) {
|
org.dom4j.Element id = resultMap.addElement("id");
|
id.addAttribute("column", idKeys.column);
|
id.addAttribute("property", idKeys.attribute);
|
id.addAttribute("jdbcType", ColumnParseUtil.getJDBCType(idKeys.type));
|
}
|
|
for (AttributeColumnMap key : keysList) {
|
if (key.attribute.equalsIgnoreCase(idKeys.attribute) || ColumnParseUtil.getJDBCType(key.type) == null)
|
continue;
|
org.dom4j.Element result = resultMap.addElement("result");
|
result.addAttribute("column", key.column);
|
result.addAttribute("property", key.attribute);
|
result.addAttribute("jdbcType", ColumnParseUtil.getJDBCType(key.type));
|
}
|
|
// 属性值中包含实体
|
for (AttributeColumnMap key : keysList) {
|
if (ColumnParseUtil.getJDBCType(key.type) == null) {
|
Class<?> propertyClass = Class.forName(key.type);
|
String propertyMapper = getDaoPackageName(propertyClass) + "." + propertyClass.getSimpleName()
|
+ "Mapper";
|
org.dom4j.Element association = resultMap.addElement("association");
|
association.addAttribute("property", key.attribute);
|
association.addAttribute("column", key.column);
|
association.addAttribute("resultMap", propertyMapper + ".BaseResultMap");
|
key.attribute = key.attribute + ".id";
|
key.type = "java.lang.Long";
|
}
|
}
|
|
org.dom4j.Element sql = root.addElement("sql");
|
sql.addAttribute("id", "Base_Column_List");
|
sql.setText(getColumns(keysList));
|
|
org.dom4j.Element select = root.addElement("select");
|
select.addAttribute("id", "selectByPrimaryKey");
|
select.addAttribute("resultMap", "BaseResultMap");
|
select.addAttribute("parameterType", "java.lang.Long");
|
select.addText("select");
|
org.dom4j.Element include = select.addElement("include");
|
include.addAttribute("refid", "Base_Column_List");
|
select.addText(String.format(" from %s where %s = #{%s,jdbcType=BIGINT}", tableName, idKeys.column,
|
idKeys.attribute));
|
|
|
select = root.addElement("select");
|
select.addAttribute("id", "selectByPrimaryKeyForUpdate");
|
select.addAttribute("resultMap", "BaseResultMap");
|
select.addAttribute("parameterType", "java.lang.Long");
|
select.addText("select");
|
include = select.addElement("include");
|
include.addAttribute("refid", "Base_Column_List");
|
select.addText(String.format(" from %s where %s = #{%s,jdbcType=BIGINT} for update", tableName, idKeys.column,
|
idKeys.attribute));
|
|
//添加sql
|
sql = root.addElement("sql");
|
sql.addAttribute("id", "listWhereSQL");
|
|
|
for (MybatisColumnData columnData : queryColumnData) {
|
org.dom4j.Element ife = sql.addElement("if");
|
ife.addAttribute("test", String.format("query.%s!=null", columnData.getProperty()));
|
if (columnData.getType().equalsIgnoreCase("Date")) {
|
if (columnData.getProperty().startsWith("min"))
|
ife.addText(String.format("AND %s >= #{query.%s}", columnData.getColumn(), columnData.getProperty()));
|
else
|
ife.addText(String.format("AND #{query.%s} > %s", columnData.getProperty(), columnData.getColumn()));
|
} else {
|
ife.addText(String.format("AND %s = #{query.%s}", columnData.getColumn(), columnData.getProperty()));
|
}
|
}
|
//批量查询
|
select = root.addElement("select");
|
select.addAttribute("id", "list");
|
select.addAttribute("resultMap", "BaseResultMap");
|
select.addText("select");
|
include = select.addElement("include");
|
include.addAttribute("refid", "Base_Column_List");
|
select.addText(String.format(" from %s where 1=1", tableName));
|
|
include = select.addElement("include");
|
include.addAttribute("refid", "listWhereSQL");
|
|
org.dom4j.Element ife = select.addElement("if");
|
ife.addAttribute("test", "query.sortList!=null");
|
org.dom4j.Element foreach = ife.addElement("foreach");
|
foreach.addAttribute("collection", "query.sortList");
|
foreach.addAttribute("item", "item");
|
foreach.addAttribute("open", " order by ");
|
foreach.addAttribute("separator", ",");
|
foreach.addText(" #{item}");
|
select.addText("limit #{query.start},#{query.count}");
|
|
//批量计数
|
select = root.addElement("select");
|
select.addAttribute("id", "count");
|
select.addAttribute("resultType", "java.lang.Long");
|
select.addText(String.format(" select count(*) from %s where 1=1", tableName));
|
include = select.addElement("include");
|
include.addAttribute("refid", "listWhereSQL");
|
|
|
org.dom4j.Element delete = root.addElement("delete");
|
delete.addAttribute("id", "deleteByPrimaryKey");
|
delete.addAttribute("parameterType", "java.lang.Long");
|
delete.setText(String.format("delete from %s where %s = #{%s,jdbcType=BIGINT}", tableName, idKeys.column,
|
idKeys.attribute));
|
|
org.dom4j.Element insert = root.addElement("insert");
|
insert.addAttribute("id", "insert");
|
insert.addAttribute("parameterType", clz.getName());
|
insert.addAttribute("useGeneratedKeys", "true");
|
insert.addAttribute("keyProperty", "id");
|
StringBuffer text = new StringBuffer();
|
text.append(String.format("insert into %s (", tableName));
|
text.append(getColumns(keysList));
|
text.append(")");
|
text.append(" values (");
|
for (AttributeColumnMap acm : keysList)
|
text.append(getKeyPair(acm)).append(",");
|
text.deleteCharAt(text.length() - 1);
|
text.append(")");
|
insert.setText(text.toString());
|
|
org.dom4j.Element insertSelective = root.addElement("insert");
|
insertSelective.addAttribute("id", "insertSelective");
|
insertSelective.addAttribute("parameterType", clz.getName());
|
insertSelective.addAttribute("useGeneratedKeys", "true");
|
insertSelective.addAttribute("keyProperty", "id");
|
insertSelective.addText("insert into " + tableName);
|
|
org.dom4j.Element trim = insertSelective.addElement("trim");
|
trim.addAttribute("prefix", "(");
|
trim.addAttribute("suffix", ")");
|
trim.addAttribute("suffixOverrides", ",");
|
for (AttributeColumnMap acm : keysList) {
|
org.dom4j.Element iff = trim.addElement("if");
|
iff.addAttribute("test",
|
(acm.attribute.indexOf(".") > -1 ? acm.attribute.split("\\.")[0] : acm.attribute) + " != null");
|
iff.setText(acm.column + ",");
|
}
|
|
insertSelective.addText("values");
|
|
trim = insertSelective.addElement("trim");
|
trim.addAttribute("prefix", "(");
|
trim.addAttribute("suffix", ")");
|
trim.addAttribute("suffixOverrides", ",");
|
for (AttributeColumnMap acm : keysList) {
|
org.dom4j.Element iff = trim.addElement("if");
|
iff.addAttribute("test",
|
(acm.attribute.indexOf(".") > -1 ? acm.attribute.split("\\.")[0] : acm.attribute) + " != null");
|
iff.setText(getKeyPair(acm) + ",");
|
}
|
|
// update
|
|
org.dom4j.Element update = root.addElement("update");
|
update.addAttribute("id", "updateByPrimaryKey");
|
update.addAttribute("parameterType", clz.getName());
|
text = new StringBuffer(String.format("update %s set ", tableName));
|
for (AttributeColumnMap acm : keysList) {
|
if (acm.attribute.equalsIgnoreCase(idKeys.attribute))
|
continue;
|
text.append(String.format("%s = #{%s,jdbcType=%s}", acm.column, acm.attribute,
|
ColumnParseUtil.getJDBCType(acm.type))).append(",");
|
}
|
text.deleteCharAt(text.length() - 1);
|
|
text.append(String.format(" where %s = #{%s,jdbcType=%s}", idKeys.column, idKeys.attribute,
|
ColumnParseUtil.getJDBCType(idKeys.type)));
|
|
update.setText(text.toString());
|
|
// updateSelective
|
org.dom4j.Element updateSelective = root.addElement("update");
|
updateSelective.addAttribute("id", "updateByPrimaryKeySelective");
|
updateSelective.addAttribute("parameterType", clz.getName());
|
updateSelective.addText("update " + tableName);
|
org.dom4j.Element set = updateSelective.addElement("set");
|
|
for (AttributeColumnMap acm : keysList) {
|
if (acm.attribute.equalsIgnoreCase(idKeys.attribute))
|
continue;
|
org.dom4j.Element iff = set.addElement("if");
|
iff.addAttribute("test",
|
(acm.attribute.indexOf(".") > -1 ? acm.attribute.split("\\.")[0] : acm.attribute) + " != null");
|
iff.setText(acm.column + "=" + getKeyPair(acm) + ",");
|
}
|
|
updateSelective.addText(String.format(" where %s = #{%s,jdbcType=%s}", idKeys.column, idKeys.attribute,
|
ColumnParseUtil.getJDBCType(idKeys.type)));
|
|
// 创建mapper文件
|
|
if (!new File(basePath + "/mapper/").exists())
|
new File(basePath + "/mapper/").mkdirs();
|
if (!new File(mapperPath).exists())
|
new File(mapperPath).createNewFile();
|
|
XMLWriter writer = new XMLWriter(new FileOutputStream(new File(mapperPath)),
|
OutputFormat.createPrettyPrint());
|
writer.setEscapeText(false);// 字符是否转义,默认true
|
writer.write(document);
|
writer.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
private static AttributeColumnMap getAttributeColumnMapByAttribute(String attributeName,
|
List<AttributeColumnMap> list) {
|
for (AttributeColumnMap acm : list)
|
if (acm.attribute.equalsIgnoreCase(attributeName))
|
return acm;
|
return null;
|
}
|
|
private static String getColumns(List<AttributeColumnMap> list) {
|
String columns = "";
|
for (AttributeColumnMap map : list)
|
columns += map.column + ",";
|
return columns.length() > 0 ? columns.substring(0, columns.length() - 1) : columns;
|
}
|
|
private static String getKeyPair(AttributeColumnMap map) {
|
return String.format("#{%s,jdbcType=%s}", map.attribute, ColumnParseUtil.getJDBCType(map.type));
|
}
|
|
}
|
|
class AttributeColumnMap {
|
String attribute;
|
String column;
|
String type;
|
|
public AttributeColumnMap(String attribute, String column, String type) {
|
this.attribute = attribute;
|
this.column = column;
|
this.type = type;
|
}
|
|
public AttributeColumnMap() {
|
|
}
|
}
|