前言:
新业务的开发总是少不了相应的增删查改,而这些功能与其他业务的增删查改大径相同,所以为了解决这种纯粹的体力劳动,提高开发效率,开发一个增删查改的代码自动生成是非常有必要的。
技术:freemarker模板
生成的目标文件:entity,dao,controller,service,.sql等五个文件
依赖包:freemarker-2.3.16.jar
commons.io-2.4.jar
主体代码:
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import com.arvin.entity.CodeAuto;
import com.arvin.entity.Column;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CodeAutoUtil {
public Map<String, Object> getCodeAutoData(CodeAuto codeAuto) {
Map<String, Object> dataMap = new HashMap<String , Object>();
dataMap.put("name", codeAuto.name);
dataMap.put("entityName", StringUtils.capitalize(codeAuto.name));
dataMap.put("controllerName", StringUtils.capitalize(codeAuto.name) + "Controller");
dataMap.put("daoName", StringUtils.capitalize(codeAuto.name) + "Dao");
dataMap.put("serviceName", StringUtils.capitalize(codeAuto.name) + "Service");
// controller 功能
dataMap.put("funs",codeAuto.funs);
// entity 字段列
List<String> stringList = new ArrayList<String>();
List<String> strs = new ArrayList<String>();
for(Column column : codeAuto.columns){
String columnStr = "public"+" "+ column.type + " " + column.name +";"; //格式: public String name;
String str = "`"+column.name+"`"+column.type+"("+parseColumnLength(column.type)+")"+" "+"NULL,"; //格式: `name` varchar(255) NULL,
stringList.add(columnStr);
strs.add(str);
}
dataMap.put("params",stringList);
//sql 建表文件
dataMap.put("colomns",strs);
return dataMap;
}
public boolean create(CodeAuto codeAuto) throws Exception{
Map<String, Object> dataMap = getCodeAutoData(codeAuto);
Template template = FreeMarkerTemplateUtils.getTemplate("Endpoint.ftl");
File file = FileUtils.getFile(codeAuto.path, codeAuto.name);
if (!file.exists()){
file.mkdir();
}
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileUtils.getFile(codeAuto.path, codeAuto.name, dataMap.get("controllerName") + ".java")), "utf-8"),10240);
template.process(dataMap,out);
template = FreeMarkerTemplateUtil.getTemplate("Dao.ftl");
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileUtils.getFile(codeAuto.path, codeAuto.name, dataMap.get("daoName") + ".java")), "utf-8"),10240);
template.process(dataMap,out);
template = FreeMarkerTemplateUtil.getTemplate("Domain.ftl");
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileUtils.getFile(codeAuto.path, codeAuto.name, dataMap.get("entityName") + ".java")), "utf-8"),10240);
template.process(dataMap,out);
template = FreeMarkerTemplateUtil.getTemplate("Service.ftl");
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileUtils.getFile(codeAuto.path, codeAuto.name, dataMap.get("serviceName") + ".java")), "utf-8"),10240);
template.process(dataMap,out);
template = FreeMarkerTemplateUtil.getTemplate("Sql.ftl");
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileUtils.getFile(codeAuto.path, codeAuto.name,dataMap.get("entityName") + ".sql")), "utf-8"),10240);
template.process(dataMap,out);
return true;
}
//数据库字段类型转换为java类型
private int parseColumnLength(String type) {
int ret;
switch (type) {
case "varchar":ret = 255;break;
case "char": ret = 255;break;
case "text": ret = 1024;break;
case "bigint": ret = 11;break;
case "tinyint":ret = 4;break;
default:ret = 255;
}
return ret;
}
}
测试代码:
import java.util.ArrayList;
import java.util.List;
import com.arvin.entity.CodeAuto;
import com.arvin.entity.Column;
public class Test {
public static void main(String[] args) throws Exception {
//Entity的字段
Column columnOne = new Column("username","varchar");
Column columnTwo = new Column("password","varchar");
Column columnThree = new Column("sex","tinyint");
List<Column> columns = new ArrayList<>();
columns.add(columnOne);
columns.add(columnTwo);
columns.add(columnThree);
//Controller的方法
String[] fun = {"add","delete","query","update"};
CodeAuto codeAuto = new CodeAuto();
codeAuto.name = "test";
codeAuto.diskPath = "E:\\codeAuto\\";
codeAuto.funs = fun;
codeAuto.columns = columns;
CodeAutoUtil cdeAutoUtil = new CodeAutoUtil();
cdeAutoUtil.create(codeAuto);
}
}
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.List;
public class CodeAuto {
public String name;
public String path;
public List<Column> columns; //entity字段
public String[] funs; // 功能点(增删查改)
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
public class Column {
public String name;//字段名
public String type;//字段类型
public Column(String name,String type) {
this.name = name;
this.type = type;
}
}
freemarker配置:
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import java.io.IOException;
public class FreeMarkerTemplateUtil {
private static final Configuration con= new Configuration();
static{
con.setTemplateLoader(new ClassTemplateLoader(FreeMarkerTemplateUtil.class, "/templates"));//模板所在路径
con.setDefaultEncoding("UTF-8"); con.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); } public static Template getTemplate(String templateName) throws IOException { try { return Configuration.getTemplate(templateName); } catch (IOException e) { throw e; } } }
Dao.ftl模板:
package ${name};
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ${entityName}Dao extends JpaRepository<${entityName}, Long> {
Page<${entityName}> findAll(Specification<${entityName}> specification, Pageable pageable);
}
Entity.ftl模板:
package ${name};
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class ${entityName} {
// JPA 主键标识, 策略为由数据库生成主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public Date updateTime;
public Date createTime;
<#list params as x>
${x}
</#list>
public ${entityName}() {}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
Controller.ftl模板:
package ${name};
import org.carrot.config.support.SuccessResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springside.modules.constants.MediaTypes;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
@RestController
@RequestMapping(value="/api/${name}")
public class ${entityName}Controller {
@Autowired
private ${entityName}Service ${name}Service;
<#list funs as x>
<#if x?contains("hasQuery")>
@RequestMapping(value = "/list", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
public SuccessResult list(@RequestHeader(value = "token") String token,
@RequestParam(required=false) String searchValue,
@PageableDefault(sort="updateTime",direction=Sort.Direction.DESC) Pageable pageable) throws Exception {
return new SuccessResult(${name}Service.list(searchValue,pageable));
}
</#if>
<#if x?contains("hasAdd")>
@RequestMapping(value = "/add", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
public SuccessResult add(@RequestHeader(value = "token") String token,
@RequestBody ${entityName} ${name}) throws Exception {
return new SuccessResult(${name}Service.add(${name}));
}
</#if>
<#if x?contains("hasDelete")>
@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
public SuccessResult delete(@RequestHeader(value = "token") String token,
@PathVariable(value = "id") Long id) throws Exception {
return new SuccessResult(${name}Service.delete(id));
}
</#if>
<#if x?contains("hasUpdate")>
@RequestMapping(value = "/update/{id}", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
public SuccessResult update(@RequestHeader(value = "token") String token, @PathVariable(value = "id") Long id,
@RequestBody ${entityName} ${name}) throws Exception {
return new SuccessResult(${name}Service.update(id, ${name}));
}
</#if>
<#if x?contains("hasQuery")>
@RequestMapping(value = "/detail/{id}", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
public SuccessResult detail(@RequestHeader(value = "token") String token,
@PathVariable(value = "id") Long id) throws Exception {
return new SuccessResult(${name}Service.detail(id));
}
</#if>
</#list>
}
Service.ftl模板:
package ${name};
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import org.carrot.util.PojoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Maps;
import javax.persistence.criteria.*;
@Service
public class ${entityName}Service {
@Autowired
private ${entityName}Dao ${name}Dao;
//根据条件查询全部
@Transactional()
public Map<String, Object> list( String searchValue,Pageable pageable) {
Map<String, Object> maps = new HashMap<String , Object>();
Page<${entityName}> page${entityName} = ${name}Dao.findAll(new Specification<${entityName}>() {
public Predicate toPredicate(Root<${entityName}> root, CriteriaQuery<?> query, CriteriaBuilder cb) { // 根据条件获取任务列表
List<Predicate> predicates = Lists.newArrayList();
Predicate[] predicateArr = new Predicate[predicates.size()];
query.where(predicates.toArray(predicateArr));
return null;
}
}, pageable);
maps.put("list", page${entityName}.getContent());
maps.put("total", page${entityName}.getTotalElements());
return maps;
}
@Transactional
public boolean add( ${entityName} ${name}) {
${name}Dao.save(${name});
return true;
}
@Transactional
public Object delete( Long id) {
${entityName} temp${entityName} = ${name}Dao.findOne(id);
if(temp${entityName} != null){
${name}Dao.delete(id);
return true;
}
return false;
}
@Transactional
public Object update( Long id, ${entityName} ${name}) throws Exception {
${entityName} temp${entityName} = ${name}Dao.findOne(id);
if (temp${entityName} != null) {
PojoUtil.copyProperties(temp${entityName}, ${name});
${name}Dao.save(temp${entityName});
return true;
}
return false;
}
@Transactional(readOnly = true)
public Object detail( Long id) {
${entityName} ${name} = ${name}Dao.findOne(id);
if(${name} != null) {
return ${name};
}
return false;
}
}
Sql.ftl模板:
CREATE TABLE if not EXISTS `${name}` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
<#list colomns as x>
${x}
</#list>
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) ,
);