1.课程介绍
1.CRUD操作(流程操作 思路要知道)
2.模板技术(freemarker-velocity)
3.代码生成器【细心】
Controller dao domain service jsp js–全部都可以
生成代码
一,智能销售CRUD
后台
@Controller
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private IEmployeeService employeeService;
//加载页面
@RequestMapping("/index")
public String index(){
return "employee";
}
//分页处理
@RequestMapping("/page")
@ResponseBody
public UiPage page(EmployeeQuery employeeQuery){
Page page = employeeService.findPageByQuery(employeeQuery);
UiPage uipage = new UiPage(page);
return uipage;
}
//方法 delete
@RequestMapping("/delete")
@ResponseBody
public Map delete(Long id){
Map mp = new HashMap();
try {
employeeService.delete(id);
mp.put("success", true);
} catch (Exception e) {
e.printStackTrace();
mp.put("success", false);
mp.put("msg", e.getMessage());
}
return mp;
}
//保存方法-- 修改和新增保存
@RequestMapping("/save")
@ResponseBody
public Map save(Employee employee){
Map mp = new HashMap();
try {
employeeService.save(employee);
mp.put("success", true);
} catch (Exception e) {
e.printStackTrace();
mp.put("success", false);
mp.put("msg", e.getMessage());
}
return mp;
}
@RequestMapping("/update")
@ResponseBody
public Map update(@ModelAttribute("editEmployee") Employee employee){
Map mp = new HashMap();
try {
employeeService.save(employee);
mp.put("success", true);
} catch (Exception e) {
e.printStackTrace();
mp.put("success", false);
mp.put("msg", e.getMessage());
}
return mp;
}
//去重
@RequestMapping("/checkUsername")
@ResponseBody
public boolean checkUsername(String username,Long id){
if(id != null && !"".equals(id)){
//修改
Employee employee = employeeService.findOne(id);
String username_db = employee.getUsername();
if(username.equals(username_db)){
return true;
}
}
return employeeService.checkUsername(username);
}
//删除方法
@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id,String cmd){
Employee employee = null;
if("update".equals(cmd) && id != null && !"".equals(id) ){
employee = employeeService.findOne(id);
employee.setDepartment(null);
}
return employee;
}
}
前台处理
/表格数据格式化
function formatObj(value){
if(value){
return value.name;
}
}
//formatImage头像格式化
function formatImage(value){
if(value){
return "<img width='100px' height='100px' src='"+value+"' alt='没有图片'/>"
}
}
//自己去扩展easyui验证的功能
$.extend($.fn.validatebox.defaults.rules, {
equals: {
validator: function(value,param){
return value == $(param[0]).val();
},
message: '密码不匹配.'
}
});
//扩展用户名是否重复的功能
$.extend($.fn.validatebox.defaults.rules, {
checkUsername: {
validator: function(value,param){
//当然输入框value 和数据库的username进行比较
//发送ajax请求 --异步(ajax同步)
var id = $("#employeeId").val();
var result = $.ajax({
type: "POST",
url: "/employee/checkUsername",
data: "username="+value+"&id="+id,
async: false //同步
}).responseText;
return result == 'true';
},
message: '用户名重复了.'
}
});
$(function(){
//定义form表单
var searchForm = $("#searchForm");
var employeeGrid = $("#employeeGrid");
//获取employeeDialog
var employeeDialog = $("#employeeDialog");
//定义表单新增的form
var employeeForm = $("#employeeForm");
//绑定事件 easyui 第二天的时候
$("a[data-method]").on('click',function(){
//获取 data-method属性 <a data-method="seacher">
var methodName = $(this).data("method");
itsource[methodName]();
});
//对象
var itsource = {
search:function(){
var param = searchForm.serializeObject();
employeeGrid.datagrid('load',param);
},
add:function(){
//隐藏数据 display:none
$("tr[data-save]").show();
//取消密码验证
$("*[data-save] input").validatebox("enableValidation");
//清空表单
employeeForm.form('clear');
//新增 --弹出一个对话框--装一个表单
employeeDialog.dialog('center').dialog('open');
},
edit:function(){
//选择一条数据进行修改
var row = employeeGrid.datagrid('getSelected');
if(row){
//隐藏数据 display:none
$("tr[data-save]").hide();
//取消密码验证
$("*[data-save] input").validatebox("disableValidation");
//部门回显
if(row.department){
row["department.id"] = row.department.id;
}
//修改 -- 回显示数据
employeeForm.form('load',row);
}else{
//提示用户
$.messager.alert('温馨提示:','请修改其中一条','info');
return;
}
//弹出对话框
employeeDialog.dialog('center').dialog('open');
},
del:function(){
//判断表格里面是否选中得数据
var row = employeeGrid.datagrid('getSelected');
if(row){
//是否确认要删除数据
$.messager.confirm('温馨提示','是否要删除?',function(value){
if(value){
//获取id值
//发送ajax到后台进行删除数据
$.get('/employee/delete',{"id":row.id},function(data){
//返回json对象
if(data.success){
$.messager.alert('温馨提示:','删除成功','info');
//重新加载数据
employeeGrid.datagrid('reload');
}else{
$.messager.alert('温馨提示:','删除失败'+data.msg,'error');
}
});
}
})
}else{
//提示用户
$.messager.alert('温馨提示:','选中一条进行删除','info');
return;
}
},
save:function(){
var url = "/employee/save";
//获取隐藏域里面id值
var id = $("#employeeId").val();
if(id){
url = "/employee/update?cmd=update"
}
//保存方法 --提交表单的数据到后台
employeeForm.form('submit', {
url:url,
onSubmit: function(){
// 提交之前的验证
return employeeForm.form('validate');
},
success:function(data){
//字符串 转换成json对象
var dataJson = $.parseJSON(data);
if(dataJson.success){
$.messager.alert('温馨提示:','操作成功','info');
//重新加载数据
employeeGrid.datagrid('reload');
//关闭对话框
employeeDialog.dialog('close');
}else{
$.messager.alert('温馨提示:','保存失败'+dataJson.msg,'error');
employeeDialog.dialog('close');
}
}
});
}
}
})
二.模板技术(freemarker-velocity)
模板技术怎样输出数据
数据+模板(html文件,vm文件,ftl文件)=输出文本
Velocity模板技术可以实现的功能
动态页面静态化:xxx.html --动态页面页面 静态化
pom.xml:添加jar文件
<!-- 代码生成器模版技术 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6</version>
</dependency>
测试Velocity功能
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();
}
}
三,代码生成器(手动写代码生成代码生成器)
一.开发步骤
1.准备模板(把每个模块需要改的地方确定好)
2.确定所有模板的生成顺序
3.确定所有模板的生成位置
4.确定要生成的基本功能的domain(Dept)
5.根据Domain名称与模板结合,在相应位置生成文件
6.解决如果父文件夹不存在的问题
7.解决如果文件已经存在的问题
8.排错(有错先改模板)
按照课件走,
@Test
public void testCreate() throws Exception{
//创建模板应用上下文
VelocityContext context = new VelocityContext();
//一.遍历所有的Domain
for (int i = 0; i < domains.length; i++) {
//1.1拿到大写的domain
String domainBig = domains[i];//Dept
//1.2拿到小写的domain //dept
String domainSmall = domainBig.substring(0,1).toLowerCase() + domainBig.substring(1);
//System.out.println(domainBig);
//System.out.println(domainSmall);
//1.3设置上下文的替换名称
context.put("Domain",domainBig);
context.put("domain",domainSmall);
//二.遍历所有的路径
for (int j = 0; j < paths.length; j++) {
//2.1拿到相应的路径
String path =paths[j];
//2.2拿到相应的模板名称
String tempName = tempNames[j];
//2.3拼接回我们需要的位置文件
String realPath = (path + tempName).replaceAll("Domain",domainBig).replaceAll("domain",domainSmall);
//三.准备相应文件与模板进行组合
//3.1准备相应的文件(要生成的文件)
File file = new File(realPath);
// 如果父文件不存在,我们创建一个
File parentFile = file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
//3.2拿到相应的模板(需要设置好编码)
Template template = Velocity.getTemplate("template/"+tempName,"UTF-8");
FileWriter writer = new FileWriter(file);
template.merge(context, writer);
writer.close();
}
}
}
easycode
支持的数据库类型
因为是基于Database Tool开发,所有Database Tool支持的数据库都是支持的。
包括如下数据库:
1.MySQL
2.SQL Server
3.Oracle
4.PostgreSQL
5.Sqlite
6.Sybase
7.Derby
8.DB2
9.HSQLDB
10.H2
安装按照课件和老师讲的走
代码生成器模板
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 =
t
o
o
l
.
a
p
p
e
n
d
(
tool.append(
tool.append(tableInfo.name, “Query”))
##设置文件名
!
c
a
l
l
b
a
c
k
.
s
e
t
F
i
l
e
N
a
m
e
(
!callback.setFileName(
!callback.setFileName(tool.append($tableName, “.java”))
##设置文件保存的位置(依然是从src开始)
!
c
a
l
l
b
a
c
k
.
s
e
t
S
a
v
e
P
a
t
h
(
!callback.setSavePath(
!callback.setSavePath(tool.append($tableInfo.savePath, “/main/java/cn/itsource/zx/query”))
##拿到首字母小写的表单
#set($lowerTableInfo =
t
o
o
l
.
f
i
r
s
t
L
o
w
e
r
C
a
s
e
(
tool.firstLowerCase(
tool.firstLowerCase(!{tableInfo.name}))
##引入相应的包
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}query;
##使用全局变量实现默认包导入
!
a
u
t
o
I
m
p
o
r
t
i
m
p
o
r
t
c
n
.
i
t
s
o
u
r
c
e
.
z
x
.
d
o
m
a
i
n
.
!autoImport import cn.itsource.zx.domain.
!autoImportimportcn.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 KaTeX parse error: Expected '}', got '#' at position 45: …s BaseQuery { #̲#注:如果生成的表没有name…!{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>{
}
IService业务层接口
##定义初始变量
#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}))
##引入相应的包
#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> {
}
Service
##定义初始变量
#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};
}