Java编写生成mybatis xml文件、Dao文件、实体类和DTO
目前现在有很多的mybatis自动生成代码的工具,典型的mybatis-generator插件,经配置生成的文件直接便可以使用了。
确实非常的方便和实用。但是在日常的开发当中,为了使项目简洁、清晰。让人一看就明白,排起错来也是相当顺手。
如果使用插件生成的文件,在业务上出了问题,那排查问题就复杂了,想改的话也不好改,故自己做了一套简单的代码生成工具,
仅仅只做简单的新增和查询操作。至于删除和更新在日常的项目中,一般都会有特殊的业务场景,故最好还是自己去写,防止出现
意外情况。本工具使用freemaker模版生成。具体代码如下:
很简单pom文件引入jdbc jar包,ftl文件放在resources目录下。
定义实体:
public class Data {
private String nativeColumn;
private String convertColumn;
public String getNativeColumn() {
return nativeColumn;
}
public void setNativeColumn(String nativeColumn) {
this.nativeColumn = nativeColumn;
}
public String getConvertColumn() {
return convertColumn;
}
public void setConvertColumn(String convertColumn) {
this.convertColumn = convertColumn;
}
}
public class DataStrute {
private String type;
private String column;
private String pColumn;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getColumn() {
return column;
}
public void setColumn(String column) {
this.column = column;
}
public String getpColumn() {
return pColumn;
}
public void setpColumn(String pColumn) {
this.pColumn = pColumn;
}
}
FreeMaker 渲染并转成文件工具类
public class FreeMakerToXML {
private static Configuration configuration = null;
private static Template t = null;
public static final String xmlTempPath = "xmlTemp.ftl";
public static final String daoTempPath = "daoTemp.ftl";
public static final String pojoTempPath = "pojoTemp.ftl";
public static final String dtoTempPath = "dtoTemp.ftl";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
configuration.setClassForTemplateLoading(FreeMakerToXML.class, "/");
//FTL文件所存在的位置,我的只能放在与java相同的包下
}
public static void createWord(Map<String,Object> dataMap,String fileName,String templte){
File outFile = new File("/Users/jason_moo/Downloads/helper/"+fileName); //生成文件的路径
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
t = configuration.getTemplate(templte); //文件名
t.process(dataMap, out, ObjectWrapper.BEANS_WRAPPER);
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
获取数据库信息并将表结构生成对应的文件到不同目录下
public class GenerateUtils {
private static String driverClass = "com.mysql.jdbc.Driver";
private static String connectionURL = "jdbc:mysql://127.0.0.1:3306/test";
private static String userName="root";
private static String passwd = "********";
private static String packetageDTO = "com.****.dto";
private static String packetageDAO = "com.****.dao";
private static String packetagePojo = "com.****.entities";
public static void main(String[] args) {
// 第二个参数穿入null代表将库下所有的表都生成相应文件,传入具体表明可生成具体表对应的文件
getData(getConnection(),null);
}
public static Connection getConnection(){
Connection conn = null;
try {
Class.forName(driverClass); //classLoader,加载对应驱动
conn = (Connection) DriverManager.getConnection(connectionURL, userName, passwd);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static String underlineToCamel(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (c == '_') {
if (++i < len) {
sb.append(Character.toUpperCase(param.charAt(i)));
}
} else {
sb.append(c);
}
}
return sb.toString();
}
public static void getData(Connection conn, String tableName){
try {
DatabaseMetaData databaseMetaData = conn.getMetaData();
tableName = tableName != null ? tableName : "%";
ResultSet colRet = databaseMetaData.getTables(null, "%", tableName, new String[] {"TABLE"});
while(colRet.next()) {
Map<String, Object> dataMap = new HashMap();
String name = colRet.getString("TABLE_NAME");
String camelCase = underlineToCamel(name);
String className =convert(camelCase);
dataMap = getColumnsData(databaseMetaData, dataMap, name,camelCase);
dataMap.put("tableName",name);
dataMap.put("dtoNameLow", camelCase + "Dto");
dataMap.put("entityName", className);
dataMap.put("entityType",packetagePojo+"."+className);
dataMap.put("dtoName", className +"Dto");
dataMap.put("dtoType",packetageDTO+"."+className +"Dto");
dataMap.put("packetageDTO",packetageDTO);
dataMap.put("packetageDAO",packetageDAO);
dataMap.put("packetagePojo",packetagePojo);
FreeMakerToXML.createWord(dataMap,"xml/"+className+"DAO.xml", FreeMakerToXML.xmlTempPath);
FreeMakerToXML.createWord(dataMap,"dao/"+className+"DAO.java", FreeMakerToXML.daoTempPath);
FreeMakerToXML.createWord(dataMap,"pojo/"+className+".java", FreeMakerToXML.pojoTempPath);
FreeMakerToXML.createWord(dataMap,"dto/"+className+"Dto.java", FreeMakerToXML.dtoTempPath);
}
}catch (SQLException e){
e.getErrorCode();
}
}
private static Map<String, Object> getColumnsData(DatabaseMetaData databaseMetaData, Map<String, Object> dataMap, String name,String camelCase) throws SQLException {
ResultSet columns = databaseMetaData.getColumns(null,"%", name,"%");
List<Data> dataList = new ArrayList<>();
List<DataStrute> dataStruteList = new ArrayList<>();
while(columns.next()) {
String column = columns.getString("COLUMN_NAME");
Data data = new Data();
data.setNativeColumn(column);
String camelClonmn = underlineToCamel(column);
data.setConvertColumn(camelClonmn);
data.setParam("#{"+camelCase+"Dto" +"."+ camelClonmn+"}");
dataList.add(data);
String columnType = columns.getString("TYPE_NAME");
String convertType = getJavaType(columnType);
DataStrute dataStrute = new DataStrute();
dataStrute.setColumn(underlineToCamel(column));
dataStrute.setpColumn(convert(camelClonmn));
dataStrute.setType(convertType);
dataStruteList.add(dataStrute);
dataMap.put("columnList",dataList);
dataMap.put("dataStrutes",dataStruteList);
}
return dataMap;
}
private static String getJavaType(String columnType) {
String convertType = null;
switch (columnType){
case "BIGINT" :
convertType = "Long";
break;
case "VARCHAR":
convertType = "String";
break;
case "TIMESTAMP":
convertType = "Date";
break;
case "TINYINT":
case "INT":
convertType = "Integer";
break;
case "DECIMAL":
convertType = "Double";
break;
default:
convertType = "String";
}
return convertType;
}
private static String convert(String nativeString){
String camelCase = underlineToCamel(nativeString);
char[] cs=camelCase.toCharArray();
cs[0]-=32;
return String.valueOf(cs);
}
}
生成事例如下
xmltemp.ftl
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="${packetageDAO}.${entityName}DAO" >
<resultMap id="${dtoName}ResultMap" type="${dtoType}" >
<#list columnList as column>
<#if column_index = 0>
<id column="id" property="id"/>
<#else>
<result column="${column.nativeColumn}" property="${column.convertColumn}"/>
</#if>
</#list>
</resultMap>
<resultMap id="${entityName}ResultMap" type="${entityType}">
<#list columnList as column>
<#if column_index = 0>
<id column="id" property="id"/>
<#else>
<result column="${column.nativeColumn}" property="${column.convertColumn}"/>
</#if>
</#list>
</resultMap>
<insert id="save" keyProperty="id" useGeneratedKeys="true" parameterType="${dtoType}">
insert into ${tableName} (coupon_discount_code, ticket_info_id,wristband_code,active_id,
created_time,deleted
<#list columnList as column>
<#if column_index = 0>
${column.nativeColumn}
<#else>
,${column.nativeColumn}
</#if>
</#list>
)
values (
<#list columnList as column>
<#if column_index = 0>
${column.convertColumn}
<#else>
,${column.convertColumn}
</#if>
</#list>
)
</insert>
<select id="query${dtoName}s" resultMap="${dtoName}ResultMap">
SELECT
*
FROM ${tableName}
<where>
<#list columnList as column>
<if test="${dtoNameLow}.${column.convertColumn} != null">
and ${column.nativeColumn} = ${column.param}
</if>
</#list>
</where>
</select>
</mapper>
daoTemp.ftl
package ${packetageDAO};
import ${dtoType};
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ${entityName}DAO {
Long save(${dtoName} ${dtoNameLow});
List<${dtoName}> query${dtoName}s(@Param("${dtoNameLow}") ${dtoName} ${dtoNameLow});
}
dtoTemp.ftl
package ${packetageDTO};
import java.lang.*;
public class ${dtoName} {
<#list dataStrutes as dataStrute>
private ${dataStrute.type} ${dataStrute.column};
</#list>
<#list dataStrutes as dataStrute>
public ${dataStrute.type} get${dataStrute.pColumn}() {
return ${dataStrute.column};
}
public void set${dataStrute.pColumn}(String ${dataStrute.column}) {
this.${dataStrute.column} = ${dataStrute.column};
}
</#list>
}
pojoTemp.ftl
package ${packetagePojo};
import java.lang.*;
public class TicketActiveRecord {
<#list dataStrutes as dataStrute>
private ${dataStrute.type} ${dataStrute.column};
</#list>
<#list dataStrutes as dataStrute>
public ${dataStrute.type} get${dataStrute.pColumn}() {
return ${dataStrute.column};
}
public void set${dataStrute.pColumn}(String ${dataStrute.column}) {
this.${dataStrute.column} = ${dataStrute.column};
}
</#list>
}
生成的DTO和Pojo就不展示了,经测试可用,写的比较匆忙,有很多东西可以优化,赶项目了。有空的时候可以添加很多东西,完善一下。