(1)主流模板技术:主要是freemarker和velocity
freemarker:默认模板后缀 ftl
velocity:默认模板后缀 vm
(2)模板技术的大体概念
模板+数据=文本
体现:JSP+数据(作用域)=HTML文件
(3)模板技术大概的作用
将动态的页面静态化、代码生成器、邮件和短信的发送模板
(1)EasyCode代码生成器
idea的一个插件,前提是会velocity模板技术,会使用到velocity模板中的一系列语法
(2)EasyCode支持的数据库类型
MySQL、SQL Server、Oracle、PostgreSQL、Sqlite、Sybase、Derby、DB2、HSQLDB、H2
(3)EasyCode的使用手册
[https://gitee.com/makejava/EasyCode/wikis/pages]
(4)在idea上安装EasyCode代码生成器步骤
离线安装(先下载相应的zip包)
在线安装
(5)安装EasyCode完成后,添加数据源
(6)在idea中使用EasyCode代码生成器。最主要的就是控制它的位置和内容
(7)下面就来做做简单的模板示范,给项目的层次做模板
会使用到velocity模板技术的一系列语法
query层:接收前台传到后台的查询对象
##定义初始变量---生成的文件应该是 XxxQuery名称
#set($tableName = $tool.append($tableInfo.name, "Query"))
##设置文件名
$!callback.setFileName($tool.append($tableName, ".java"))
##设置文件保存的位置(依然是从src开始)
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/aisell/query"))
##拿到首字母小写的表单
#set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name}))
##引入相应的包--最后生成 package cn.itsource.aisell.query这个包出来,我们也可以直接写这个结果出来
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}query;
##使用全局变量实现默认包导入
$!autoImport
import cn.itsource.aisell.domain.$!{tableInfo.name};
import com.github.wenhao.jpa.Specifications;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
public class $!{tableInfo.name}Query extends BaseQuery {
##注:如果生成的表没有name,这里会报错,遇到这种情况请把它删除
private String name;
@Override
public Specification createSpec() {
//根据条件把数据返回即可
return Specifications.<$!{tableInfo.name}>and()
.like(StringUtils.isNotBlank(name),"name", "%"+name+"%")
.build();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
domain层:实体类
##引入宏定义
$!define
##拿到首字母小写的表单
#set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name}))
##使用宏定义设置回调(保存位置与文件后缀)
##注意:为了路径,这里都是从main的位置开始
#save("/main/java/cn/itsource/aisell/domain", ".java")
##使用宏定义设置包后缀
#setPackageSuffix("domain")
##使用全局变量实现默认包导入
$!autoImport
import java.io.Serializable;
##导入注解包
import javax.persistence.Entity;
import javax.persistence.Table;
##使用宏定义实现类注释信息
#tableComment("实体类")
@Entity
@Table(name="$!{lowerTableInfo}")
public class $!{tableInfo.name} extends BaseDomain {
##实现列进行排除。父类有的字段,子类不要有。将共有的字段传进去即可
#set($temp = $tool.newHashSet("id"))
#foreach($item in $temp)
#set($newList = $tool.newArrayList())
#foreach($column in $tableInfo.fullColumn)
#if($column.name!=$item)
##带有反回值的方法调用时使用$tool.call来消除返回值
$tool.call($newList.add($column))
#end
#end
##重新保存
$tableInfo.setFullColumn($newList)
#end
#foreach($column in $tableInfo.fullColumn)
#if(${column.comment})//${column.comment}#end
private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
#foreach($column in $tableInfo.fullColumn)
##使用宏定义实现get,set方法
#getSetMethod($column)
#end
}
repository层:原来的dao层,在springDataJpa中叫法不一样
##定义初始变量---生成的文件应该是 XxxRepository名称
#set($tableName = $tool.append($tableInfo.name, "Repository"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
##设置文件保存的位置(依然是从src开始)
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/aisell/repository"))
##拿到首字母小写的表单
#set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name}))
##引入相应的包
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}repository;
import cn.itsource.aisell.domain.$!{tableInfo.name};
public interface $!{tableInfo.name}Repository extends BaseRepository<$!{tableInfo.name},Long>{
}
service层:业务层—接口部分
##定义初始变量---拼接生成的文件应该是 IXxxService名称
#set($tableName = $tool.append("I",$tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
##设置文件保存的位置(依然是从src开始)
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/aisell/service"))
##拿到首字母小写的表单
#set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name}))
##引入相应的包
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;
import cn.itsource.aisell.domain.$!{tableInfo.name};
public interface I$!{tableInfo.name}Service extends IBaseService<$!{tableInfo.name},Long> {
}
service层:业务层—实现接口的类
##定义初始变量---生成的文件应该是 XxxServiceImpl名称
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
##设置文件保存的位置(依然是从src开始)
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/aisell/service/impl"))
##拿到首字母小写的表单
#set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name}))
##引入相应的包
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;
import cn.itsource.aisell.domain.$!{tableInfo.name};
import cn.itsource.aisell.repository.$!{tableInfo.name}Repository;
import cn.itsource.aisell.service.I$!{tableInfo.name}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class $!{tableInfo.name}ServiceImpl extends BaseServiceImpl<$!{tableInfo.name},Long> implements I$!{tableInfo.name}Service {
@Autowired
private $!{tableInfo.name}Repository $!{lowerTableInfo}Repository;
}
service层:业务层—测试类
##定义初始变量---生成的文件应该是 XxxServiceTest名称
#set($tableName = $tool.append($tableInfo.name, "ServiceTest"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
##设置文件保存的位置(依然是从src开始)
$!callback.setSavePath($tool.append($tableInfo.savePath, "/test/java/cn/itsource/aisell/service"))
##拿到首字母小写的表单
#set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name}))
##引入相应的包
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;
import cn.itsource.aisell.domain.$!{tableInfo.name};
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class $!{tableInfo.name}ServiceTest extends BaseSpringTest {
@Autowired
private I$!{tableInfo.name}Service $!{lowerTableInfo}Service;
@Test
public void findAll(){
System.out.println($!{lowerTableInfo}Service);
System.out.println($!{lowerTableInfo}Service.getClass());
List<$!{tableInfo.name}> $!{lowerTableInfo}s = $!{lowerTableInfo}Service.findAll();
for ($!{tableInfo.name} $!{lowerTableInfo} : $!{lowerTableInfo}s) {
System.out.println($!{lowerTableInfo});
}
}
}
controller层:web层
##定义初始变量(类名)
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/aisell/controller"))
##把首字母设置成小写
#set($tableNameLower = $tool.firstLowerCase($!{tableInfo.name}))
package cn.itsource.aisell.controller;
import cn.itsource.aisell.common.JsonResult;
import cn.itsource.aisell.common.UIPage;
import cn.itsource.aisell.domain.$!{tableInfo.name};
import cn.itsource.aisell.query.$!{tableInfo.name}Query;
import cn.itsource.aisell.service.I$!{tableInfo.name}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/$!{tableNameLower}")
public class $!{tableName} {
@Autowired
private I$!{tableInfo.name}Service $!{tableNameLower}Service;
@RequestMapping("/index")
public String index(){
return "$!{tableNameLower}/$!{tableNameLower}";
}
/**
* 在执行任何一个路径(方法) 之前都会先执行这个方法
*/
@ModelAttribute("edit$!{tableInfo.name}")
public $!{tableInfo.name} beforeEdit(Long id,String cmd){
//只有修改才做查询
if(id!=null && "update".equals(cmd)){
$!{tableInfo.name} db$!{tableInfo.name} = $!{tableNameLower}Service.findOne(id);
//解决n-to-n的问题(凡是要传过来的关联对象,都把它清空)
return db$!{tableInfo.name};
}
return null;
}
/**
* 现在返回的是SpringDataJpa设置好的Page对象{context:[],totalElements:xx}
* 而咱们前台需要的结构:{rows:[],total:xx}
* @param query
* @return
*/
@RequestMapping("/page")
@ResponseBody
public UIPage<$!{tableInfo.name}> page($!{tableInfo.name}Query query){
return new UIPage<>($!{tableNameLower}Service.findPageByQuery(query));
}
//为了我后期的权限考虑,添加与修改的路径不能是一样的
@RequestMapping("/save")
@ResponseBody
public JsonResult save($!{tableInfo.name} $!{tableNameLower}){
return saveOrUpdate($!{tableNameLower});
}
@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("edit$!{tableInfo.name}")$!{tableInfo.name} $!{tableNameLower}){
return saveOrUpdate($!{tableNameLower});
}
//添加或者修改
private JsonResult saveOrUpdate($!{tableInfo.name} $!{tableNameLower}){
try {
$!{tableNameLower}Service.save($!{tableNameLower});
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(false,e.getMessage());
}
return new JsonResult();
}
/**
* 咱们以后写功能,很有可能是有前端人员的!
* 我们已经商量好了:{success:true,msg:xxxx}
*/
@RequestMapping("/delete")
@ResponseBody
public JsonResult delete(Long id){
try {
$!{tableNameLower}Service.delete(id);
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(false,e.getMessage());
}
return new JsonResult();
}
}
jsp层:页面
##把首字母设置成小写
#set($tableNameLower = $tool.firstLowerCase($!{tableInfo.name}))
##去掉表的t_前缀
##实现列进行排除(父类如果已经有了,就把它排除掉)
#set($temp = $tool.newHashSet("id"))
#foreach($item in $temp)
#set($newList = $tool.newArrayList())
#foreach($column in $tableInfo.fullColumn)
#if($column.name!=$item)
##带有反回值的方法调用时使用$tool.call来消除返回值
$tool.call($newList.add($column))
#end
#end
##重新保存
$tableInfo.setFullColumn($newList)
#end
##设置回调
$!callback.setFileName($tool.append($tableNameLower, ".jsp"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/webapp/WEB-INF/views/${tableNameLower}"))
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2019/3/15
Time: 11:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%@include file="/WEB-INF/views/head.jsp" %>
<%--引入$!{tableNameLower}特有的js--%>
## 遍历咱们的所有列
#foreach($column in $tableInfo.fullColumn)
$!{column.name}
#end
<%--表单弹出框--%>
<%--弹出框(表单)操作--%>
js层:
##把首字母设置成小写
#set($tableNameLower = $tool.firstLowerCase($!{tableInfo.name}))
##设置回调
$!callback.setFileName($tool.append($tableNameLower, ".js"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/webapp/js/model/"))
$(function () {
//常用的控件先获取
var $!{tableNameLower}DataGrid =$("#$!{tableNameLower}DataGrid");
var $!{tableNameLower}Dialog =$("#$!{tableNameLower}Dialog");
var searchForm =$("#searchForm");
var $!{tableNameLower}Form =$("#$!{tableNameLower}Form");
//注册方法
$("*[data-method]").on("click",function(){
var methodName = $(this).data("method");
//调用方法
itsource[methodName]();
})
itsource = {
add(){
//把所有带data-show的元素显示起来
$("*[data-show]").show();
$("*[data-show] input").validatebox("enable");
//打开对话框
$!{tableNameLower}Dialog.dialog("center").dialog("open");
//把form中的数据清空
$!{tableNameLower}Form.form("clear");
},
edit(){
var row = $!{tableNameLower}DataGrid.datagrid("getSelected");
if(!row){
$.messager.alert("提示","选中再来!瓜!","info");
return;
}
//把所有带data-show的元素隐藏起来
$("*[data-show]").hide();
$("*[data-show] input").validatebox("disable");
//打开对话框
$!{tableNameLower}Dialog.dialog("center").dialog("open");
//把form中的数据清空
$!{tableNameLower}Form.form("clear");
//咱们部门要的字段:"department.id"
// row的部门部门: department.id
//完成修改的回显
$!{tableNameLower}Form.form("load",row);
},
//保存功能
save(){
//根据id确定是添加路径还是修改路径
var url = "/$!{tableNameLower}/save";
var id = $("#$!{tableNameLower}Id").val();
if(id){
url = "/$!{tableNameLower}/update?cmd=update";
}
$!{tableNameLower}Form.form('submit', {
url:url,
//提交表单前的方法
onSubmit: function(){
return $(this).form('validate');
},
//操作成功后的回调 {success:true,msg:xxx}
success:function(data){
//返回的是JSON字符串,我们需要把转成一个JSON对象
var result = JSON.parse(data);
if(result.success){
//成功后刷新
$!{tableNameLower}DataGrid.datagrid("reload");
//关闭窗口
$!{tableNameLower}Dialog.dialog("close");
}else{
//把失败信息做一个提示
$.messager.alert("提示",`你出错了! 原因是:${result.msg}`,"error");
}
}
});
},
//删除
delete(){
//1.查看是否选中了这一行
var row = $!{tableNameLower}DataGrid.datagrid("getSelected");
//2.如果没有选中,给出提示(未选中)
if(!row){
$.messager.alert("提示","选中再来!瓜!","info");
return;
}
//3.如果选中,让用户确认是否删除
$.messager.confirm('确认','您要狠心删除我嘛?',function(r){
if (r){
//4.如果确认删除,直接访问后台进行删除
$.get("/$!{tableNameLower}/delete",{id:row.id},function(result){
if(result.success){
//成功后刷新
$!{tableNameLower}DataGrid.datagrid("reload");
}else{
//把失败信息做一个提示
$.messager.alert("提示",`你出错了! 原因是:${result.msg}`,"error");
}
})
}
});
},
search(){
//拿到表所有参数(变成json)
var params = searchForm.serializeObject();
$!{tableNameLower}DataGrid.datagrid('load',params);
}
};
})