智能销售系统技术心得——第四篇
2019-03-29 00:27
141 查看
智能销售系统技术心得
第四章
模板技术
同样的代码写来写去枯燥无味,所以伟大的发明出现了,模板技术
只需要模板,加数据就能够生成咱们想要的文件啦
velocity 默认模板的后缀vm
freemarker 默认模板的后缀ftl
ftl可以用来生成静态html文件,
而vm的功能有如下:
动态页面静态化:xxx.html
在后台准备数据,在前台准备模板,通过IO把数据与模板合并,真正的生成一个html页面出来
用作发送邮件、短信模板
pom.xml:添加jar文件
<!-- 代码生成器模版技术 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.6</version> </dependency>
然后测试一下
public class VelocityTest { @Test public void testVelocity01() throws Exception { //创建模板应用上下文 VelocityContext context = new VelocityContext(); context.put("msg", "小张是个好同志"); //拿到相应的模板(需要设置好编码) Template template = Velocity.getTemplate("temptest/hello.html","UTF-8"); //准备输出流 StringWriter writer = new StringWriter(); template.merge(context, writer); System.out.println(writer); } @Test public void testVelocity02() throws Exception { //创建模板应用上下文 VelocityContext context = new VelocityContext(); context.put("msg", "小张是个好同志"); //拿到相应的模板(需要设置好编码) Template template = Velocity.getTemplate("temptest/hello.html","UTF-8"); //准备输出流 File file = new File("temptest/helloNew.html"); FileWriter writer = new FileWriter(file); template.merge(context, writer); writer.close(); } }
temptest /hello.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> 大伙都说:${msg} </body> </html>
vm是个不错的模板技术,但是还是不符合我的需求,所以这次我使用的是IDEA的一款插件,EasyCode,也叫代码生成器,可以帮我们解决重复代码反复写的问题,虽然很方便,但是一定切记要小心,备份备份,看清路径再生成代码,还有个前提就是,需要会velocity,因为写法其实也差不太多
功能说明:
• 支持多表同时操作
• 支持同时生成多个模板
• 支持自定义模板
• 支持自定义类型映射(支持正则)
• 支持自定义附加列
• 支持列附加属性
• 所有配置项目支持分组模式,在不同项目(或选择不同数据库时),只需要切换对应的分组,所有配置统一变化。
详细说明请参考该网站
https://gitee.com/makejava/EasyCode/wikis/pages
安装好就不废话了,直接开整,以下结构模板供参考
Domain实体对象
##引入宏定义 $!define ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##使用宏定义设置回调(保存位置与文件后缀) ##注意:为了路径,我现在都从main的位置开始 #save("/main/java/cn/itsource/zx/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 }
Query查询对象
##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "Query")) ##设置文件名 $!callback.setFileName($tool.append($tableName, ".java")) ##设置文件保存的位置(依然是从src开始) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/zx/query")) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##引入相应的包 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}query; ##使用全局变量实现默认包导入 $!autoImport import cn.itsource.zx.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 createSpecification() { //根据条件把数据返回即可 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; } }
Repository数据层
##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "Repository")) ##设置回调 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/zx/repository")) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##引入相应的包 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}repository; import cn.itsource.zx.domain.$!{tableInfo.name}; public interface $!{tableInfo.name}Repository extends BaseRepository<$!{tableInfo.name},Long>{ }
IXxxService业务层接口
##定义初始变量 #set($tableName = $tool.append("I",$tableInfo.name, "Service")) ##设置回调 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/zx/service")) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##引入相应的 4000 包 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service; import cn.itsource.zx.domain.$!{tableInfo.name}; public interface I$!{tableInfo.name}Service extends IBaseService<$!{tableInfo.name},Long> { }
XxxService
##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "ServiceImpl")) ##设置回调 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/zx/service/impl")) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##引入相应的包 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl; import cn.itsource.zx.domain.$!{tableInfo.name}; import cn.itsource.zx.repository.$!{tableInfo.name}Repository; import cn.itsource.zx.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}; }
Test基本测试生成
##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "ServiceTest")) ##设置回调 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/test/java/cn/itsource/zx/service")) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##引入相应的包 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service; import cn.itsource.zx.domain.$!{tableInfo.name}; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; public class $!{tableInfo.name}ServiceTest extends BaseServiceTest { @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}); } } }
XxxController:控制层
##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "Controller")) ##设置回调 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/cn/itsource/zx/web/controller")) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##引入相应的包 #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}web.controller; import cn.itsource.zx.common.UiPage; import cn.itsource.zx.domain. $!{tableInfo.name}; import cn.itsource.zx.query. $!{tableInfo.name}Query; import cn.itsource.zx.service.I $!{tableInfo.name}Service; import org.springframework.beans.factory.annotation.Autowired; 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; import java.util.HashMap; import java.util.Map; @Controller @RequestMapping("/$!{lowerTableInfo}") public class $!{tableInfo.name}Controller extends BaseController { @Autowired private I$!{tableInfo.name}Service $!{lowerTableInfo}Service; @RequestMapping("/index") public String index() { //根据配置,这里会跳到/WEB-INF/views/$!{lowerTableInfo}/$!{lowerTableInfo}.jsp页面 return "$!{lowerTableInfo}/$!{lowerTableInfo}"; } //查询分页数据 @RequestMapping("/page") @ResponseBody public UiPage page($!{tableInfo.name}Query query){ return new UiPage($!{lowerTableInfo}Service.findPageByQuery(query)); } //这里准备一个方法,所有方法执行前都会执行它 @ModelAttribute("edit $!{tableInfo.name}") public $!{tableInfo.name} beforeEdit(Long id, String cmd){ //有id的时候-> 修改功能 if(id!=null && "update".equals(cmd)) { $!{tableInfo.name} $!{lowerTableInfo} = $!{lowerTableInfo}Service.findOne(id); //把这个要修改的关联对象设置为null,可以解决n-to-n的问题 return $!{lowerTableInfo}; } return null; } //添加 @RequestMapping("/save") @ResponseBody public Map<String,Object> save($!{tableInfo.name} $!{lowerTableInfo}){ return saveOrUpdate($!{lowerTableInfo}); } //修改 @RequestMapping("/update") @ResponseBody public Map<String,Object> update(@ModelAttribute("edit $!{tableInfo.name}") $!{tableInfo.name} $!{lowerTableInfo}){ return saveOrUpdate($!{lowerTableInfo}); } //添加或者修改 private Map<String,Object> saveOrUpdate( $!{tableInfo.name} $!{lowerTableInfo}){ Map<String,Object> map = new HashMap<>(); try { $!{lowerTableInfo}Service.save($!{lowerTableInfo}); map.put(SUCCESS, true); } catch (Exception e) { e.printStackTrace(); map.put(SUCCESS, false); map.put("msg", e.getMessage()); } return map; } /** * 返回的结果:{SUCCESS:true,msg:"原因..."} * @param id * @return */ @RequestMapping("/delete") @ResponseBody public Map delete(Long id){ Map<String,Object> map = new HashMap<>(); try { $!{lowerTableInfo}Service.delete(id); map.put(SUCCESS, true); } catch (Exception e) { e.printStackTrace(); map.put(SUCCESS, false); map.put("msg", e.getMessage()); } return map; } }
xxx.jsp 页面展示
##定义初始变量 #set($tableName = $tool.append($tableInfo.name)) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##设置回调 $!callback.setFileName($tool.append($lowerTableInfo, ".jsp")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/webapp/WEB-INF/views/${lowerTableInfo}")) ##实现列进行排除 #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 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$!{lowerTableInfo}管理</title> <%@include file="/WEB-INF/views/head.jsp" %> <script type="text/javascript" src="/js/model/$!{lowerTableInfo}.js"></script> </head> <body> <table id="$!{lowerTableInfo}Grid" class="easyui-datagrid" data-options="fit:true,fixed:true,fitColumns:true,toolbar:'#tb',singleSelect:true,onRowContextMenu:showMenu" url="/$!{lowerTableInfo}/page" iconCls="icon-save" enableHeaderClickMenu="true" rownumbers="true" pagination="true" > <thead> ##这里是遍历所有相应的字段 <tr> #foreach($column in $tableInfo.fullColumn) <th width="20" field="$column.name" sortable="true">$column.name</th> #end </tr> </thead> </table> <div id="tb" style="padding:5px;height:auto"> <!-- 这部分是加上增删改的按键:现在没有功能,我们先不管它 --> <div style="margin-bottom:5px"> <a href="#" data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加</a> <a href="#" data-method="edit" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改</a> <a href="#" data-method="del" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除</a> </div> <!-- 这部门是查询的功能 --> <div> <form id="searchForm" action="/$!{lowerTableInfo}/download" method="post"> 名称: <input name="name" class="easyui-textbox" style="width:80px;height:32px"> </form> </div> </div> <!-- 弹出相应的功能框 --> <div id="$!{lowerTableInfo}Dialog" class="easyui-dialog" title="数据操作" data-options="closed:true,modal:true" style="width:400px;padding:10px"> <form id="$!{lowerTableInfo}Form" method="post"> <input id="$!{lowerTableInfo}Id" type="hidden" name="id"> <table cellpadding="5"> #foreach($column in $tableInfo.fullColumn) <tr> <td>$column.name:</td> <td><input class="easyui-validatebox" type="text" name="$column.name"></input></td> </tr> #end </table> <div style="text-align:center;padding:5px"> <a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a> <a href="javascript:void(0)" class="easyui-linkbutton" "$('#$!{lowerTableInfo}Dialog').dialog('close')">取消</a> </div> </form> </div> <div id="gridMenu" class="easyui-menu" style="width:120px;"> <div data-options="iconCls:'icon-add'" data-method="add" >添加</div> <div data-options="iconCls:'icon-edit'" data-method="edit">修改</div> <div data-options="iconCls:'icon-remove'" data-method="del">删除</div> </div> </body> </html>
Xxx.js
##定义初始变量 #set($tableName = $tool.append($tableInfo.name)) ##拿到首字母小写的表单 #set($lowerTableInfo = $tool.firstLowerCase($!{tableInfo.name})) ##设置回调 $!callback.setFileName($tool.append($lowerTableInfo, ".js")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/main/webapp/js/model")) $(function () { //这里我们把很多会常用到的元素进行一个抽取 var searchForm = $("#searchForm"); var $!{lowerTableInfo}Grid = $("#$!{lowerTableInfo}Grid"); var $!{lowerTableInfo}Dialog = $("#$!{lowerTableInfo}Dialog"); var $!{lowerTableInfo}Form = $("#$!{lowerTableInfo}Form"); //只要a标签中有data-method属性,咱们就给它添加事件 // 执行对应的itsource中的事件 $("*[data-method]").on("click",function () { itsource[$(this).data("method")](); }) window.itsource={ search:function () { //需要先引入 jquery.jdirk.js 才可以使用这个方法 var params = searchForm.serializeObject(); $!{lowerTableInfo}Grid.datagrid('load',params); }, add:function () { //隐藏有data-save属性的元素 $("*[data-save]").show(); //禁用有data-save属性的input元素的验证功能 $("*[data-save] input").validatebox("enableValidation"); //弹出表单窗口 $!{lowerTableInfo}Form.form("clear");//清除数据 $!{lowerTableInfo}Dialog.dialog("center").dialog("open"); }, edit:function () { //弹出表单窗口 //选中了某一条数据才删除 var row = $!{lowerTableInfo}Grid.datagrid("getSelected"); if(row) { //隐藏有data-save属性的元素 $("*[data-save]").hide(); //禁用有data-save属性的input元素的验证功能 $("*[data-save] input").validatebox("disableValidation"); $!{lowerTableInfo}Form.form("clear");//清除数据 $!{lowerTableInfo}Dialog.dialog("center").dialog("open"); //为form加载数据 $("#$!{lowerTableInfo}Form").form("load",row); }else{ $.messager.alert('提示信息','请选择一行再进行修改!','info'); } }, del:function () { //拿到选中的这条数据 var row = $!{lowerTableInfo}Grid.datagrid("getSelected"); if(row){ $.messager.confirm('确认框', '确定要狠心删除我么?', function(r){ if (r){ //进行删除 $.get("/$!{lowerTableInfo}/delete",{id:row.id},function (result) { if(result.success){ $('#$!{lowerTableInfo}Grid').datagrid('reload'); }else{ //alert("删除失败"); $.messager.alert('提示信息','删除失败!,原因:'+result.msg,"error"); } }) } }); }else{ $.messager.alert('提示信息','请选择一行再进行删除!','info'); } }, save:function () { var url = "/$!{lowerTableInfo}/save"; var id = $("#$!{lowerTableInfo}Id").val(); if(id){ url = "/$!{lowerTableInfo}/update?cmd=update"; } $!{lowerTableInfo}Form.form('submit', { url:url, onSubmit: function(){ //做验证 return $("#$!{lowerTableInfo}Form").form("validate"); }, success:function(data){ var result = JSON.parse(data);//转成相应的json数据 if(result.success) { $('#$!{lowerTableInfo}Grid').datagrid('reload'); }else{ $.messager.alert('提示信息','操作失败!,原因:'+result.msg,"error"); } $!{lowerTableInfo}Dialog.dialog('close'); } }) } } })
相关文章推荐
- CIO应用商业智能技术系统的重构思考
- WCF广州本田整车销售系统技术解析(四) 订单修改功能实现分析
- 用友T6-ERP系统技术解析(二)销售订单(四)
- 智能配线系统技术高峰论坛现场发言纪要
- 珠宝连锁门店销售系统技术白皮书
- 智能布线系统技术高峰论坛会议策划书
- 钟表维修管理系统技术解析(二) 销售记录的查询功能
- CIO应用商业智能技术系统的重构思考
- 中国(北京)国际智能工业与信息安全技术发展论坛暨2014年中国嵌入式系统年会邀请函
- 订单可视化(智能制造、流程再造、企业信息化) 第四篇 技术方案的制定
- 智能配线系统技术高峰论坛会议邀请函
- 【转贴】商务智能系统的可行性分析报告:Pentaho 技术概述
- CIO应用商业智能技术系统的重构思考
- 智能配线系统技术高峰论坛PPT讲座主要内容
- 企业商业智能技术系统应用的重构思考
- CIO应用商业智能技术系统的重构思考
- 用友T6-ERP系统技术解析(二)销售订单(二)
- 首帧秒开+智能鉴黄+直播答题,阿里云直播系统背后技术大起底
- WCF广州本田整车销售系统技术解析(一) 新建项目与登陆验证功能实现
- CIO应用商业智能技术系统的重构思考