1.前端jsp进行抽取
<%-- 导入easyui的样式文件和js文件 注意先后顺序--%>
<link rel="stylesheet" type="text/css" href="/easyui/themes/default/easyui.css"/>
<link rel="stylesheet" type="text/css" href="/easyui/themes/icon.css"/>
<script type="text/javascript" src="/easyui/jquery.min.js"></script>
<script type="text/javascript" src="/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/easyui/locale/easyui-lang-zh_CN.js"></script>
<script type="text/javascript" src="/js/common.js"></script>
<style type="text/css">
.form-group {
width: 200px;
height: 35px;
margin: auto;
}
.form-group:first-child {
margin-top: 25px;
}
.in {
width: 200px;
height: 25px;
border: 0px solid #1471ff;
}
.in:focus {
box-shadow: 10px 0px 0px 4px #5f76ff;
}
</style>
2.前端JS进行抽取
// jquery的入口函数
$(function () {
/**
* easyui的datagrid要求后端返回的数据必须包含两个属性
* total 表示总行数
* rows 表示当前页要显示的数据集合
*/
$('#dg').datagrid({
url: '/employee/page',//异步请求加载数据的地址
frozenColumns: [[{field: '1111', checkbox: true}]], //在表格左侧添加多选框
striped: true,
method: "post", //请求方法 GET或者POST
pagination: true,//是否显示分页工具栏
rownumbers: true, //是否显示行号
toolbar: "#toolbar",//工具栏
columns: [[
{field: 'id', title: '编号', width: 100, hidden: true},
{field: 'username', title: '用户名', width: 100},
{field: 'password', title: '密码', width: 300},
{field: 'email', title: '邮箱', width: 200},
{field: 'headImage', title: '头像', width: 100},
{field: 'age', title: '年龄', width: 100},
{field: 'department', title: '部门', width: 100, formatter: function (value, row, index) {
// value:字段值。 row:行记录数据。index: 行索引。
//如果value不等于空 那么返回字段值对象 否则返回空字符串
return value ? value.name : ""
}
},
]]
});
//先通过表格获取到分页工具栏对象,然后再添加点击事件
$('#dg').datagrid("getPager").pagination({
onSelectPage: function (pageNumber, pageSize) {
$('#dg').datagrid('loading');
$('#pageNum').val(pageNumber);
$('#pageSize').val(pageSize);
$('#dg').datagrid('load', $("#searchForm").toJSON());
$(this).pagination({
pageNumber: pageNumber,//给分页工具栏设置一下底部的当前页码以及每页显示的行数
pageSize: pageSize
});
$('#dg').datagrid('loaded');
}
});
//给所有按钮绑定点击事件 所有有data-method属性的按钮
$("a[data-method]").click(function () {
//获取当前按钮的data-method属性值
var methodName = $(this).attr("data-method");
//调用window.methods对象的对应方法
window.methods[methodName]();
});
});
//将当前页面所有js方法全部封装到window.methods对象中
window.methods= {
search: function () {
$('#dg').datagrid('loading');
console.debug($("#searchForm").toJSON())
$('#dg').datagrid('load', $("#searchForm").toJSON());
$('#dg').datagrid("getPager").pagination({
pageNumber: 1,//给分页工具栏设置一下底部的当前页码以及每页显示的行数
pageSize: 10
});
$('#dg').datagrid('loaded');
},
add: function () {
$("#dialog").dialog("open"); //打开一个模态框
//重置一下表单
$("#ffff").form("reset");
$("#employeeid").val("");
//显示密码框/设置为启用状态
$("#passwordBox").show();
$("#passwordBox>input[name=password]").prop("disabled", false);
},
save: function () {
var param = $("#ffff").toJSON();
if (param.id) {
//id框有值的话就做修改
url = "/employee/update";
//修改数据时额外多传入一个参数action,值是update
param.action = "update";
}
$.post(url, param, function (data) {
if (data.status == 200) {
$.messager.alert("消息", data.msg, "info");
//新增成功要刷新表格数据
$('#dg').datagrid('loading');
$("#pageNo").val(1);
$("#pageSize").val(10);
//要实现翻页只需要传递两个请求参数pageNo和pageSize给后端即可
$('#dg').datagrid('load', $("#searchForm").toJSON());
//给分页工具栏设置一下底部的当前页码以及每页显示的行数
$('#dg').datagrid("getPager").pagination({
pageNumber: 1,
pageSize: 10
});
$('#dg').datagrid('loaded');
//关闭模态框
$("#dialog").dialog("close");
} else {
$.messager.alert("错误", data.msg, "error");
}
}, "json");
},
edit: function () {
//重置一下表单
$("#ffff").form("reset");
//获取用户选中的行
var selectedRows = $("#dg").datagrid("getSelections");
if (selectedRows.length == 0) {
$.messager.alert("错误", "请先选中你要编辑的数据!", "error");
return;
}
if (selectedRows.length > 1) {
$.messager.alert("错误", "对不起,您只能选中一行进行编辑!", "error");
return;
}
//先通过当前选中行的id去查询数据
$.getJSON("/employee/findOne", {id: selectedRows[0].id}, function (employee) {
//再回填表单
$("#ffff").form("load", employee);
//关联对象必须手动回填一下
$("#departmentId2").combobox("setValue", employee.department.id);
//隐藏密码框/设置为禁用状态
$("#passwordBox").hide();
$("#passwordBox>input[name=password]").prop("disabled", true);
//打开模态框
$("#dialog").dialog("open");
});
},
remove: function () {
//获取用户选中的行
var selectedRows = $("#dg").datagrid("getSelections");
if (selectedRows.length == 0) {
$.messager.alert("错误", "请先选中你要删除的数据!", "error");
return;
}
//消息确认框
$.messager.confirm('确认', '您确认想要删除这些数据吗?', function (r) {
if (r) {
var ids = [];
for (var i = 0; i < selectedRows.length; i++) {
ids.push(selectedRows[i].id);
}
$.getJSON("/employee/delete", {ids: ids.join(",")}, function (data) {
if (data.status == 200) {
$.messager.alert("消息", data.msg, "info");
//新增成功要刷新表格数据
$('#dg').datagrid('loading');
$("#pageNo").val(1);
$("#pageSize").val(10);
//要实现翻页只需要传递两个请求参数pageNo和pageSize给后端即可
$('#dg').datagrid('load', $("#searchForm").toJSON());
//给分页工具栏设置一下底部的当前页码以及每页显示的行数
$('#dg').datagrid("getPager").pagination({
pageNumber: 1,
pageSize: 10
});
$('#dg').datagrid('loaded');
} else {
$.messager.alert("错误", data.msg, "error");
}
});
}
});
},
cancel:function () {
$("#dialog").dialog("close");
}
};
3.抽取后的JSP页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>员工管理页面</title>
<meta charset="UTF-8">
<%@include file="/WEB-INF/views/common.jsp" %>
<script type="text/javascript" src="/js/employee/employee.js"></script>
</head>
<body>
<table id="dg"></table>
<div id="toolbar">
<form id="searchForm">
<a href="javascript:void(0);" data-method="add" class="easyui-linkbutton"
data-options="iconCls:'icon-add'">新增</a>
<a href="javascript:void(0);" data-method="edit" class="easyui-linkbutton"
data-options="iconCls:'icon-edit'">编辑</a>
<a href="javascript:void(0);" data-method="remove" class="easyui-linkbutton"
data-options="iconCls:'icon-remove'">删除</a>
<input type="hidden" value="1" name="pageNo" id="pageNo">
<input type="hidden" value="10" name="pageSize" id="pageSize">
<input type="text" name="username" id="username" class="in" placeholder="按用户名模糊查询" />
<input type="text" name="age1" id="age1" class="in" placeholder="按年龄范围搜索" />
<input type="text" name="age2" id="age2" class="in" placeholder="按年龄范围搜索" />
<%--panelHeight:'auto' 加上让下拉框自适应--%>
<select name="departmentId" id="departmentId1" class="easyui-combobox in"
data-options="url:'/department/findAll',valueField:'id',textField:'name',value:'-1',panelHeight:'auto'"></select>
<a href="javascript:void(0);" data-method="search" class="easyui-linkbutton"
data-options="iconCls:'icon-search'">搜索</a>
</form>
</div>
<div id="dialog" class="easyui-dialog" title="新增/编辑员工信息" style="width:400px;height:300px;top:100px;"
data-options="iconCls:'icon-save',closed:true,modal:true">
<form id="ffff">
<div class="form-group">
<input type="hidden" name="id" id="employeeid">
<input type="text" name="username" placeholder="用户名" class="easyui-validatebox in">
</div>
<div class="form-group" id="passwordBox">
<input type="text" name="password" placeholder="密码" class="easyui-validatebox in">
</div>
<div class="form-group">
<input type="text" name="email" placeholder="邮箱" class="easyui-validatebox in">
</div>
<div class="form-group">
<input type="text" name="age" placeholder="年龄" class="easyui-validatebox in">
</div>
<div class="form-group">
<select name="department.id" id="departmentId2" class="easyui-combobox in"
data-options="url:'/department/findAll',valueField:'id',textField:'name',value:'-1',panelHeight:'auto'"></select>
</div>
<div class="form-group">
<a href="javascript:void(0);" data-method="cancel" class="easyui-linkbutton" data-options="iconCls:'icon-undo'">取消</a>
<a href="javascript:void(0);" data-method="save" class="easyui-linkbutton" data-options="iconCls:'icon-redo'">确认</a>
</div>
</form>
</div>
</body>
</html>
4.后端EmployeeController层
package cn.itsource.controller;
import cn.itsource.domain.Employee;
import cn.itsource.query.EmployeeQuery;
import cn.itsource.service.IEmployeeService;
import cn.itsource.utils.MyPage;
import cn.itsource.utils.ResultJson;
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;
@Controller
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private IEmployeeService employeeService;
@RequestMapping("/index")
public String index() {
System.err.println("测试热部署成功");
System.err.println("接收请求成功");
return "employee/employee";
}
/**
* 分页查询数据
*
* @param employeeQuery
* @return
* @ResponseBody注解表示[异步请求/不跳转页面]将当前方法的返回值(对象/List集合/Map集合/数组)使用第三方工具(jackson)自动转化为json格式的字符串 放入响应的消息体中发送给浏览器
*/
@ResponseBody
@RequestMapping("/page")
public MyPage<Employee> page(EmployeeQuery employeeQuery) {
return employeeService.findByPage(employeeQuery);
}
/**
* 新增
*
* @param employee
* @return
* @ResponseBody的作用是将java对象转为json格式的数据。
*/
@ResponseBody
@RequestMapping("/save")
public ResultJson save(Employee employee) {
try {
employeeService.save(employee);
} catch (Exception e) {
e.printStackTrace();
return new ResultJson(500, "操作失败" + e.getMessage());
}
return new ResultJson(200, "ok");
}
@ResponseBody
@RequestMapping("/findOne")
public Employee findOne(Long id) {
return employeeService.findOne(id);
}
//@ModelAttribute写在方法上表示当前类中所有方法之前都必须先执行此方法
@ModelAttribute("update")
public Employee findOneBeforeUpdate(Long id,String action) {
Employee one = null;
if ("update".equals(action) && id != null && id > 0) {
//查询出来的对象就一定是持久状态[一定与数据库中的数据完全一致]
one = employeeService.findOne(id);
//解决一下N to N错误
one.setDepartment(null);
}
return one;
}
@ResponseBody
@RequestMapping("/update")
public ResultJson update(@ModelAttribute("update")Employee employee) {
try {
employeeService.save(employee);
} catch (Exception e) {
e.printStackTrace();
return new ResultJson(500, "操作失败" + e.getMessage());
}
return new ResultJson(200, "ok");
}
@ResponseBody
@RequestMapping("/delete")
public ResultJson delete(String ids){
try {
employeeService.delete(ids);
} catch (Exception e) {
e.printStackTrace();
return new ResultJson(500,"操作失败:" + e.getMessage());
}
return new ResultJson(200,"ok");
}
}
4.1 解决N to N错误
出现异常的原因是:一个持久化对象的OID被修改了
解决方法
当修改的时候,有关联对象的时候,将关联对象设置为空
@ModelAttribute写在方法上就表示当前类中所有方法执行之前都必须先执行此方法
@ModelAttribute写在形参变量前表示将此方法返回的对象与形参变量对象进行合并,以查询出来的持久状态对象为准
4.2 easyui的一些方法和注意事项
easyUI中combobox 高度自适应
data-options=“required:true,editable:false,panelHeight:‘auto’” 加上panelHeight:'auto'即可
效果图:
easy分页注意:
easyui的分页(pagination)工具栏它将在数据网格(datagrid)的底部生成一个分页(pagination)工具栏。pagination将发送两个参数到服务器:
page:页码,起始值 1。
rows:每页显示行。
5.代码生成器
5.1 EasyCode
EasyCode是基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml)。只要是与数据库相关的代码都可以通过自定义模板来生成。支持数据库类型与java类型映射关系配置。支持同时生成生成多张表的代码。每张表有独立的配置信息。完全的个性化定义,规则由你设置。
5.2支持的数据库类型
因为是基于Database Tool开发,所有Database Tool支持的数据库都是支持的。
包括如下数据库:
选中要使用的数据库
生成代码:
5.5 Domain类生成代码实例
##引入宏定义
$!define
##定义一个变量
#set($firstLowerName = $tool.firstLowerCase($!{tableInfo.name}))
##使用宏定义设置回调(保存位置与文件后缀)
#save("/main/java/cn/itsource/domain", ".java")
##实现动态排除列
#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
##使用宏定义设置包后缀
#setPackageSuffix("domain")
##使用全局变量实现默认包导入
$!autoImport
import javax.persistence.*;
## $!{tableInfo.name} 首字母大写的表名称
## $tableInfo.fullColumn 所有列组成的集合
## ${column.comment} 列的注释
##$!{tool.getClsNameByFullName($column.type)} 模板的工具方法
##使用宏定义实现类注释信息
#tableComment("$!{tableInfo.name}实体类")
@Entity
@Table(name="${firstLowerName}")
public class $!{tableInfo.name} extends BaseDomain{
#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
}