AdminEAP为是基于AdminLTE改造的后台管理框架,包含了组件集成、CURD增删改查、系统工具、工作流、系统权限与安全等基本的系统管理功能和各种交互demo,项目源码已经在Github上开源,并部署到阿里云。
Github : https://github.com/bill1012/AdminEAP
AdminEAP 官网: http://www.admineap.com
本文介绍使用freemarker模板,在AdminEAP框架下实现代码生成器,以实现CURD功能的快速生成,借助于代码生成器,基础的开发可以节约大量的时间,同时保持了编码的一致性。
使用步骤
下面以Generator实体为例,介绍代码生成器的使用
1、编写实体类
编写实体类,通过自定义注解Header声明相关属性
Header为自定义注解,开发者在建立外键关系时,可通过ManyToOne,也通过joinClass指定关联的实体,dataSource指定了在编辑时,该属性的数据来源,当为字典时,指定为字典父编码,也可以指定一个url。
2、生成xml配置
启动项目后,输入queryId,实体名,业务名,点击“加载配置“,弹出xml配置窗口,可在此配置窗口配置查询xml
AdminEAP的所有数据列表都是基于xml配置的,可支持反射接口查询、sql配置的查询、离线查询(hql)。
3、重启系统使xml配置生效
如果是首次生成xml文件(注意是文件,如果在已有的xml配置内容,则不需要重新,刷新系统即可,系统会读取更新的xml)
4、配置具体参数
输入queryId,点击”加载配置“后,系统读取xml的配置,并回填所有的默认配置,包括要生成的文件,文件路径等等,开发者也可以根据自己的需要更改参数配置。在界面右侧是实体的属性列表,开发者可以勾选数据再编辑时使用的控件类型,也可以勾选是是否作为查询条件,是否在编辑界面中维护等等。
更具体配置说明,包含在今后的技术文档(付费)中
5、根据freemarker模板生成代码
从界面上收集好以上配置参数后,代码生成器将这些参数给配置好的freemarker模板,生成相关的源代码。
以下是控制器模板controller.html
package ${nameSpace}.controller;
import java.util.Date;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSON;
import com.cnpc.framework.base.entity.Dict;
import com.cnpc.framework.utils.StrUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cnpc.framework.base.service.BaseService;
import com.cnpc.framework.annotation.RefreshCSRFToken;
import com.cnpc.framework.annotation.VerifyCSRFToken;
import com.cnpc.framework.base.pojo.Result;
import ${className};
/**
* ${modelName}管理控制器
* @author jrn
* ${curTime?string("yyyy-MM-dd HH:mm:ss")}由代码生成器自动生成
*/
@Controller
@RequestMapping("/${htmlPrefix}")
public class ${javaPrefix}Controller {
@Resource
<#if javaTypes?contains("service")>
private ${javaPrefix}Service ${htmlPrefix}Service;
<#else>
private BaseService baseService;
</#if>
@RequestMapping(value="/list",method = RequestMethod.GET)
public String list(){
return "${businessPackage}/${htmlPrefix}_list";
}
@RefreshCSRFToken
@RequestMapping(value="/edit",method = RequestMethod.GET)
public String edit(String id,HttpServletRequest request){
request.setAttribute("id", id);
return "${businessPackage}/${htmlPrefix}_edit";
}
@RequestMapping(value="/detail",method = RequestMethod.GET)
public String detail(String id,HttpServletRequest request){
request.setAttribute("id", id);
return "${businessPackage}/${htmlPrefix}_detail";
}
@RequestMapping(value="/get/{id}",method = RequestMethod.POST)
@ResponseBody
public ${javaPrefix} get(@PathVariable("id") String id){
return <#if javaTypes?contains("service")>${htmlPrefix}Service<#else>baseService</#if>.get(${javaPrefix}.class, id);
}
@VerifyCSRFToken
@RequestMapping(value="/save")
@ResponseBody
<#assign isObj=1>
<#list fields as field>
<#if field.columnName?contains(".")>
<#assign isObj=0>
</#if>
</#list>
public Result save(<#if isObj=1>${javaPrefix} ${htmlPrefix}<#else>String obj</#if>){
<#if isObj=0>
${javaPrefix} ${htmlPrefix}= JSON.parseObject(obj,${javaPrefix}.class);
<#list fields as field>
<#if field.columnName?contains(".")>
<#assign fieldName=field.columnName?substring(0,field.columnName?index_of("."))>
<#assign fieldN=fieldName?substring(0,1)?upper_case+fieldName?substring(1)>
${htmlPrefix}.set${fieldN}(<#if javaTypes?contains("service")>${htmlPrefix}Service<#else>baseService</#if>.get(${field.type}.class,${htmlPrefix}.get${fieldN}().getId()));
</#if>
</#list>
</#if>
if(StrUtil.isEmpty(${htmlPrefix}.getId())){
<#if dateFields?exists&&(dateFields?size>0)>
<#list dateFields as date>
${date};
</#list>
</#if>
<#if javaTypes?contains("service")>${htmlPrefix}Service<#else>baseService</#if>.save(${htmlPrefix});
}
else{
<#if leftFields?exists&&(leftFields?size>0)>
${javaPrefix} ${htmlPrefix}_old=<#if javaTypes?contains("service")>${htmlPrefix}Service<#else>baseService</#if>.get(${javaPrefix}.class,${htmlPrefix}.getId());
BeanUtils.copyProperties(${htmlPrefix},${htmlPrefix}_old, <#list leftFields as str><#if str_index==0>"${str}"<#else>,"${str}"</#if></#list>);
<#if leftDates?exists&&(leftDates?size>0)>
<#list leftDates as ld>
${ld};
</#list>
</#if>
${htmlPrefix}_old.setUpdateDateTime(new Date());
<#if javaTypes?contains("service")>${htmlPrefix}Service<#else>baseService</#if>.update(${htmlPrefix}_old);
<#else>
${htmlPrefix}.setUpdateDateTime(new Date());
<#if javaTypes?contains("service")>${htmlPrefix}Service<#else>baseService</#if>.update(${htmlPrefix});
</#if>
}
return new Result(true);
}
@RequestMapping(value="/delete/{id}",method = RequestMethod.POST)
@ResponseBody
public Result delete(@PathVariable("id") String id){
${javaPrefix} ${htmlPrefix}=this.get(id);
try{
baseService.delete(${htmlPrefix});
return new Result();
}
catch(Exception e){
return new Result(false,"该数据已经被引用,不可删除");
}
}
}
6、修改生成的代码并重启系统查看效果
开发者根据需要修改生成的代码,并重启系统,查看效果,如果需要分配权限,请先将生成的菜单功能授权,才可有相应的菜单。
通过代码生成生成了一个业务功能的CURD操作。
7、总结
以上操作步骤,在开发环境使用,在项目中使用代码生成器的主要工作量在编写实体,两次重启系统(如果在之前xml追加内容,则是一次重启)上,其余采用默认配置即可。
欢迎大家使用AdminEAP框架,如有意见建议请登录AdminEAP官网给我提意见。