来源:huzhiyong
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by huzhiyong on 2017/2/7.
* 用于生成基本的mapper文件
* 输入:SQLyog 导出的建表语句
* 输出:1,基本Dao和DO类,2,mapper文件,3,测试代码 全部输出到 output.txt 文件
*
* sql规范:
* 1, 数据库字段名全小写,用下划线隔开
* 2,默认每个表都有 id 字段(自增主键) modified_date
* 3, 每列都要有注释,列注释当中不包括 英文逗号,数据库注释不包括 英文括号
* 4,删除掉索引行,当有联合索引时,会报错
*/
public class MapperCreator {
private static final HashMap<String,String> sqlJavaTypeMap = new HashMap<>();
private static final HashMap<String,String> sqlJdbcTypeMap = new HashMap<>();
static{
sqlJavaTypeMap.put("bigint", "Long") ;
sqlJavaTypeMap.put("int", "Integer") ;
sqlJavaTypeMap.put("tinyint", "Integer") ;
sqlJavaTypeMap.put("varchar", "String") ;
sqlJavaTypeMap.put("text", "String") ;
sqlJavaTypeMap.put("char", "String") ;
sqlJavaTypeMap.put("datetime", "Date") ;
sqlJavaTypeMap.put("timestamp", "Date") ;
sqlJavaTypeMap.put("mediumtext", "String") ;
sqlJdbcTypeMap.put("bigint", "BIGINT") ;
sqlJdbcTypeMap.put("int", "INTEGER") ;
sqlJdbcTypeMap.put("tinyint", "INTEGER") ;
sqlJdbcTypeMap.put("varchar", "VARCHAR") ;
sqlJdbcTypeMap.put("text", "VARCHAR") ;
sqlJdbcTypeMap.put("char", "CHAR") ;
sqlJdbcTypeMap.put("datetime", "TIMESTAMP") ;// 注意,这里使用这个类型,不能直接使用DATE,mybatis的Date只有年月日
sqlJdbcTypeMap.put("timestamp", "TIMESTAMP") ;
sqlJdbcTypeMap.put("mediumtext", "VARCHAR") ;
}
private static final String DAO_END = "Dao" ;
private static final String DO_END = "DO" ;
// 修改这两个参数
private static final String OUTPUT_DIR = "C:\\Users\\jrliangbo\\Downloads" ;
private static final String PACKAGE_NAME = "com.heytap.mall.comment.core.domain.dao." ;
public static void main(String[] args) throws Exception{
// 此处将sql建表语句粘出,注意sql规范
String sql = "CREATE TABLE `t_comment_liking` (\n" +
" `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id 自增主键',\n" +
" `comment_id` bigint(20) NOT NULL COMMENT '评论id 评论id',\n" +
" `user_id` varchar(64) DEFAULT NULL COMMENT '用户唯一标识 用户唯一标识',\n" +
" `device_id` varchar(64) DEFAULT NULL COMMENT '设备id',\n" +
" `liking` tinyint(1) DEFAULT NULL COMMENT '点赞 点赞与否,1点赞',\n" +
" `data_status` tinyint(1) DEFAULT NULL COMMENT '数据有效性 数据是否有效,1有效',\n" +
" `create_time` timestamp NOT NULL COMMENT '创建时间',\n" +
" `modify_time` timestamp NOT NULL COMMENT '修改时间',\n" +
" `created` varchar(32) NOT NULL DEFAULT '' COMMENT '创建人',\n" +
" `modified` varchar(32) NOT NULL DEFAULT '' COMMENT '更新人',\n" +
" PRIMARY KEY (`id`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论点赞表 '" ;
sql = sql.replace("\n","") ;
process(sql) ;
System.out.println("end");
}
/**
* 生成 java DO类
* 生成 Dao类
* 生成 mapper文件
* 生成 测试类
*/
private static void process(String allData){
int begin = allData.indexOf("(");
int end = allData.lastIndexOf(")");
String firstLine = allData.substring(0, begin) ;
String columnLine = allData.substring(begin+1,end);
String tableName = getTableName(firstLine) ;
List<Item> columnList = getColumnList(columnLine) ;
String baseName = columnName2JavaName(tableName) ;
String doVarName = baseName + DO_END ;
String daoVarName = baseName + DAO_END ;
String doClassName = doVarName.substring(0,1).toUpperCase() + doVarName.substring(1) ;
String daoClassName = daoVarName.substring(0,1).toUpperCase() + daoVarName.substring(1) ;
StringBuilder sb = new StringBuilder("") ;
sb.append(doClassName);
sb.append("-----------------------------------------------------------\n\n") ;
sb.append(createDoFile(columnList)) ;
sb.append("\n\n") ;
sb.append(daoClassName);
sb.append("-----------------------------------------------------------\n\n") ;
sb.append(createDaoFile(doVarName, doClassName, daoClassName)) ;
sb.append("\n\n") ;
sb.append(baseName.substring(0,1).toUpperCase());
sb.append(baseName.substring(1));
sb.append("Mapper.xml-------------------------------------------------\n\n") ;
sb.append(createMapperFile(columnList,daoClassName,doClassName,tableName));
sb.append("\n\n");
sb.append(daoClassName);
sb.append("Test.java");
sb.append("-----------------------------------------------------------\n\n") ;
sb.append(createTestFile(columnList,doClassName,doVarName,daoClassName,daoVarName)) ;
sb.append("\n\n") ;
writeToFile(OUTPUT_DIR, sb.toString()) ;
return ;
}
private static void writeToFile(String dir, String data){
String filePath = dir + "\\\\" + "output.txt" ;
FileWriter fos;
try {
fos = new FileWriter(filePath);
fos.write(data);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static String createDoFile(List<Item> columnList){
StringBuilder sb = new StringBuilder("") ;
for(Item item : columnList){
sb.append("/** ");
sb.append(item.getComment());
sb.append(" */\n");
sb.append("private ");
sb.append(item.getJavaType());
sb.append(" ");
sb.append(item.getName()) ;
sb.append(";\n\n") ;
}
sb.append("\n\n");
return sb.toString() ;
}
private static String createDaoFile(String doVarName,String doClassName,String daoClassName){
String base = "@SuperDao\n" +
"public interface TMPDAO {\n" +
" int insert(TMPDO tmpdo);\n" +
" int update(TMPDO tmpdo);\n" +
" int delete(Long id);\n" +
" TMPDO getById(Long id);\n" +
"}";
base = base.replace("TMPDAO",daoClassName);
base = base.replace("TMPDO",doClassName);
base = base.replace("tmpdo",doVarName);
return base ;
}
private static String createMapperFile(List<Item> columnList,String daoClassName,String doClassName,String tableName){
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
"<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\" >\n" +
"<mapper namespace=\"");
sb.append(PACKAGE_NAME);
sb.append(daoClassName);
sb.append("\">\n");
sb.append("<resultMap id=\"BaseResultMap\" type=\"");
sb.append(doClassName);
sb.append("\">\n") ;
sb.append("<id column=\"id\" property=\"id\" jdbcType=\"BIGINT\"/>\n") ;
for(Item item : columnList){
if(!item.getName().equals("id")){
sb.append("<result column=\"");
sb.append(item.getColumn());
sb.append("\" property=\"");
sb.append(item.getName());
sb.append("\" jdbcType=\"");
sb.append(item.getJdbcType());
sb.append("\"/>\n");
}
}
sb.append(" </resultMap>\n") ;
sb.append("<sql id=\"Base_Column_List\">\n");
sb.append(columnList.get(0).getColumn());
for(int i=1; i<columnList.size(); i++){
sb.append(",") ;
sb.append(columnList.get(i).getColumn()) ;
}
sb.append("\n");
sb.append("</sql>\n") ;
// insert
sb.append(createInsertSql(columnList, doClassName, tableName)) ;
sb.append("\n\n");
// update
sb.append(createUpdateSql(columnList, doClassName, tableName)) ;
sb.append("\n\n");
// getById
sb.append(createQuerySql(tableName)) ;
sb.append("\n\n");
// delete
sb.append(createDeleteSql(tableName)) ;
sb.append("\n\n");
sb.append("</mapper>\n");
return sb.toString() ;
}
private static String createInsertSql(List<Item> columnList,String doClassName,String tableName){
StringBuilder sb = new StringBuilder("");
sb.append("<insert id=\"insert\" useGeneratedKeys=\"true\" keyProperty=\"id\" parameterType=\"");
sb.append(doClassName);
sb.append("\">\n");
sb.append("INSERT into ");
sb.append(tableName) ;
sb.append("\n");
sb.append("<trim prefix=\"(\" suffix=\")\">\n");
for(Item item : columnList){
if(!item.getColumn().equals("id") && !item.getColumn().equals("modified_date")){
if(item.getColumn().equals("created_date")){
sb.append("created_date,\n");
}else if(item.isCanEmpty()){
sb.append("<if test=\"");
sb.append(item.getName());
sb.append("!= null\">\n");
sb.append(item.getColumn());
sb.append(",\n");
sb.append("</if>\n");
}else{
sb.append(item.getColumn());
sb.append(",\n") ;
}
}
}
sb.append("modified_date\n");
sb.append("</trim>\n") ;
sb.append("<trim prefix=\"values (\" suffix=\")\">\n");
for(Item item : columnList){
if(!item.getColumn().equals("id") && !item.getColumn().equals("modified_date")){
if(item.getColumn().equals("created_date")){
sb.append("current_timestamp,\n");
}else if(item.isCanEmpty()){
sb.append("<if test=\"");
sb.append(item.getName());
sb.append(" != null\">\n");
sb.append("#{");
sb.append(item.getName());
sb.append(",jdbcType=");
sb.append(item.getJdbcType());
sb.append("},\n");
sb.append("</if>\n");
}else{
sb.append("#{");
sb.append(item.getName());
sb.append(",jdbcType=");
sb.append(item.getJdbcType());
sb.append("},\n");
}
}
}
sb.append("current_timestamp\n");
sb.append("</trim>\n") ;
sb.append("</insert>\n") ;
return sb.toString() ;
}
private static String createUpdateSql(List<Item> columnList,String doClassName,String tableName){
StringBuilder sb = new StringBuilder("");
sb.append("<update id=\"update\" parameterType=\"");
sb.append(doClassName);
sb.append("\">\n");
sb.append("update ");
sb.append(tableName);
sb.append("\n");
sb.append("<set>\n");
for(Item item : columnList){
if(!item.getColumn().equals("id")
&& !item.getColumn().equals("modified_date")
&& !item.getColumn().equals("created_date")){
sb.append("<if test=\"");
sb.append(item.getName());
sb.append(" != null\">\n");
sb.append(item.getColumn());
sb.append(" = #{");
sb.append(item.getName());
sb.append(",jdbcType=");
sb.append(item.getJdbcType());
sb.append("},\n");
sb.append("</if>\n");
}
}
sb.append("modified_date = current_timestamp\n");
sb.append("</set>\n");
sb.append("where id = #{id,jdbcType=BIGINT}\n");
sb.append("</update>\n");
return sb.toString() ;
}
private static String createQuerySql(String tableName){
StringBuilder sb = new StringBuilder("");
sb.append("<select id=\"getById\" resultMap=\"BaseResultMap\" parameterType=\"java.lang.Long\">\n");
sb.append("SELECT\n");
sb.append("<include refid=\"Base_Column_List\" />\n");
sb.append("from ");
sb.append(tableName);
sb.append("\n");
sb.append("where id = #{id,jdbcType=BIGINT}\n");
sb.append("</select>\n") ;
return sb.toString() ;
}
private static String createDeleteSql(String tableName){
StringBuilder sb = new StringBuilder("");
sb.append("<delete id=\"delete\" parameterType=\"java.lang.Long\">\n");
sb.append("DELETE\n");
sb.append("from ");
sb.append(tableName);
sb.append("\n");
sb.append("where id = #{id,jdbcType=BIGINT}\n");
sb.append("</delete>\n") ;
return sb.toString() ;
}
private static String createTestFile(List<Item> columnList,String doClassName,String doVarName,String daoClassName, String daoVarName){
String model = "public class TMPXXXDaoTest extends TestBase {\n" +
" private static final Logger logger = LoggerFactory.getLogger(TMPXXXDaoTest.class);\n" +
"\n" +
" @Resource\n" +
" private TMPXXXDao tmpXXXDao;\n" +
"\n" +
" private Long id ;\n" +
"\n" +
" @Test\n" +
" public void testInsert(){\n" +
" TMPXXXDO tmpXXXDO = create();\n" +
" int result = tmpXXXDao.insert(tmpXXXDO);\n" +
" Assert.assertTrue(result > 0);\n" +
" id = tmpXXXDO.getId() ;\n" +
" Assert.assertNotNull(id);\n" +
" Assert.assertTrue(id > 0);\n" +
" }\n" +
"\n" +
" @Test(dependsOnMethods = \"testInsert\")\n" +
" public void testGetById(){\n" +
" TMPXXXDO tmpXXXDO = tmpXXXDao.getById(id);\n" +
" Assert.assertNotNull(tmpXXXDO);\n" +
" logger.info(\"testGetById获得对象: {}\", tmpXXXDO);\n" +
" }\n" +
"\n" +
" @Test(dependsOnMethods = \"testGetById\")\n" +
" public void testUpdate(){\n" +
" TMPXXXDO tmpXXXDO = create();\n" +
" tmpXXXDO.setId(id);\n" +
" SET_STRING_PLACEHOLDER\n" +
" int result = tmpXXXDao.update(tmpXXXDO);\n" +
" Assert.assertTrue(result > 0);\n" +
" }\n" +
"\n" +
" @Test(dependsOnMethods = \"testUpdate\")\n" +
" public void testGetById2(){\n" +
" TMPXXXDO tmpXXXDO = tmpXXXDao.getById(id);\n" +
" Assert.assertNotNull(tmpXXXDO);\n" +
" logger.info(\"testGetById2获得对象: {}\", tmpXXXDO);\n" +
" }\n" +
"\n" +
" @Test(dependsOnMethods = \"testGetById2\")\n" +
" public void testDelete(){\n" +
" int result = tmpXXXDao.delete(id);\n" +
" Assert.assertTrue(result > 0);\n" +
" }\n" +
"\n" +
" @Test(dependsOnMethods = \"testDelete\")\n" +
" public void testGetById3(){\n" +
" TMPXXXDO tmpXXXDO = tmpXXXDao.getById(id);\n" +
" Assert.assertNull(tmpXXXDO);\n" +
" }\n" +
"\n" +
"\n" +
" private TMPXXXDO create(){\n" +
" TMPXXXDO tmpXXXDO = new TMPXXXDO();\n" +
" SET_STRING_PLACEHOLDER\n" +
" return tmpXXXDO ;\n" +
" }\n" +
"}" ;
model = model.replace("TMPXXXDao",daoClassName);
model = model.replace("tmpXXXDao",daoVarName);
model = model.replace("TMPXXXDO",doClassName);
model = model.replace("tmpXXXDO",doVarName);
String setString = getSetString(columnList,doVarName);
model = model.replace("SET_STRING_PLACEHOLDER", setString);
return model ;
}
private static String getSetString(List<Item> columnList,String doVarName){
StringBuilder sb = new StringBuilder("");
for(Item item:columnList){
if(!item.getColumn().equals("id")){
if(item.isCanEmpty()){
sb.append("//") ;
}
sb.append(doVarName);
sb.append(".set");
sb.append(item.getName().substring(0,1).toUpperCase());
sb.append(item.getName().substring(1));
sb.append("(");
// 当有新的类型时,需要在此处添加
if(item.getJavaType().equals("Integer")){
sb.append("0");
}else if(item.getJavaType().equals("Long")){
sb.append("0L");
}else if(item.getJavaType().equals("String")){
sb.append("\"hello world 测试\"");
}else if(item.getJavaType().equals("Date")){
sb.append("new Date()");
}else{
sb.append("");
}
sb.append(");\n");
}
}
return sb.toString() ;
}
private static List<Item> getColumnList(String data){
List<Item> result = new ArrayList<Item>();
String[] array = data.split(",") ;
for(String line : array){
if(!isKeyLine(line)){
Item item = new Item();
item.setColumn(getColumn(line));
item.setComment(getComment(line));
item.setSqlType(getType(line));
item.setCanEmpty(canEmpty(line));
if(!sqlJavaTypeMap.containsKey(item.getSqlType())){
throw new RuntimeException("找不到对应类型") ;
}
item.setJavaType(sqlJavaTypeMap.get(item.getSqlType()));
item.setJdbcType(sqlJdbcTypeMap.get(item.getSqlType()));
item.setName(columnName2JavaName(item.getColumn()));
result.add(item);
}
}
return result ;
}
private static boolean isKeyLine(String line){
line = line.trim();
line = line.toUpperCase() ;
if(line.startsWith("PRIMARY")
|| line.startsWith("KEY")
|| line.startsWith("INDEX")
|| line.startsWith("UNIQUE")
){
return true ;
}
return false ;
}
private static String removeQuote(String data, int quote){
data = data.trim() ;
int begin = data.indexOf(quote);
if(begin > -1){
int end = data.indexOf(quote,begin+1);
if(end > -1){
return data.substring(begin+1,end) ;
}
}
return data ;
}
private static String getTableName(String firstLine){
String[] array = firstLine.split(" ");
int length = array.length;
return removeQuote(array[length-1],'`');
}
// 获取注释,COMMENT 之后第一个用 引号包起来的内容
private static String getComment(String line){
String[] array = line.split("COMMENT");
return removeQuote(array[1],'\'') ;
}
private static String getColumn(String line){
return removeQuote(line,'`');
}
private static boolean canEmpty(String line){
// 有默认值的认为插入是可以为空
if(line.contains("NOT NULL DEFAULT")){
return true ;
}
return !(line.contains("NOT NULL")) ;
}
private static String getType(String line){
line = line.trim() ;
String[] array = line.split(" ");
String name = array[1];
int end = name.indexOf("(");
if(end > 1){
return name.substring(0,end) ;
}
return name ;
}
private static String columnName2JavaName(String column){
column = column.toLowerCase() ;
String[] array = column.split("_") ;
StringBuilder sb = new StringBuilder("");
sb.append(array[0]);
for(int i=1; i<array.length; i++){
sb.append(array[i].substring(0,1).toUpperCase()) ;
sb.append(array[i].substring(1)) ;
}
return sb.toString() ;
}
}
class Item{
private String name; // java字段名
private String column ; // 数据库列名
private String sqlType ;
private String javaType;
private String jdbcType ;
private boolean canEmpty ;// 是否可为Null
private String comment ; //注释
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColumn() {
return column;
}
public void setColumn(String column) {
this.column = column;
}
public String getSqlType() {
return sqlType;
}
public void setSqlType(String sqlType) {
this.sqlType = sqlType;
}
public String getJavaType() {
return javaType;
}
public void setJavaType(String javaType) {
this.javaType = javaType;
}
public String getJdbcType() {
return jdbcType;
}
public void setJdbcType(String jdbcType) {
this.jdbcType = jdbcType;
}
public boolean isCanEmpty() {
return canEmpty;
}
public void setCanEmpty(boolean canEmpty) {
this.canEmpty = canEmpty;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}