告别编写基础的增删改查代码
告别编写基础的增删改查代码
一、 说明
1.本文基本帮你实现不用编写基础的增删改查代码 注意是“基础”的,你只需要写一个实体类,其他都可以自动生成包括 mapper、dao、service、controller、建表sql。
2.springboot版本:2.0.5 、mybatis:1.3.2 、swagger:2.8.0。
3.本文代码目前为定制化代码 例如mapper文件命名规范、controller请求路径等可根据自己项目的风格自行调整。
二、代码
1.生成mapper文件
文件命名规则可根据自己需要更改、默认采用“id”作为主键。
import java.lang.reflect.Field; /** * mapper.xml生成类 * 注意:所有实体主键假定为id */ public class MapperUtils { public static boolean generateMapper(Class clazz){ StringBuilder sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n") .append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" ") .append("\"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n") .append("\n"); sb.append("<mapper namespace=\"").append(clazz.getSimpleName()).append("\">\n"); sb.append("\t<resultMap id=\"resultMap\" type=\"").append(clazz.getName()).append("\">\n"); sb.append("\t\t<id column=\"id\" property=\"id\"/>\n"); Field[] fields = clazz.getDeclaredFields(); StringBuilder associations = new StringBuilder(); /**生成resultMap中result*/ for (Field field : fields) { String fieldName = field.getName(); if(field.getGenericType().getTypeName().indexOf(".model.") != -1){ //外键 associations.append("\t\t<association property=\"").append(fieldName) .append("\" javaType=\"").append(field.getGenericType().getTypeName()).append("\">\n"); associations.append("\t\t\t<id column=\"").append(BaseGeneratorUtils.camel2Underline(fieldName)+"_id").append("\" property=\"id\"/>\n"); associations.append("\t\t</association>\n"); }else if(!"id".equals(fieldName)){ sb.append("\t\t<result column=\"").append(BaseGeneratorUtils.camel2Underline(fieldName)) .append("\" property=\"").append(fieldName).append("\"/>\n"); } } sb.append(associations); sb.append("\t</resultMap>\n\n"); /**生成 sql columns*/ sb.append("\t<sql id=\"columns\">\n\t\t"); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String columnName = BaseGeneratorUtils.getColumn(field); sb.append("`").append(columnName).append("`"); if(i < fields.length-1){ sb.append(","); } } sb.append("\n\t</sql>\n\n"); /**生成 sql properties*/ sb.append("\t<sql id=\"properties\">\n\t\t"); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String columnName = BaseGeneratorUtils.getFieldName(field); sb.append("#{").append(columnName).append("}"); if(i < fields.length-1){ sb.append(","); } } sb.append("\n\t</sql>\n\n"); /**生成insert*/ sb.append("\t<insert id=\"insert\">\n"); sb.append("\t\tinsert into ").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())) .append(" (<include refid=\"columns\"></include>)\n"); sb.append("\t\tvalues (<include refid=\"properties\"></include>)\n"); sb.append("\t</insert>\n\n"); /**生成updateByPrimaryKey*/ sb.append("\t<update id=\"updateByPrimaryKey\">\n"); sb.append("\t\tupdate ").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())).append("\n"); sb.append("\t\t<set>\n"); for (Field field : fields) { sb.append("\t\t\t").append(BaseGeneratorUtils.getColumn(field)).append(" = ") .append("#{").append(BaseGeneratorUtils.getFieldName(field)).append("},\n"); } sb.append("\t\t</set>\n"); sb.append("\t\twhere id = #{id}\n"); sb.append("\t</update>\n\n"); /**生成updateByPrimaryKeySelective*/ sb.append("\t<update id=\"updateByPrimaryKeySelective\">\n"); sb.append("\t\tupdate ").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())).append("\n"); sb.append("\t\t<set>\n"); for (Field field : fields) { sb.append("\t\t\t<if test=\""); if(field.getGenericType().getTypeName().indexOf(".model.") != -1){ sb.append(field.getName()).append(" != null and ").append(field.getName()).append(".id != null"); }else{ sb.append(field.getName()).append(" != null"); } sb.append("\">\n"); sb.append("\t\t\t\t").append(BaseGeneratorUtils.getColumn(field)).append(" = ") .append("#{").append(BaseGeneratorUtils.getFieldName(field)).append("},\n"); sb.append("\t\t\t</if>\n"); } sb.append("\t\t</set>\n"); sb.append("\t\twhere id = #{id}\n"); sb.append("\t</update>\n\n"); /**生成deleteByPrimaryKey*/ sb.append("\t<delete id=\"deleteByPrimaryKey\">\n"); sb.append("\t\tdelete from ").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())).append(" where id = #{id}\n"); sb.append("\t</delete>\n"); /**生成selectByPrimaryKey*/ sb.append("\t<select id=\"selectByPrimaryKey\" resultMap=\"resultMap\">\n"); sb.append("\t\tselect * from ").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())).append(" where id = #{id}\n"); sb.append("\t</select>\n\n"); /**生成selectByExample*/ sb.append("\t<select id=\"selectByExample\" resultMap=\"resultMap\">\n"); sb.append("\t\tselect * from ").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())).append("\n"); sb.append("\t\t<where>\n"); for (Field field : fields) { sb.append("\t\t\t<if test=\""); if(field.getGenericType().getTypeName().indexOf(".model.") != -1){ sb.append(field.getName()).append(" != null and ").append(field.getName()).append(".id != null"); }else{ sb.append(field.getName()).append(" != null"); } sb.append("\">\n"); sb.append("\t\t\t\tand ").append(BaseGeneratorUtils.getColumn(field)).append(" = ") .append("#{").append(BaseGeneratorUtils.getFieldName(field)).append("}\n"); sb.append("\t\t\t</if>\n"); } sb.append("\t\t</where>\n"); sb.append("\t</select>\n\n"); sb.append("</mapper>"); //保存至文件中 String folderPath = clazz.getResource("").toString().replace("/target/classes", "/src/main/resources/mybatis"); folderPath=folderPath.replace("com/surfilter/eyes/", "").replace("entity/", "");//文件生成路径定制化 替换字符串 String filePath = folderPath+clazz.getSimpleName()+"Dao.xml"; return BaseGeneratorUtils.writeIntoFile(filePath, sb.toString()); } }
2.BaseDao
所有dao层默认继承BaseDao。
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.List; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component public class BaseDao<E> { private static final Logger log = LoggerFactory.getLogger(BaseDao.class); private Class<E> entityClass; @Resource private SqlSessionTemplate st; private final static String INSERT_KEY = "insert"; private final static String INSERT_SELECTIVE_KEY = "insertSelective"; private final static String UPDATE_BY_PRIMARYKEY_KEY = "updateByPrimaryKey"; private final static String UPDATE_BY_PRIMARYKEY_SELECTIVE_KEY = "updateByPrimaryKeySelective"; private final static String DELETE_BY_PRIMARYKEY_KEY = "deleteByPrimaryKey"; private final static String SELECT_BY_PRIMARYKEY_KEY = "selectByPrimaryKey"; private final static String SELECT_BY_PRIMARYKEY_KEY_FOR_UPDATE = "selectByPrimaryKeyForUpdate"; private final static String SELECT_BY_EXAMPLE_KEY = "selectByExample"; /** * 新增加 * @param entity */ public int insert(E entity){ if(log.isDebugEnabled()){ log.debug("Base dao ,insert, entity = " + getRealKey(INSERT_KEY) ); } return st.insert( getRealKey(INSERT_KEY),entity ); } public int insertSelective(E entity){ return st.insert( getRealKey(INSERT_SELECTIVE_KEY),entity ); } public int updateByPrimaryKey(E entity){ return st.update(getRealKey(UPDATE_BY_PRIMARYKEY_KEY), entity); } public int updateByPrimaryKeySelective(E entity){ return st.update(getRealKey(UPDATE_BY_PRIMARYKEY_SELECTIVE_KEY), entity); } public int deleteByPrimaryKey(Object id){ return st.delete(getRealKey(DELETE_BY_PRIMARYKEY_KEY), id); } /** * 通过实体主键获取该实体 * @see SELECT_BY_PRIMARYKEY_KEY * @param id * @return */ public E selectByPrimaryKey(Object id){ return st.selectOne(getRealKey(SELECT_BY_PRIMARYKEY_KEY), id); } /** * 通过实体主键获取该实体,并加锁 */ public E selectByPrimaryKeyForUpdate(Object id){ return st.selectOne(getRealKey(SELECT_BY_PRIMARYKEY_KEY_FOR_UPDATE), id); } public <E> List<E> selectByFilter(Object filter){ return st.selectList(getRealKey(SELECT_BY_EXAMPLE_KEY), filter); } String getEntityClassName() { return getEntityClass().getSimpleName(); } public String getRealKey(String key){ StringBuilder sb = new StringBuilder(); sb.append(getEntityClassName()).append(".").append(key); return sb.toString(); } public Class<E> getEntityClass() { if (entityClass != null) { return entityClass; } Type type = getClass().getGenericSuperclass(); if (type instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) type; if (paramType.getActualTypeArguments().length == 2) { // likely dealing with -> new // EntityHome<Person>().getEntityClass() if (paramType.getActualTypeArguments()[1] instanceof TypeVariable) { throw new IllegalArgumentException( "Could not guess entity class by reflection"); } // likely dealing with -> new Home<EntityManager, Person>() { // ... }.getEntityClass() else { entityClass = (Class<E>) paramType.getActualTypeArguments()[1]; } } else { // likely dealing with -> new PersonHome().getEntityClass() // where PersonHome extends EntityHome<Person> entityClass = (Class<E>) paramType.getActualTypeArguments()[0]; } } else { throw new IllegalArgumentException( "Could not guess entity class by reflection"); } return entityClass; } }
3.BaseService
默认注入BaseDao
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.surfilter.eyes.common.core.dao.BaseDao; @Component public class BaseService { @Autowired private BaseDao baseDao; public <E> void createEntity(E entity){ baseDao.insert(entity); } public <E> void deleteEntityById(final String id){ baseDao.deleteByPrimaryKey(id); } public <E> void updateEntityById(E entity){ baseDao.updateByPrimaryKey(entity); } public <E> void updateEntitySelectiveById(E entity){ baseDao.updateByPrimaryKeySelective(entity); } public <E> E getEntityById(Class<E> c,final String id){ return (E) baseDao.selectByPrimaryKey(id); } }
4.生成dao、service、controller文件
本文默认实现了新增方法其他方法可仿照自己增加或者直接使用BaseService代码,controller层默认注入相关service,service默认注入相关dao,service默认继承BaseService。
/** * 生成java文件 * */ public class javaUtils { /** * 生成contrller文件 * @Title: generateController * @Description: TODO * @param: @param clazz * @param: @return * @return: boolean * @author: haoqingshuang * @date: 2018年11月19日 下午5:59:13 */ public static boolean generateController(Class clazz){ StringBuilder sb = new StringBuilder(); String javaTxt = BaseGeneratorUtils.readJavaFile(clazz); String lowerJavaName = BaseGeneratorUtils.captureName(clazz.getSimpleName()); String prevPackage = clazz.getName().split("\\.")[clazz.getName().split("\\.").length-3]; String chineseName = BaseGeneratorUtils.getJavaAnnotation(javaTxt, clazz.getSimpleName()); String crePackage = clazz.getName().replace("entity", "controller"); sb.append("package ").append(crePackage.substring(0,crePackage.lastIndexOf("."))).append(";\n\n"); sb.append("import ").append(clazz.getName()).append(";\n"); sb.append("import org.springframework.web.bind.annotation.RestController;\n"); sb.append("import org.springframework.web.bind.annotation.RequestMapping;\n"); sb.append("import io.swagger.annotations.Api;\n\n"); sb.append("import org.slf4j.Logger;\n"); sb.append("import org.slf4j.LoggerFactory;\n"); sb.append("import "+clazz.getName().replace("entity", "service")).append("Service;\n"); sb.append("import org.springframework.beans.factory.annotation.Autowired;\n"); sb.append("import com.surfilter.eyes.common.core.entity.PageResult;\n"); sb.append("import io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiOperation;\n"); sb.append("import io.swagger.annotations.ApiResponse;\nimport io.swagger.annotations.ApiResponses;\n"); sb.append("import org.springframework.web.bind.annotation.PostMapping;\n"); sb.append("import com.surfilter.eyes.dago.exception.CommonException;\n"); sb.append("/**\n"); sb.append(" * ").append(chineseName).append("\tcontroller\n"); sb.append(" */\n"); sb.append("@RestController\n"); sb.append("@RequestMapping(\"${versionName}/").append(BaseGeneratorUtils.camel2Slantline(lowerJavaName)).append("\")\n"); sb.append("@Api(tags = \""+chineseName+"\")\n"); sb.append("public class ").append(clazz.getSimpleName()).append("Controller {\n\n"); sb.append("\tprivate static final Logger logger = LoggerFactory.getLogger("+clazz.getSimpleName()+"Controller.class);\n\n"); sb.append("\n"); sb.append("\t@Autowired\n"); sb.append("\tprivate ").append(clazz.getSimpleName()+"Service ").append(BaseGeneratorUtils.captureName(clazz.getSimpleName()+"Service;\n\n")); sb.append("\t@PostMapping(\"/create\")\n"); sb.append("\t@ApiOperation(\"新增\")\n"); sb.append("\t@ApiResponses(value = {@ApiResponse(code = 200, message = \"请求成功\", response = String.class, responseContainer = \"String\")})\n"); sb.append("\tpublic PageResult create"+clazz.getSimpleName()+"("+clazz.getSimpleName()+" model) {\n"); sb.append("\t\tlong st = System.currentTimeMillis();\n"); sb.append("\t\tPageResult pageResult = new PageResult();\n"); sb.append("\t\ttry {\n"); sb.append("\t\t\tpageResult.setMsg("+BaseGeneratorUtils.captureName(clazz.getSimpleName()+"Service.save")).append(clazz.getSimpleName()+"(model));\n"); sb.append("\t\t\tpageResult.setStatus(1);\n"); sb.append("\t\t} catch (CommonException e) {\n"); sb.append("\t\t\tpageResult.setMsg(e.getMessage());\n"); sb.append("\t\t\tpageResult.setStatus(2);\n"); sb.append("\t\t}\n"); sb.append("\t\tpageResult.setTime(System.currentTimeMillis() - st);\n"); sb.append("\t\treturn pageResult;\n"); sb.append("\t}\n"); sb.append("}"); String folderPath = clazz.getResource("").toString().replace("/target/classes", "/src/main/java").replace("/model", "").replace("entity", "controller"); String filePath = folderPath + clazz.getSimpleName() + "Controller.java"; return BaseGeneratorUtils.writeIntoFile(filePath, sb.toString()); } /** * 生成dao 继承BaseDao接口 * @Title: generateDao * @Description: TODO * @param: @param clazz * @param: @return * @return: boolean * @author: haoqingshuang * @date: 2018年11月19日 下午3:36:58 */ public static boolean generateDao(Class clazz){ StringBuilder sb = new StringBuilder(); String javaTxt = BaseGeneratorUtils.readJavaFile(clazz); String lowerJavaName = BaseGeneratorUtils.captureName(clazz.getSimpleName()); String prevPackage = clazz.getName().split("\\.")[clazz.getName().split("\\.").length-3]; String chineseName = BaseGeneratorUtils.getJavaAnnotation(javaTxt, clazz.getSimpleName())+"dao"; //sb.append("package ").append(clazz.getName().substring(0, clazz.getName().indexOf("Model")).replace("entity", "repository")).append("Dao;\n\n"); String crePackage = clazz.getName().replace("entity", "repository"); sb.append("package ").append(crePackage.substring(0,crePackage.lastIndexOf("."))).append(";\n\n"); sb.append("import ").append(clazz.getName()).append(";\n"); sb.append("import com.surfilter.eyes.common.core.dao.BaseDao;\n"); sb.append("import org.springframework.stereotype.Repository;\n"); sb.append("/**\n"); sb.append(" * ").append(chineseName).append("\n"); sb.append(" */\n"); sb.append("@Repository\n"); sb.append("public class ").append(clazz.getSimpleName()).append("Dao extends BaseDao<").append(clazz.getSimpleName()).append(">{\n"); sb.append("\n"); sb.append("}"); String folderPath = clazz.getResource("").toString().replace("/target/classes", "/src/main/java").replace("/model", "").replace("entity", "repository"); String filePath = folderPath + clazz.getSimpleName() + "Dao.java"; return BaseGeneratorUtils.writeIntoFile(filePath, sb.toString()); } /** * 生成service文件 目前只写了insert方法 并注入了dao层 * @Title: generateService * @Description: TODO * @param: @param clazz * @param: @return * @return: boolean * @author: haoqingshuang * @date: 2018年11月19日 下午4:40:05 */ public static boolean generateService(Class clazz){ StringBuilder sb = new StringBuilder(); String javaTxt = BaseGeneratorUtils.readJavaFile(clazz); String lowerJavaName = BaseGeneratorUtils.captureName(clazz.getSimpleName()); String prevPackage = clazz.getName().split("\\.")[clazz.getName().split("\\.").length-3]; String chineseName = BaseGeneratorUtils.getJavaAnnotation(javaTxt, clazz.getSimpleName()); //sb.append("package ").append(clazz.getName().substring(0, clazz.getName().indexOf("Model")).replace("entity", "repository")).append("Dao;\n\n"); String crePackage = clazz.getName().replace("entity", "service"); sb.append("package ").append(crePackage.substring(0,crePackage.lastIndexOf("."))).append(";\n\n"); sb.append("import ").append(clazz.getName()).append(";\n"); sb.append("import org.springframework.stereotype.Service;\n"); sb.append("import org.springframework.beans.factory.annotation.Autowired;\n"); sb.append("import org.slf4j.Logger;\n"); sb.append("import org.slf4j.LoggerFactory;\n"); sb.append("import org.springframework.transaction.annotation.Transactional;\n"); sb.append("import com.surfilter.eyes.dago.exception.CommonException;\n"); sb.append("import com.surfilter.eyes.common.core.service.BaseService;\n"); //import com.surfilter.eyes.dago.entity.integration.scheduling.HaoTestModel; //import com.surfilter.eyes.dago.repository.integration.scheduling.DagoTestModelDao; sb.append("import "+clazz.getName().replace("entity", "repository")).append("Dao;\n"); sb.append("/**\n"); sb.append(" * ").append(chineseName).append("\tservice\n"); sb.append(" */\n"); sb.append("@Service\n"); sb.append("public class ").append(clazz.getSimpleName()).append("Service extends BaseService"); sb.append("{\n\n"); sb.append("\tprivate static final Logger logger = LoggerFactory.getLogger("+clazz.getSimpleName()+"Service.class);\n\n"); sb.append("\t@Autowired\n"); sb.append("\tprivate ").append(clazz.getSimpleName()+"Dao ").append(BaseGeneratorUtils.captureName(clazz.getSimpleName()+"Dao;\n\n")); sb.append("\t/**\n"); sb.append("\t * ").append("新增"+chineseName+"\n"); sb.append("\t */\n"); sb.append("\t@Transactional(rollbackFor = Exception.class)\n"); sb.append("\tpublic String save"+clazz.getSimpleName()+"("+clazz.getSimpleName()+" model)throws CommonException {\n"); sb.append("\t\tif(null==model){\n"); sb.append("\t\t\tthrow new CommonException(\"参数错误,请检查!\");\n"); sb.append("\t\t}\n"); sb.append("\t\t"+BaseGeneratorUtils.captureName(clazz.getSimpleName()+"Dao")+".insert(model);\n"); sb.append("\t\treturn \"新增成功!\";\n"); sb.append("\t}\n\n"); sb.append("}"); String folderPath = clazz.getResource("").toString().replace("/target/classes", "/src/main/java").replace("/model", "").replace("entity", "service"); String filePath = folderPath + clazz.getSimpleName() + "Service.java"; return BaseGeneratorUtils.writeIntoFile(filePath, sb.toString()); } }
5.生成建表sql语句
权限语句、菜单语句可参考建表语句自行编写。
import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Type; import org.apache.commons.lang.StringUtils; import org.hibernate.validator.constraints.Length; public class SqlUtils { public static String generateDdl(Class clazz) { StringBuilder sb = new StringBuilder("CREATE TABLE `").append(BaseGeneratorUtils.camel2Underline(clazz.getSimpleName())) .append("` (").append("\n"); String javaTxt = BaseGeneratorUtils.readJavaFile(clazz); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { String fieldName = BaseGeneratorUtils.camel2Underline(field.getName()); if(field.getGenericType().getTypeName().indexOf(".model.") != -1){ fieldName += "_id"; } sb.append(" `").append(fieldName).append("` "); /** 判断类型信息 */ Type type = field.getType(); switch (type.getTypeName()) { case "java.lang.String": sb.append("varchar("); // 对于字符串考虑注解 int max = 255; Annotation[] annotations = field.getAnnotations(); for(Annotation annotation : annotations){ if(annotation.annotationType().getName() == "org.hibernate.validator.constraints.Length"){ Length length = (Length) annotation; max = length.max()>0?length.max():max; } } sb.append(max).append(") "); break; case "java.util.Date": sb.append("datetime "); break; case "int": case "java.lang.Integer": case "long": case "java.lang.Long": sb.append("int(11) "); break; case "double": case "java.lang.Double": sb.append("double "); break; default: // 关联对象、玫举 sb.append("varchar(32) "); } //注解 Annotation[] annotations = field.getAnnotations(); for(Annotation annotation : annotations){ switch(annotation.annotationType().getName()){ case "org.hibernate.validator.constraints.NotEmpty": case "org.hibernate.validator.constraints.NotBlank": case "javax.validation.constraints.NotNull": sb.append("NOT NULL "); } } // 注释 String note = BaseGeneratorUtils.getJavaAnnotation(javaTxt, field.getName()); if(StringUtils.isNotEmpty(note)){ sb.append("COMMENT '").append(note).append("'"); } sb.append(",\n"); } sb.append(" PRIMARY KEY (`id`)").append("\n").append(") ENGINE=InnoDB DEFAULT CHARSET=utf8 "); // 表注释 String clazzNote = BaseGeneratorUtils.getJavaAnnotation(javaTxt, clazz.getSimpleName()); if(StringUtils.isNotEmpty(clazzNote)){ sb.append("COMMENT='").append(clazzNote).append("';"); }else{ sb.append(";"); } return sb.toString(); } }
6.基础文件生成类
import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 根据实体生成相应资源 * 1. 所有实体类均默认主键为id * 2. 生成的相关的sql * 3. 生成代码过程中,会参考实体类的注释及注解(\@Length \@NotBlank \@NotEmpty),所以先完善注解再生成 * 目前可生成的代码有: * mapper、controller、sql(建表语句) */ public class SourceGenerateUtils { private static final Logger logger = LoggerFactory.getLogger(SourceGenerateUtils.class); public static void generate(Class clazz){ if(MapperUtils.generateMapper(clazz)){ logger.info(clazz.getSimpleName()+"Dao.xml 文件已生成"); }else{ logger.info(clazz.getSimpleName()+"Dao.xml 文件已存在,未重新生成"); } if(javaUtils.generateDao(clazz)){ logger.info(clazz.getSimpleName()+"Dao.java 文件已生成"); }else{ logger.info(clazz.getSimpleName()+"Dao.java 文件已存在,未重新生成"); } if(javaUtils.generateService(clazz)){ logger.info(clazz.getSimpleName()+"Service.java 文件已生成"); }else { logger.info(clazz.getSimpleName()+"Service.java 文件已存在,未重新生成"); } if(javaUtils.generateController(clazz)){ logger.info(clazz.getSimpleName()+"Controller.java 文件已生成"); }else { logger.info(clazz.getSimpleName()+"Controller.java 文件已存在,未重新生成"); } logger.info("正在生成Sql语句,sql仅供参考,注意审查..."); logger.info("#建表语句\n"+SqlUtils.generateDdl(clazz)); } }
7.对象转化为Map形式
把对象转化为Map形式,key类型String;value类型Object(只推荐在Mybatis dao层中使用)。
import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 把对象转化为Map形式,key类型String;value类型Object(只推荐在Mybatis dao层中使用) * */ public class MybatisExample2MapUtils { private final static Log log = LogFactory.getLog(MybatisExample2MapUtils.class); /** * 把对象转化为Map形式,key String;value Object * @param bean * @return */ public static Map<?,?> example2Map(final Object bean){ if(bean == null){ return (new HashMap<Object, Object>()); } final Map<String, Object> result = new HashMap<String, Object>(); final PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean); for (PropertyDescriptor descriptor : descriptors) { final String name = descriptor.getName(); if(PropertyUtils.getReadMethod(descriptor) != null){ try { final Object tempObj = PropertyUtils.getProperty(bean, name); //log.debug("第二层对象解析:" + tempObj); if(tempObj == null){ continue; } //log.debug("属性名称:" + tempObj.getClass().getName()); if(tempObj.getClass().getName().startsWith("com.surfilter")){ final PropertyDescriptor[] descriptors2 = PropertyUtils.getPropertyDescriptors(tempObj); for (PropertyDescriptor descriptor2 : descriptors2) { final String name2 = descriptor2.getName(); if(PropertyUtils.getReadMethod(descriptor) != null){ Object obj2 = PropertyUtils.getProperty(tempObj, name2); if(obj2 == null){ continue; } result.put(name+"_"+name2, obj2); } } }else{ result.put(name, tempObj); } } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { log.error("Bean转化为Map错误! Message:"+ e.getMessage()); e.printStackTrace(); } } } if(log.isDebugEnabled()){ log.debug("转化结果=" + result); } return result ; } }
8.实体类
注意本文使用了lombok
实体类注释、属性注释请采用如下格式,其他格式的注释可能存在取不到的情况(未测试),类注释用于swagger接口说明、controller、service、dao注释。属性注释主要用于生成sql语句的字段描述。
/**
*注释内容XXX
*/
请在相关属性上添加@Length 、@NotBlank 、@NotEmpty、@Length(max = 200)注解,用于生成sql判断是否为空、及长度,还可作为实体类验证使用。
测试实体类如下:直接在该类下运行main方法即可 注意查看控制台输出。
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import lombok.Data; import org.hibernate.validator.constraints.Length; import com.surfilter.eyes.dago.utils.generator.SourceGenerateUtils; /** * 测试实体 */ @Data @ApiModel(value = "HaoTestModel", description = "测试实体") public class HaoTestModel { /** * 编号 */ @NotEmpty @Length(max = 200) @ApiModelProperty(value = "编号", required = true) private String id; /** * 姓名 */ @NotEmpty @Length(max = 200) @ApiModelProperty(value = "姓名", required = true) private String name; /** * 年龄 */ @NotNull @ApiModelProperty(value = "用户类别", required = true) private Integer userType; public static void main(String[] args) { SourceGenerateUtils.generate(HaoTestModel.class); } }
三、生成文件展示
1.生成的mapper文件
<?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="HaoTestModel"> <resultMap id="resultMap" type="com.surfilter.eyes.dago.entity.integration.scheduling.HaoTestModel"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="user_type" property="userType"/> </resultMap> <sql id="columns"> `id`,`name`,`user_type` </sql> <sql id="properties"> #{id},#{name},#{userType} </sql> <insert id="insert"> insert into hao_test_model (<include refid="columns"></include>) values (<include refid="properties"></include>) </insert> <update id="updateByPrimaryKey"> update hao_test_model <set> id = #{id}, name = #{name}, user_type = #{userType}, </set> where id = #{id} </update> <update id="updateByPrimaryKeySelective"> update hao_test_model <set> <if test="id != null"> id = #{id}, </if> <if test="name != null"> name = #{name}, </if> <if test="userType != null"> user_type = #{userType}, </if> </set> where id = #{id} </update> <delete id="deleteByPrimaryKey"> delete from hao_test_model where id = #{id} </delete> <select id="selectByPrimaryKey" resultMap="resultMap"> select * from hao_test_model where id = #{id} </select> <select id="selectByExample" resultMap="resultMap"> select * from hao_test_model <where> <if test="id != null"> and id = #{id} </if> <if test="name != null"> and name = #{name} </if> <if test="userType != null"> and user_type = #{userType} </if> </where> </select> </mapper>
2.生成的dao文件
import com.surfilter.eyes.dago.entity.integration.scheduling.HaoTestModel; import com.surfilter.eyes.common.core.dao.BaseDao; import org.springframework.stereotype.Repository; /** * 测试实体dao */ @Repository public class HaoTestModelDao extends BaseDao<HaoTestModel>{ }
3.生成的service文件
import com.surfilter.eyes.dago.entity.integration.scheduling.HaoTestModel; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; import com.surfilter.eyes.dago.exception.CommonException; import com.surfilter.eyes.common.core.service.BaseService; import com.surfilter.eyes.dago.repository.integration.scheduling.HaoTestModelDao; /** * 测试实体 service */ @Service public class HaoTestModelService extends BaseService{ private static final Logger logger = LoggerFactory.getLogger(HaoTestModelService.class); @Autowired private HaoTestModelDao haoTestModelDao; /** * 新增测试实体 */ @Transactional(rollbackFor = Exception.class) public String saveHaoTestModel(HaoTestModel model)throws CommonException { if(null==model){ throw new CommonException("参数错误,请检查!"); } haoTestModelDao.insert(model); return "新增成功!"; } }
4.生成的controller文件
import com.surfilter.eyes.dago.entity.integration.scheduling.HaoTestModel; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; import io.swagger.annotations.Api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.surfilter.eyes.dago.service.integration.scheduling.HaoTestModelService; import org.springframework.beans.factory.annotation.Autowired; import com.surfilter.eyes.common.core.entity.PageResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.springframework.web.bind.annotation.PostMapping; import com.surfilter.eyes.dago.exception.CommonException; /** * 测试实体 controller */ @RestController @RequestMapping("${versionName}/hao/test/model") @Api(tags = "测试实体") public class HaoTestModelController { private static final Logger logger = LoggerFactory.getLogger(HaoTestModelController.class); @Autowired private HaoTestModelService haoTestModelService; @PostMapping("/create") @ApiOperation("新增") @ApiResponses(value = {@ApiResponse(code = 200, message = "请求成功", response = String.class, responseContainer = "String")}) public PageResult createHaoTestModel(HaoTestModel model) { long st = System.currentTimeMillis(); PageResult pageResult = new PageResult(); try { pageResult.setMsg(haoTestModelService.saveHaoTestModel(model)); pageResult.setStatus(1); } catch (CommonException e) { pageResult.setMsg(e.getMessage()); pageResult.setStatus(2); } pageResult.setTime(System.currentTimeMillis() - st); return pageResult; } }
5.生成的sql文件
CREATE TABLE `hao_test_model` ( `id` varchar(200) COMMENT '编号', `name` varchar(200) COMMENT '姓名', `user_type` int(11) NOT NULL COMMENT '年龄', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试实体';
6.文件生成明细
四、注意
1.如果XXXDao、XXXService、XXXContrller、mapper文件已生成 则不会再生成,防止发生覆盖后悔莫及,请放心运行main方法。
2.类注释请一定书写,很多地方都用到了类注释。
3.文中controller、service只写了一个添加的方法,可以写一个BaseController、BaseService 并继承该类。
4.如有问题欢迎评论交流。