需求:
1. 当设计好数据库之后能够一键生成一些重复的代码,光是CRUD都能省很多时间,让咱们程序员只负责业务岂不快哉。所以生成器需要能生成常用的增删改查
2.项目过程中很有可能会修改表字段,除非前期工作做得非常好,有人创建表的时候会预留一些字段,但是我的习惯是 这些字段只有项目已经上线之后才使用
实现流程:
一、 准备工作
1. idea 其实eclipse也可以 无所谓
2.maven 因为需要打成jar包,maven比较简单,用jdk打包也行 无所谓
3.数据库驱动包
4.项目结构图如下
二、pom和模板 因为使用模板替换的,没有使用第三方模板,就自己定义字符串来搞的,反正也不复杂,难得用第三方的了
1. pom.xml
4.0.0
org.cms
cms
1.0-SNAPSHOT
jar
mysql
mysql-connector-java
8.0.18
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
1.8
1.8
2. 模板类
package com.cms.template;
public class Template {
/**
* 父级模型模板
*/
public static final String CLASS_BASE_TEMPLATE = "package {{baseModelPackage}};\n" +
"import java.io.Serializable;\n" +
"{{imports}}" +
"public class {{classname}}Base implements Serializable{\n" +
"\tprivate static final long serialVersionUID = 1L;\n"+
"{{fields}}" +
"{{getter_setter}}" +
"}";
/**
* 子级模型模板
*/
public static final String CLASS_TEMPLATE = "package {{modelPackage}};\n" +
"import {{baseModelPackage}}.{{classname}}Base;\n" +
"public class {{classname}} extends {{classname}}Base{\n" +
"\tprivate static final long serialVersionUID = 1L;\n"+
"}";
/**
* 父级DAO
*/
public static final String BASE_DAO_TEMPLATE = "package {{baseDAOPackage}};\n" +
"import java.util.List;\n" +
"import org.apache.ibatis.annotations.Param;\n" +
"import {{modelPackage}}.{{classname}};\n" +
"public interface {{classname}}BaseDAO{\n" +
"\tint insert({{classname}} obj);\n"+
"\tint updateById({{classname}} obj);\n"+
"\tint deleteById(Long id);\n"+
"\t{{classname}} selectOneById(@Param(\"id\")Long id,@Param(\"logicWhereSql\")String logicWhereSql);\n"+
"\tList<{{classname}}> selectAll(String logicWhereSql);\n"+
"}";
/**
* 子级DAO
*/
public static final String DAO_TEMPLATE = "package {{daoPackage}};\n" +
"import java.util.List;\n" +
"import org.apache.ibatis.annotations.Param;\n" +
"import {{modelPackage}}.{{classname}};\n" +
"import {{pageDTOPackage}}.{{classname}}PageDTO;\n" +
"import {{baseDAOPackage}}.{{classname}}BaseDAO;\n" +
"public interface {{classname}}DAO extends {{classname}}BaseDAO{\n" +
"\tint logicDeleteById(@Param(\"id\")Long id,@Param(\"logicSetSql\")String logicSetSql);\n"+
"\tlong selectCount(@Param(\"dto\"){{classname}}PageDTO dto,@Param(\"logicWhereSql\")String logicWhereSql);\n"+
"\tList<{{classname}}> selectPage(@Param(\"dto\"){{classname}}PageDTO dto,@Param(\"logicWhereSql\")String logicWhereSql);\n"+
"}";
/**
* Service
*/
public static final String SERVICE_TEMPLATE = "package {{servicePackage}};\n" +
"import org.springframework.beans.factory.annotation.Autowired;\n" +
"import org.springframework.stereotype.Service;\n" +
"import org.springframework.transaction.annotation.Transactional;\n" +
"import {{modelPackage}}.{{classname}};\n" +
"import {{pageDTOPackage}}.{{classname}}PageDTO;\n" +
"import {{daoPackage}}.{{classname}}DAO;\n" +
"import {{resultDTOPackage}}.{{resultDTO}};\n" +
"@Service\n" +
"public class {{classname}}Service{\n" +
"\tprivate static final String logicWhereSql=\"deleted = 1\";\n"+
"\tprivate static final String logicSetSql=\"set deleted = -1\";\n"+
"\t@Autowired\n" +
"\tprivate {{classname}}DAO {{class_var}}DAO;\n" +
"\tprivate String validate({{classname}} obj){return null;}\n"+
"\t@Transactional\n"+
"\tpublic {{resultDTO}} insert({{classname}} obj){\n"+
"\t\tString validateResult = validate(obj);\n"+
"\t\tif(validateResult!=null&&validateResult.length()!=0){\n" +
"\t\t\treturn {{resultDTO}}.put400(validateResult,\"params validate failed.\");\n"+
"\t\t}\n"+
"\t\ttry {\n"+
"\t\t\t{{class_var}}DAO.insert(obj);\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\");\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"insert {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"\t@Transactional\n"+
"\tpublic {{resultDTO}} updateById({{classname}} obj){\n"+
"\t\tString validateResult = validate(obj);\n"+
"\t\tif(validateResult!=null&&validateResult.length()!=0){\n" +
"\t\t\treturn {{resultDTO}}.put400(validateResult,\"params validate failed.\");\n"+
"\t\t}\n"+
"\t\ttry {\n"+
"\t\t\t{{class_var}}DAO.updateById(obj);\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\");\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"update {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"\t@Transactional\n"+
"\tpublic {{resultDTO}} deleteById(Long id){\n"+
"\t\ttry {\n"+
"\t\t\t{{class_var}}DAO.deleteById(id);\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\");\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"delete {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"\t@Transactional\n"+
"\tpublic {{resultDTO}} logicDeleteById(Long id){\n"+
"\t\ttry {\n"+
"\t\t\t{{class_var}}DAO.logicDeleteById(id,logicSetSql);\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\");\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"delete {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"\tpublic {{resultDTO}} selectOneById(Long id){\n"+
"\t\ttry {\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\",{{class_var}}DAO.selectOneById(id,logicWhereSql));\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"query one {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"\tpublic {{resultDTO}} selectAll(){\n"+
"\t\ttry {\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\",{{class_var}}DAO.selectAll(logicWhereSql));\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"query all {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"\tpublic {{resultDTO}} paging({{classname}}PageDTO dto){\n"+
"\t\ttry {\n"+
"\t\t\tlong count = {{class_var}}DAO.selectCount(dto,logicWhereSql);\n"+
"\t\t\tdto.setTotal(count);\n"+
"\t\t\tif(count==0){\n" +
"\t\t\t\treturn {{resultDTO}}.putSuccess(\"ok\",dto);\n"+
"\t\t\t}\n"+
"\t\t\tdto.setData({{class_var}}DAO.selectPage(dto,logicWhereSql));\n"+
"\t\t\treturn {{resultDTO}}.putSuccess(\"ok\",dto);\n"+
"\t\t}catch(Exception e){\n" +
"\t\t\treturn {{resultDTO}}.put500(\"paging {{classname}} failed\",e.getMessage());\n"+
"\t\t}\n"+
"\t}\n"+
"}";
public static final String ACTION_TEMPLATE = "package {{actionPackage}};\n"+
"import org.springframework.stereotype.Controller;\n"+
"import org.springframework.web.bind.annotation.CrossOrigin;\n"+
"import org.springframework.web.bind.annotation.RequestMapping;\n"+
"import org.springframework.beans.factory.annotation.Autowired;\n" +
"import org.springframework.web.bind.annotation.RequestBody;\n"+
"import org.springframework.web.bind.annotation.ResponseBody;\n"+
"import {{servicePackage}}.{{classname}}Service;\n" +
"import {{modelPackage}}.{{classname}};\n" +
"import {{pageDTOPackage}}.{{classname}}PageDTO;\n" +
"import {{resultDTOPackage}}.{{resultDTO}};\n" +
"@Controller\n"+
"@RequestMapping(\"/{{class-mapping}}\")\n"+
"@CrossOrigin\n"+
"public class {{classname}}Action{\n"+
"\t@Autowired\n" +
"\tprivate {{classname}}Service {{class_var}}Service;\n" +
"\t@RequestMapping(\"/add\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} add(@RequestBody {{classname}} obj) {\n"+
"\t\treturn {{class_var}}Service.insert(obj);\n"+
"\t}\n"+
"\t@RequestMapping(\"/edit\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} edit(@RequestBody {{classname}} obj) {\n"+
"\t\treturn {{class_var}}Service.updateById(obj);\n"+
"\t}\n"+
"\t@RequestMapping(\"/delete\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} delete(Long id) {\n"+
"\t\treturn {{class_var}}Service.deleteById(id);\n"+
"\t}\n"+
"\t@RequestMapping(\"/delete-logic\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} deleteLogic(Long id) {\n"+
"\t\treturn {{class_var}}Service.logicDeleteById(id);\n"+
"\t}\n"+
"\t@RequestMapping(\"/selectOne\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} selectOne(Long id) {\n"+
"\t\treturn {{class_var}}Service.selectOneById(id);\n"+
"\t}\n"+
"\t@RequestMapping(\"/selectAll\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} selectAll() {\n"+
"\t\treturn {{class_var}}Service.selectAll();\n"+
"\t}\n"+
"\t@RequestMapping(\"/paging\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} paging(@RequestBody {{classname}}PageDTO dto) {\n"+
"\t\treturn {{class_var}}Service.paging(dto);\n"+
"\t}\n"+
"}";
public static final String API_ACTION_TEMPLATE = "package {{apiActionPackage}};\n"+
"import org.springframework.stereotype.Controller;\n"+
"import org.springframework.web.bind.annotation.CrossOrigin;\n"+
"import org.springframework.web.bind.annotation.RequestMapping;\n"+
"import org.springframework.beans.factory.annotation.Autowired;\n" +
"import org.springframework.web.bind.annotation.RequestBody;\n"+
"import org.springframework.web.bind.annotation.ResponseBody;\n"+
"import {{servicePackage}}.{{classname}}Service;\n" +
"import {{modelPackage}}.{{classname}};\n" +
"import {{pageDTOPackage}}.{{classname}}PageDTO;\n" +
"import {{resultDTOPackage}}.{{resultDTO}};\n" +
"@Controller\n"+
"@RequestMapping(\"/api/{{class-mapping}}\")\n"+
"@CrossOrigin\n"+
"public class API{{classname}}Action{\n"+
"\t@Autowired\n" +
"\tprivate {{classname}}Service {{class_var}}Service;\n" +
"\t@RequestMapping(\"/add\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} add(@RequestBody {{classname}} obj) {\n"+
"\t\treturn {{class_var}}Service.insert(obj);\n"+
"\t}\n"+
"\t@RequestMapping(\"/edit\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} edit(@RequestBody {{classname}} obj) {\n"+
"\t\treturn {{class_var}}Service.updateById(obj);\n"+
"\t}\n"+
"\t@RequestMapping(\"/delete\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} delete(Long id) {\n"+
"\t\treturn {{class_var}}Service.deleteById(id);\n"+
"\t}\n"+
"\t@RequestMapping(\"/delete-logic\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} deleteLogic(Long id) {\n"+
"\t\treturn {{class_var}}Service.logicDeleteById(id);\n"+
"\t}\n"+
"\t@RequestMapping(\"/selectOne\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} selectOne(Long id) {\n"+
"\t\treturn {{class_var}}Service.selectOneById(id);\n"+
"\t}\n"+
"\t@RequestMapping(\"/selectAll\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} selectAll() {\n"+
"\t\treturn {{class_var}}Service.selectAll();\n"+
"\t}\n"+
"\t@RequestMapping(\"/paging\")\n"+
"\t@ResponseBody\n"+
"\tpublic {{resultDTO}} paging(@RequestBody {{classname}}PageDTO dto) {\n"+
"\t\treturn {{class_var}}Service.paging(dto);\n"+
"\t}\n"+
"}";
public static final String PAGE_DTO_TEMPLATE = "package {{pageDTOPackage}};\n"+
"import {{modelPackage}}.{{classname}};\n"+
"import {{pageDTOPackage}}.{{classname}}PageDTO;\n" +
"public class {{classname}}PageDTO extends {{pageDTO}}<{{classname}}>{\n"+
"}";
public static final String BASE_MAPPER_TEMPLATE = "\n" +
"\n" +
"\n" +
"\t\n" +
"\t\tinsert into `{{tableName}}`\n" +
"\t\t\n"+
"{{into}}"+
"\t\t \n"+
"\t\t\n" +
"{{values}}"+
"\t\t \n"+
"\t \n" +
"\t\n" +
"\t\tupdate `{{tableName}}`\n"+
"\t\t\n"+
"{{sets}}"+
"\t\t \n"+
"\t\twhere id = #{id}\n"+
"\t \n" +
"\t\n" +
"\t\tdelete from `{{tableName}}` where id = #{id}\n"+
"\t \n" +
"\t\n" +
"\t\n" +
" ";
public static final String MAPPER_TEMPLATE = "\n" +
"\n" +
"\n" +
"\t\n" +
"\t\t\n"+
"\t\t\tupdate `{{tableName}}` ${logicSetSql} where id = #{id}\n"+
"\t\t \n"+
"\t \n" +
"\t\n" +
"\t\n" +
"\t\n" +
"\t\t\n"+
"\t\t\t\n\t\t\t\t${logicWhereSql}\n\t\t\t \n"+
"\t\t \n"+
"\t \n" +
" ";
}
三、 包装类和工具类
1. 包装类 看名字就知道是 数据库类型转换为java类型的
package com.cms.dto;
public class DBType2JavaTypeDTO {
private String classname;//全限定名
private String name;//简写类名
private Class clz;//字节码
public DBType2JavaTypeDTO(String classname, String name, Class clz) {
this.classname = classname;
this.name = name;
this.clz = clz;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class getClz() {
return clz;
}
public void setClz(Class clz) {
this.clz = clz;
}
}
2. 工具类
1) ClassesUtil 这个类的作用就是转换类型,生成getter/setter和写文件的 方法上都有注释是干嘛的
package com.cms.util;
import com.cms.dto.DBType2JavaTypeDTO;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
public class ClassesUtil {
/**
* 表明->类名
*
* @param tableName 表名
* @param separator 分隔符 表的连接符,表名->类名时会将此连接符删除,并使用驼峰将前后进行拼接 如 dic_item --> DicItem
* @return
*/
public static String convertClassNameByTableName(String tableName, String separator) {
List classes = new ArrayList<>();
//处理连接器
String newSeparator = separator==null?" ":separator;
String[] names = tableName.split(newSeparator);
String classname = "";
for (String str : names) {
classname += StringUtil.toFirstUpperCase(str);
}
return classname;
}
private static DBType2JavaTypeDTO convertJAVATypeByDBType(String dbType) {
dbType = dbType.toUpperCase();
switch(dbType){
case "VARCHAR":
case "TEXT":
case "CHAR":
return class2DTO(String.class);
case "DECIMAL":
return class2DTO(BigDecimal.class);
case "TINYINT":
case "SMALLINT":
case "MEDIUMINT":
case "INT":
return class2DTO(Integer.class);
case "BIGINT":
case "INTEGER":
return class2DTO(Long.class);
case "DATETIME":
case "TIMESTAMP":
case "DATE":
case "TIME":
return class2DTO(Date.class);
case "DOUBLE":
return class2DTO(Double.class);
case "FLOAT":
return class2DTO(Float.class);
case "BIT":
return class2DTO(Boolean.class);
}
return null;
}
/**
* class转模型
* @param clz
* @return
*/
private static DBType2JavaTypeDTO class2DTO(Class> clz){
return new DBType2JavaTypeDTO(clz.getName(),clz.getSimpleName(),clz);
}
/**
* 是否是不用导包的类型
* @return
*/
public static boolean isJAVALangType(Class> clz){
return short.class.equals(clz)||
byte.class.equals(clz)||
int.class.equals(clz)||
long.class.equals(clz)||
float.class.equals(clz)||
double.class.equals(clz)||
boolean.class.equals(clz)||
char.class.equals(clz)||
Integer.class.equals(clz)||
Long.class.equals(clz)||
Float.class.equals(clz)||
Double.class.equals(clz)||
String.class.equals(clz)||
Short.class.equals(clz)||
Byte.class.equals(clz)||
Character.class.equals(clz)||
Boolean.class.equals(clz);
}
/**
* 传入一个数据库类型字符串 返回一句导包代码
* @param clz
* @return
*/
public static String handlerImport(String clz){
DBType2JavaTypeDTO typeDTO = convertJAVATypeByDBType(clz);
if(!isJAVALangType(typeDTO.getClz())){
return "import\t"+typeDTO.getClassname()+";";
}
return "";
}
/**
* 根据变量名 数据库类型 和注释 返回一句字段+注释的代码
* @param type
* @param comment
* @return
*/
public static String handlerField(String name,String type, String comment) {
DBType2JavaTypeDTO typeDTO = convertJAVATypeByDBType(type);
if(StringUtil.isNotEmptyOrNull(comment)){
comment = "//"+comment;
}
return "\tprivate\t"+typeDTO.getName()+"\t"+name+";\t"+comment;
}
/**
* 生成getter/setter
* @param name
* @param type
* @return
*/
public static String handlerGetterAndSetter(String name, String type) {
DBType2JavaTypeDTO typeDTO = convertJAVATypeByDBType(type);
return "\tpublic "+typeDTO.getName()+" "+getter(name)+"(){\n"+
"\t\treturn this."+name+";\n"+
"\t}\n"+
"\tpublic void "+setter(name)+"("+typeDTO.getName()+" "+name+"){\n"+
"\t\tthis."+name+"="+name+";\n"+
"\t}";
}
/**
* 根据字段名生成set属性名
* @param name
* @return
*/
public static String setter(String name) {
String one = name.substring(0, 1);
String two = name.substring(1,2);
//如果第一个字符和第二个字符都是小写 就将第一个转大写
//如果第一个小写 第二个大写 不变
//如果第一个大写 不变
//所有只判断第一个和第二个是小写 其他都不变
int i = one.charAt(0);
int j = two.charAt(0);
if (i >= 97 && i <=122&&j >= 97 && j <=122){
one = one.toUpperCase();
return "set"+one+name.substring(1);
}else {
return "set"+name;
}
}
/**
* 根据字段名生成get属性名
* @param name
* @return
*/
public static String getter(String name) {
String one = name.substring(0, 1);
String two = name.substring(1,2);
//如果第一个字符和第二个字符都是小写 就将第一个转大写
//如果第一个小写 第二个大写 不变
//如果第一个大写 不变
//所有只判断第一个和第二个是小写 其他都不变
int i = one.charAt(0);
int j = two.charAt(0);
if (i >= 97 && i <=122&&j >= 97 && j <=122){
one = one.toUpperCase();
return "get"+one+name.substring(1);
}else {
return "get"+name;
}
}
/**
* 写文件
* @param rules
* @param packageStr
*/
private static String content = "";
public static void write(Map rules, String packageStr,String filename,String template) {
content = template;
Set> entries = rules.entrySet();
for(Map.Entry item:entries){
if(item.getValue()==null){
continue;
}
content = content.replace(item .getKey(),item.getValue());
}
String path = packageStr.replace(".", "/");
String url = Thread.currentThread().getContextClassLoader().getResource(".").getPath();
path = new File(url).getParentFile().getParentFile().toPath()+"/src/main/java/"+path+"/"+filename;
File file = new File(path);
//不存在
if (!file.exists()) {
file.getParentFile().mkdirs();
}
try {
FileOutputStream out = new FileOutputStream(file);
out.write(content.getBytes());
out.close();
System.out.println("文件写成功:"+path);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2)DBUtil 操作数据库相关的工具类
package com.cms.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DBUtil {
/**
* 获取链接对象
*/
public static Connection getConn(String url, String username, String password) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
return DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取当前使用的数据库名
*/
public static String getDatabaseName(Connection conn) {
try {
String sql = "select database();";
PreparedStatement state = conn.prepareStatement(sql);
ResultSet set = state.executeQuery();
if(set.next()) {
return set.getString("database()");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取所有表名
*/
public static List getTables(Connection conn) {
List list = new ArrayList<>();
try {
String sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?";
PreparedStatement state = conn.prepareStatement(sql);
state.setObject(1,getDatabaseName(conn));
ResultSet query = state.executeQuery();
while(query.next()){
list.add(query.getString("TABLE_NAME"));
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 获取某表的字段名
* @return
*/
public static List
3. StringUtil 字符串相关工具类
package com.cms.util;
public class StringUtil {
public static boolean isEmptyOrNull(String str){
return str==null||"".equals(str.trim());
}
public static boolean isNotEmptyOrNull(String str){
return str!=null&&!"".equals(str.trim());
}
/**
* 首字母大写
* @param str
* @return
*/
public static String toFirstUpperCase(String str){
if(isEmptyOrNull(str)){
return "";
}
char[] cs=str.toCharArray();
if(cs[0]>=95){
cs[0]-=32;
}
return String.valueOf(cs);
}
/**
* 首字母小写
* @param str
* @return
*/
public static String toFirstLowerCase(String str){
char[] cs=str.toCharArray();
if(cs[0]<95){
cs[0]+=32;
}
return String.valueOf(cs);
}
}
4. TemplateUtil 这个就是替换模板的工具类 也就是把模板换成需要的代码的 只有一个方法
package com.cms.util;
import java.sql.Connection;
import java.util.*;
public class TemplateUtil {
public static Map handlerRules(Connection connection, String tableName, String separator,
String baseModelPackage, String modelPackage,
String baseDAOPackage, String daoPackage,
String baseMapperPackage, String mapperPackage,
String servicePackage, String actionPackage,
String apiActionPackage, String pageDTOPackage,
String pageDTO,String resultDTO,String resultDTOPackage){
String classname = ClassesUtil.convertClassNameByTableName(tableName, separator);
Map rules = new HashMap<>();
rules.put("{{tableName}}",tableName);
rules.put("{{baseModelPackage}}",baseModelPackage);
rules.put("{{modelPackage}}",modelPackage);
rules.put("{{baseDAOPackage}}",baseDAOPackage);
rules.put("{{daoPackage}}",daoPackage);
rules.put("{{baseMapperPackage}}",baseMapperPackage);
rules.put("{{mapperPackage}}",mapperPackage);
rules.put("{{servicePackage}}",servicePackage);
rules.put("{{actionPackage}}",actionPackage);
rules.put("{{apiActionPackage}}",apiActionPackage);
rules.put("{{pageDTOPackage}}",pageDTOPackage);
rules.put("{{pageDTO}}",pageDTO);
rules.put("{{classname}}",classname);
rules.put("{{resultDTO}}",resultDTO);
rules.put("{{resultDTOPackage}}",resultDTOPackage);
rules.put("{{class-mapping}}",tableName.replace(separator,"-"));
//类名转变量名
rules.put("{{class_var}}",StringUtil.toFirstLowerCase(classname));
//获取字段名
List> tableInfo = DBUtil.getTableInfo(connection, tableName);
Set imports = new HashSet<>();
List fields = new ArrayList<>();
List getter_setters = new ArrayList<>();
List intos = new ArrayList<>();
List values = new ArrayList<>();
List sets = new ArrayList<>();
tableInfo.forEach(map -> {
//字段名
String name = map.get("name");
//字段类型--目前得到的是DB类型
String type = map.get("type");
//字段注释
String comment = map.get("comment");
//处理导包
String importStr = ClassesUtil.handlerImport(type);
if (StringUtil.isNotEmptyOrNull(importStr)) {
imports.add(importStr);
}
//处理字段
fields.add(ClassesUtil.handlerField(name, type, comment));
//处理getter/setter
getter_setters.add(ClassesUtil.handlerGetterAndSetter(name, type));
if(!name.equals("id")){
intos.add("\t\t\t\n\t\t\t\t`"+name+"`,\n\t\t\t \n");
values.add("\t\t\t\n\t\t\t\t#{"+name+"},\n\t\t\t \n");
sets.add("\t\t\t\n\t\t\t\t`"+name+"`=#{"+name+"},\n\t\t\t \n");
}
});
String imports_str = "";
for (String str : imports) {
imports_str += str + "\n";
}
rules.put("{{imports}}", imports_str);
String fields_str = "";
for (String str : fields) {
fields_str += str + "\n";
}
rules.put("{{fields}}", fields_str);
String getter_setters_str = "";
for (String str : getter_setters) {
getter_setters_str += str + "\n";
}
rules.put("{{getter_setter}}", getter_setters_str);
//封装insert语句的列
String into = "";
for(String str:intos){
into += str;
}
rules.put("{{into}}",into);
//封装insert语句的值
String valuesStr = "";
for(String str:values){
valuesStr += str;
}
rules.put("{{values}}",valuesStr);
//封装set语句
String setStr = "";
for(String str:sets){
setStr += str;
}
rules.put("{{sets}}",setStr);
return rules;
}
}
三、 核心的抛给程序员使用的类 没什么注释,但是看方法名应该就知道干嘛的了
package com.cms;
import com.cms.template.Template;
import com.cms.util.ClassesUtil;
import com.cms.util.DBUtil;
import com.cms.util.StringUtil;
import com.cms.util.TemplateUtil;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
public class DBHandler {
private Connection connection;
/**
* 一键生成 父子模型、父子DAO、父子XML、service、后台action、web api action
*/
public void auto() {
//获取所有表明
List tables = DBUtil.getTables(connection);
tables.forEach(tableNam -> {
autoOneByTableName(tableNam);
});
}
public void autoOneByTableName(String tableName) {
createModel(tableName);
createBaseModelAndBaseMapper(tableName);
createDAO(tableName);
createBaseDAO(tableName);
createMapper(tableName);
createService(tableName);
createDTO(tableName);
createAction(tableName);
}
public void createBaseModelAndBaseMapper(String tableName) {
if(StringUtil.isEmptyOrNull(baseModelPackage)){
System.err.println("未指定base model包,创建base model失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{baseModelPackage}}"), rules.get("{{classname}}") + "Base.java", Template.CLASS_BASE_TEMPLATE);
if(StringUtil.isEmptyOrNull(baseMapperPackage)){
System.err.println("未指定父级DAO包,创建父级DAO失败");
return;
}
ClassesUtil.write(rules, rules.get("{{baseMapperPackage}}"), rules.get("{{classname}}") + "BaseDAO.xml", Template.BASE_MAPPER_TEMPLATE);
}
public void createBaseDAO(String tableName){
if(StringUtil.isEmptyOrNull(baseDAOPackage)){
System.err.println("未指定base dao包,创建base dao失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{baseDAOPackage}}"), rules.get("{{classname}}") + "BaseDAO.java", Template.BASE_DAO_TEMPLATE);
}
public void createMapper(String tableName) {
if(StringUtil.isEmptyOrNull(mapperPackage)){
System.err.println("未指定DAO包,创建DAO失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{mapperPackage}}"), rules.get("{{classname}}") + "DAO.xml", Template.MAPPER_TEMPLATE);
}
public void createDTO(String tableName) {
if(StringUtil.isEmptyOrNull(pageDTOPackage)){
System.err.println("未指定分页DTO包,创建分页DTO失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{pageDTOPackage}}"), rules.get("{{classname}}") + "PageDTO.java", Template.PAGE_DTO_TEMPLATE);
}
public void createAction(String tableName) {
if(StringUtil.isEmptyOrNull(actionPackage)){
System.err.println("未指定action包,创建action失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{actionPackage}}"), rules.get("{{classname}}") + "Action.java", Template.ACTION_TEMPLATE);
if(StringUtil.isEmptyOrNull(apiActionPackage)){
System.err.println("未指定api action包,创建api action失败");
return;
}
ClassesUtil.write(rules, rules.get("{{apiActionPackage}}"), "API"+rules.get("{{classname}}") + "Action.java", Template.API_ACTION_TEMPLATE);
}
public void createService(String tableName) {
if(StringUtil.isEmptyOrNull(servicePackage)){
System.err.println("未指定service包,创建service失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{servicePackage}}"), rules.get("{{classname}}") + "Service.java", Template.SERVICE_TEMPLATE);
}
public void createDAO(String tableName) {
if(StringUtil.isEmptyOrNull(daoPackage)){
System.err.println("未指定dao包,创建dao失败");
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{daoPackage}}"), rules.get("{{classname}}") + "DAO.java", Template.DAO_TEMPLATE);
}
/**
* 创建子级模型
*/
public void createModel(String tableName) {
if(StringUtil.isEmptyOrNull(modelPackage)){
return;
}
Map rules = handlerRules(tableName);
ClassesUtil.write(rules, rules.get("{{modelPackage}}"), rules.get("{{classname}}") + ".java", Template.CLASS_TEMPLATE);
}
private Map handlerRules(String tableName){
return TemplateUtil.handlerRules(connection,tableName, separator,
baseModelPackage, modelPackage,
baseDAOPackage, daoPackage,
baseMapperPackage, mapperPackage,
servicePackage, actionPackage,
apiActionPackage, pageDTOPackage,
pageDTO,resultDTO,resultDTOPackage);
}
public DBHandler(String url, String username, String password) {
this.connection = DBUtil.getConn(url, username, password);
}
private String separator;
private String baseModelPackage;
private String modelPackage;
private String baseDAOPackage;
private String daoPackage;
private String baseMapperPackage;
private String mapperPackage;
private String servicePackage;
private String actionPackage;
private String apiActionPackage;
private String pageDTOPackage;
private String pageDTO;
private String resultDTO;
private String resultDTOPackage;
public String getSeparator() {
return separator;
}
public void setSeparator(String separator) {
this.separator = separator;
}
public String getBaseModelPackage() {
return baseModelPackage;
}
public void setBaseModelPackage(String baseModelPackage) {
this.baseModelPackage = baseModelPackage;
}
public String getModelPackage() {
return modelPackage;
}
public void setModelPackage(String modelPackage) {
this.modelPackage = modelPackage;
}
public String getBaseDAOPackage() {
return baseDAOPackage;
}
public void setBaseDAOPackage(String baseDAOPackage) {
this.baseDAOPackage = baseDAOPackage;
}
public String getDaoPackage() {
return daoPackage;
}
public void setDaoPackage(String daoPackage) {
this.daoPackage = daoPackage;
}
public String getBaseMapperPackage() {
return baseMapperPackage;
}
public void setBaseMapperPackage(String baseMapperPackage) {
this.baseMapperPackage = baseMapperPackage;
}
public String getMapperPackage() {
return mapperPackage;
}
public void setMapperPackage(String mapperPackage) {
this.mapperPackage = mapperPackage;
}
public String getServicePackage() {
return servicePackage;
}
public void setServicePackage(String servicePackage) {
this.servicePackage = servicePackage;
}
public String getActionPackage() {
return actionPackage;
}
public void setActionPackage(String actionPackage) {
this.actionPackage = actionPackage;
}
public String getApiActionPackage() {
return apiActionPackage;
}
public void setApiActionPackage(String apiActionPackage) {
this.apiActionPackage = apiActionPackage;
}
public String getPageDTOPackage() {
return pageDTOPackage;
}
public void setPageDTOPackage(String pageDTOPackage) {
this.pageDTOPackage = pageDTOPackage;
}
public String getPageDTO() {
return pageDTO;
}
public void setPageDTO(String pageDTO) {
this.pageDTO = pageDTO;
}
public String getResultDTO() {
return resultDTO;
}
public void setResultDTO(String resultDTO) {
this.resultDTO = resultDTO;
}
public String getResultDTOPackage() {
return resultDTOPackage;
}
public void setResultDTOPackage(String resultDTOPackage) {
this.resultDTOPackage = resultDTOPackage;
}
}
四、 使用
1) 打jar包 maven打jar包 傻瓜式操作 就不上图了
2)将jar包放入maven本地库
3)在项目中添加 就是依赖打的这个jar包 名字和包如果不是我这么定义的 请按照自己的来
com.cms
cms
1.0-SNAPSHOT
4)项目中创建个测试类
package com.love.util;
import com.cms.DBHandler;
public class Test {
public static void main(String[] args) {
DBHandler handler = new DBHandler("jdbc:log4jdbc:mysql:///love?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false",
"root","admin");
//数据库表的分隔符 如果你的表是 sys_service 那么就传_ 如果没有 随便传或者空字符串都行
handler.setSeparator("_");
/**
*父级模型的包 为什么要有父级模型?
* 是为了解决项目过程中改表结构
* 我们使用时只是有子模型 可以子模型中定义一些属性来方便我们开发或者给前端返回结果
* 如果后期改表了就不用去动子模型 而父级模型我们一般不使用 只是用来与数据库一一映射的
*/
handler.setBaseModelPackage("com.love.entity.base");
/**
* 子模型的包
*/
handler.setModelPackage("com.love.entity");
/**
* 父级dao所在的包
* 跟父级模型同理 基本的CRUD跟数据库结构挂钩 数据库表改了 那么dao肯定也要改
*/
handler.setBaseDAOPackage("com.love.dao.base");
/**
* 子dao所在的包
*/
handler.setDaoPackage("com.love.dao");
/**
* 父级dao的映射文件xml的包
* 根据习惯不同 有些喜欢把dao和xml合在一起 有些喜欢分开 那这里就分开 实用性稍微强一些
*/
handler.setBaseMapperPackage("com.love.dao.base");
/**
* 子级dao的映射文件xml的包
*/
handler.setMapperPackage("com.love.dao");
/**
* service所在的包
*/
handler.setServicePackage("com.love.service");
/**
* 后台控制器所在的包
*/
handler.setActionPackage("com.love.controller");
/**
* 前端api控制器所在的包
*/
handler.setApiActionPackage("com.love.controller.api");
/**
* dto所在的包
* 这个dto是所有模型的高级查询+分页dto 一般高级查询加分页功能都会在一起 所以一般会创建一个dto来专门做高级查询+分页
* 而且这个dto会继承setPageDTO的参数对应的类
*/
handler.setPageDTOPackage("com.love.dto");
/**
* 结果对象所在的包 这个我单独在下面罗列 单独贴图
*/
handler.setResultDTOPackage("com.love.dto");
/**
* 项目中自己的分页DTO基类 封装了分页和结果的 单独下面贴图
*/
handler.setPageDTO("PageDTO");
/**
* 结果类 单图贴图
*/
handler.setResultDTO("ResultDTO");
/**
* 生成所有表的所有 就是模型->控制器全部
*/
// handler.auto();
/**
* 生成某一张表的全部
*/
handler.autoOneByTableName("table");
//这个方法就是改了表之后需要重新生成模型和doa的和xml的方法
handler.createBaseModelAndBaseMapper("account");
//还有一些单独生成某一个文件的方法
}
}
5) PageDTO 分页dto基类
package com.love.dto;
import java.util.ArrayList;
import java.util.List;
public class PageDTO {
private long page;//当前页
private long pageSize;//每页显示条数
private long total;//总记录数
private long pageCount;//尾页
private List data;//数据集
public PageDTO() {
}
public long getPage() {
return page;
}
public void setPage(long page) {
this.page = page;
}
public long getPageSize() {
return this.pageSize;
}
public void setPageSize(long pageSize) {
this.pageSize = pageSize;
}
public long getTotal() {
return this.total;
}
public void setTotal(long total) {
this.total = total;
if (this.pageSize < 1L || this.pageSize > 100L) {
this.pageSize = 10L;
}
this.pageCount = total / this.pageSize + (long)(total % this.pageSize != 0L ? 1 : 0);
if (this.page > this.pageCount) {
this.page = this.pageCount;
}
if (this.page < 1L) {
this.page = 1L;
}
}
public long getPageCount() {
return this.pageCount;
}
public void setPageCount(long pageCount) {
this.pageCount = pageCount;
}
public List getData() {
if (null == this.data) {
this.data = new ArrayList();
}
return this.data;
}
public void setData(List dataList) {
this.data = dataList;
}
public long getFromRowIndex() {
return (this.page - 1L) * this.pageSize;
}
}
6) ResultDTO结果类
package com.love.dto;
import java.io.Serializable;
public class ResultDTO implements Serializable {
private static final long serialVersionUID = 1L;
private int code;//200或其他 200是正确
private String msg;//操作信息
private Object data;//查询单个获取的信息
private String errMsg;//错误消息,只有错误的时候才有
private ResultDTO() {
}
public static ResultDTO putSuccess(String msg,Object data) {
ResultDTO dto = new ResultDTO();
dto.code = 200;
dto.msg = msg;
dto.data = data;
return dto;
}
public static ResultDTO putSuccess(String msg) {
ResultDTO dto = new ResultDTO();
dto.code = 200;
dto.msg = msg;
dto.data = null;
return dto;
}
public static ResultDTO put400(String msg) {
return putError(msg, msg,400);
}
public static ResultDTO put400(String msg,String errMsg) {
return putError(msg, errMsg,400);
}
public static ResultDTO put401(String msg,String errMsg) {
return putError(msg, errMsg,401);
}
public static ResultDTO put500(String msg,String errMsg) {
return putError(msg, errMsg,500);
}
public static ResultDTO putError(String errMsg) {
ResultDTO dto = new ResultDTO();
dto.code = 500;
dto.msg = null;
dto.data = null;
dto.errMsg = errMsg;
return dto;
}
public static ResultDTO putError(String msg,String errMsg,int code) {
ResultDTO dto = new ResultDTO();
dto.code = code;
dto.msg = msg;
dto.data = null;
dto.errMsg = errMsg;
return dto;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}
五、 结果
1) 父级模型
2)子级模型 自定义属性写在这个模型中,下述方法不会覆盖这个文件
3) 父级dao
4)子级dao
5)父级xml dao的sql不要写在这个xml
6)子级xml 自定义的sql写在这里
7)service logicWhereSql和logicSetSql都是逻辑查询和逻辑删除相关的,如果表有逻辑字段 deleted -1代表删除 那么:
logicWhereSql = "deleted != -1"
logicSetSql = "set deleted = -1"
8)控制器 api的控制器跟这个一样
9)dto 分页类