1.后台增删改查方法
本篇博客前期准备是依照上篇博客而言的,需要的朋友可以点此前往:
1.1修改Navicat查询语句
修改查询语句,把各个用户的身份根据id来给值。其实也就是给原本查询到的表全部信息加上一个会议身份信息。如下:
原始查询结果:
修改后查询结果:
查询语句如下:
SELECT u.*, (CASE WHEN u.rid = '1' THEN '管理员' WHEN u.rid = '2' THEN '发起者' WHEN u.rid = '3' THEN '审批者' WHEN u.rid = '4' THEN '参与者' WHEN u.rid = '5' THEN '会议室管理员' ELSE '其他' END ) rname FROM `t_oa_user` u
1.2编写Dao方法
查询结果无误之后,接下来我们就可以写我们增删改查的Dao方法了,如下:
package com.zking.dao; import java.util.List; import java.util.Map; import com.zking.entity.User; import com.zking.util.BaseDao; import com.zking.util.PageBean; import com.zking.util.StringUtils; public class UserDao extends BaseDao<User> { public List<User> list(User user, PageBean pageBean) throws Exception { String sql = "select * from t_oa_user where 1 = 1"; return super.executeQuery(sql, User.class, pageBean); } public User login(User user) throws Exception { String sql = "select * from t_oa_user where loginName = '"+user.getLoginName()+"' and pwd = '"+user.getPwd()+"'"; List<User> lst = super.executeQuery(sql, User.class, null); if(lst != null && lst.size() == 1) { return lst.get(0); } return null; } /**查询 * List<User>与List<Map>都是转成一样的json宿主,但是前者不能返回rname,后者可以 * 查询结果携带rname * @param user * @param pageBean * @return * @throws Exception */ public List<Map<String, Object>> userRole(User user, PageBean pageBean) throws Exception { String sql = "SELECT u.*,\r\n" + "(CASE \r\n" + " WHEN u.rid = '1' THEN\r\n" + " '管理员'\r\n" + " WHEN u.rid = '2' THEN\r\n" + " '发起者'\r\n" + " WHEN u.rid = '3' THEN\r\n" + " '审批者'\r\n" + " WHEN u.rid = '4' THEN\r\n" + " '参与者'\r\n" + " WHEN u.rid = '5' THEN\r\n" + " '会议室管理员'\r\n" + " ELSE\r\n" + " '其他'\r\n" + "END\r\n" + ") rname\r\n" + "FROM `t_oa_user` u where 1=1"; String name = user.getName(); if(StringUtils.isNotBlank(name)) { sql += "and name like '%"+name+"%'"; } return super.executeQuery(sql, pageBean); }//到这里我们的查询就算是写完了,借助工具类去查询我们的新加属性rname,不借助工具类的话我们也可以含泪建一个实体类哈 //增加 public int add(User user) throws Exception { String sql = "insert into t_oa_user(name, loginName, pwd) values(?,?,?)"; return super.executeUpdate(sql, user, new String[] {"name","loginName","pwd"}); } //删除 public int del(User user) throws Exception { String sql = "delete from t_oa_user where id = ?"; return super.executeUpdate(sql, user, new String[] {"id"}); } //修改 public int edit(User user) throws Exception { String sql = "update t_oa_user set name = ?,loginName = ?,pwd = ? where id = ?"; return super.executeUpdate(sql, user, new String[] {"name","loginName","pwd","id"}); } }
1.2.1查询测试
代码完成后我们用JUnit测试以下结果,现在UserDao下新建一个JUnittest类然后编写代码查询数据,如下:
package com.zking.dao; import static org.junit.Assert.*; import java.util.List; import java.util.Map; import org.junit.Test; import com.zking.entity.User; public class UserDaoTest { private UserDao userDao = new UserDao(); @Test public void testUserRole() throws Exception { User user = new User(); //user.setName("张");//按张进行查询--->测试模糊查询 List<Map<String, Object>> userRole = userDao.userRole(user, null); for (Map<String, Object> u : userRole) { System.out.println(u); } } @Test public void testAdd() throws Exception { fail("Not yet implemented"); } @Test public void testDel() { fail("Not yet implemented"); } @Test public void testEdit() { fail("Not yet implemented"); } }
测试结果:
可以看到我们已经成功拿到表里的数据。查询完成了就轮到我们的新增方法了。
1.2.2新增测试
UserDaoTest:
@Test public void testAdd() throws Exception { User user = new User(1, "增加咯", "zjl", "123", 4); userDao.add(user); }
JUnit测试结果:
由于我们没有遍历结果,我们去navicat用查询语句直接查询以下我们的用户表看新增成功与否,如下:
ok这里已经新增成功了,接下来我们完成剩下的部分。
1.2.3修改测试
UserDaoTest:
@Test public void testEdit() throws Exception { User user = new User(13, "修改咯", "xgl", "123456", 4); userDao.edit(user); }
JUnit执行结果:
Navicat查询表结果:
1.2.4删除测试
UserDaoTest:
@Test public void testDel() throws Exception { User user = new User(13, "修改咯", "xgl", "123456", 4); userDao.del(user); }
JUnit执行结果:
Navicat查询表结果:
可以看到我们之前添加和修改的那条数据已经被删除了。接下来就是R工具类的使用。
2.R工具类的使用
我们首先来到LayUI的数据表格类,点击开启头部工具栏,参考主页代码,如下:
最右侧数据类型讲解:
code——>一定等于0,不然数据出不来。
msg——>比如:查询成功
count——>服务条件总数
data——>具体,当前页展示的一些数据
参考完之后,我们就需要造数据了(数据表格内容),在造数据之前,首先我们需要建一个R.java
工具类,如下:
package com.zking.util; import java.util.HashMap; public class R extends HashMap{ public R data(String key, Object value) { this.put(key, value); return this; } public static R ok(int code, String msg) { R r = new R(); r.data("success", true).data("code", code).data("msg", msg); return r; } public static R error(int code, String msg) { R r = new R(); r.data("success", false).data("code", code).data("msg", msg); return r; } public static R ok(int code, String msg,Object data) { R r = new R(); r.data("success", true).data("code", code).data("msg", msg).data("data", data); return r; } public static R ok(int code, String msg, long count, Object data) { R r = new R(); r.data("success", true).data("code", code).data("msg", msg).data("count", count).data("data", data); return r; } }
再进行后台代码的编写,如下:
package com.zking.web; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.zking.dao.UserDao; import com.zking.entity.User; import com.zking.framework.ActionSupport; import com.zking.framework.ModelDriver; import com.zking.util.PageBean; import com.zking.util.R; import com.zking.util.ResponseUtil; public class UserAction extends ActionSupport implements ModelDriver<User> { private User user = new User(); private UserDao userDao = new UserDao(); public void login(HttpServletRequest req, HttpServletResponse resp) { try { User u = userDao.login(user); ResponseUtil.writeJson(resp, u); } catch (Exception e) { e.printStackTrace(); } } //查询 public void userRole(HttpServletRequest req, HttpServletResponse resp) { try { PageBean pageBean = new PageBean(); pageBean.setRequest(req);//参数初始化 List<Map<String,Object>> userRole = userDao.userRole(user, pageBean); // Map<String, Object> map = new HashMap<String, Object>();//未用R工具类时的数据代码 // map.put("code", 0); // map.put("msg", "查询成功"); // map.put("count", pageBean.getTotal()); // map.put("data", userRole); ResponseUtil.writeJson(resp, R.ok(0, "查询成功", pageBean.getTotal(), userRole));//用了之后的代码 } catch (Exception e) { e.printStackTrace(); } } //新增 public void add(HttpServletRequest req, HttpServletResponse resp) { try { int add = userDao.add(user); ResponseUtil.writeJson(resp, R.ok(0, "新增成功")); } catch (Exception e) { e.printStackTrace(); } } //删除 public void del(HttpServletRequest req, HttpServletResponse resp) { try { int del = userDao.del(user); ResponseUtil.writeJson(resp, R.ok(0, "删除成功")); } catch (Exception e) { e.printStackTrace(); } } //修改 public void edit(HttpServletRequest req, HttpServletResponse resp) { try { int edit = userDao.edit(user); ResponseUtil.writeJson(resp, R.ok(0, "修改成功")); } catch (Exception e) { e.printStackTrace(); } } @Override public User getModel() { return user; } }
在没用R工具类之前的代码是较为繁琐的(注解的那部分代码即为未借助R工具类的造数据方法)。
用了之后明显减少了很多。变得很简便,实用。
这一行代码取代了前面未打注解的四行代码,即为R工具类的使用方法;
写完了后台代码之后就轮到前台代码的编写了。
3.查询的前端代码实现
先建一个userManager.jsp用来显示我们的用户管理选项卡的代码(注:除了数据表格还有模糊查询所需的输入框和按钮也需要布局上去),如下:
userManager.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/common/header.jsp" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="${pageContext.request.contextPath }/static/js/system/userManage.js"></script> <title>Insert title here</title> </head> <body> <!-- 搜索栏 --> <div class="layui-form-item"> <div class="layui-inline"> <label class="layui-form-label">用户名:</label> <div class="layui-input-inline"> <input type="text" id="name" placeholder="请输入用户名" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-inline"> <div class="layui-input-inline"> <button id="btn_search" type="button" class="layui-btn layui-btn-normal"> <i class="layui-icon layui-icon-search"></i> 查询 </button> <button id="btn_add" type="button" class="layui-btn">新增</button> </div> </div> </div> <table class="layui-hide" id="test" lay-filter="test"></table> <script type="text/html" id="toolbarDemo"> <div class="layui-btn-container"> <button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button> <button class="layui-btn layui-btn-sm" lay-event="getCheckLength">获取选中数目</button> <button class="layui-btn layui-btn-sm" lay-event="isAll">验证是否全选</button> </div> </script> <script type="text/html" id="barDemo"> <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a> </script> <!-- 注意:如果你直接复制所有代码到本地,上述 JS 路径需要改成你本地的 --> <script> </script> </body>
userManage.js:
var table,$; layui.use(['table','jquery'], function(){ table = layui.table ,$ = layui.jquery; initTable(); $("#btn_search").click(function(){ query(); }); }); function initTable(){ table.render({ elem: '#test' ,url:'user.action?methodName=userRole' ,toolbar: '#toolbarDemo' //开启头部工具栏,并为其绑定左侧模板 ,defaultToolbar: ['filter', 'exports', 'print', { //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可 title: '提示' ,layEvent: 'LAYTABLE_TIPS' ,icon: 'layui-icon-tips' }] ,title: '用户数据表' ,cols: [[ {type: 'checkbox', fixed: 'left'} ,{field:'id', title:'ID', width:80, fixed: 'left', unresize: true, sort: true} ,{field:'loginName', title:'账户名', width:120, edit: 'text'} ,{field:'name', title:'用户名', width:150, edit: 'text', templet: function(res){ return '<em>'+ res.name +'</em>' }} ,{field:'pwd', title:'密码', width:80, edit: 'text', sort: true} ,{field:'rname', title:'角色名', width:100} ,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150} ]] ,page: true }); //头工具栏事件 table.on('toolbar(test)', function(obj){ var checkStatus = table.checkStatus(obj.config.id); switch(obj.event){ case 'getCheckData': var data = checkStatus.data; layer.alert(JSON.stringify(data)); break; case 'getCheckLength': var data = checkStatus.data; layer.msg('选中了:'+ data.length + ' 个'); break; case 'isAll': layer.msg(checkStatus.isAll ? '全选': '未全选'); break; //自定义头工具栏右侧图标 - 提示 case 'LAYTABLE_TIPS': layer.alert('这是工具栏右侧自定义的一个图标按钮'); break; }; }); //监听行工具事件 table.on('tool(test)', function(obj){ var data = obj.data; //console.log(obj) if(obj.event === 'del'){ layer.confirm('真的删除行么', function(index){ obj.del(); layer.close(index); }); } else if(obj.event === 'edit'){ layer.prompt({ formType: 2 ,value: data.email }, function(value, index){ obj.update({ email: value }); layer.close(index); }); } }); } function query(){ table.reload('test',{ where:{ name:$("#name").val() } ,request:{ pageName: 'page' ,limitName:'rows' } }); }
这里把原本写在jsp页面的表格代码剪到了js页面,然后在jsp页面直接调js用就行了。然后还有表格重载所需的代码(我们需要把模糊查询之后的结果重新以数据表格的方式呈现在我们的main.jsp页面上)。
最终效果图:
最后就是我们的增删改实现了。
4.增删改前端代码的实现
4.1新增
首先我们要通过点击新增按钮弹出一个新的页面去填写新增的信息,可以参考LayUI官方文档中的弹出层,如下:
//打开新增页面实现新增 function edit(title){ layer.open({ type: 2, //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层) title:title, area: ['660px', '340px'], //宽高 skin: 'layui-layer-rim', //样式类名 content: 'jsp/system/userEdit.jsp', //书本编辑页面 btn:['保存','关闭'], yes: function(index, layero){ //调用子页面中提供的getData方法,快速获取子页面的form表单数据 let data= $(layero).find("iframe")[0].contentWindow.getData(); console.log(data); //判断title标题 let methodName="add"; if(title=="编辑") methodName="edit"; $.post('user.action?methodName='+methodName, data,function(rs){ if(rs.success){ //关闭对话框 layer.closeAll(); //调用查询方法刷新数据 query(); }else{ layer.msg(rs.msg,function(){}); } },'json'); }, btn2: function(index, layero){ layer.closeAll(); } }); }
这里需要注意的是,弹出的新增页面不只是单个jsp中的信息,这里存在一个父子页面关系,如代码中的注解所说,我们需要调用子页面中提供的getdata方法,以此来获取子页面中的表单数据(子页面需要有一个下拉框来选择用户参加会议的身份,用户是以什么身份来参加本次会议的)。所以我们需要借助以下方法:
userEdit.js:
let layer,form,$; layui.use(['layer','form','jquery'],function(){ layer=layui.layer,form=layui.form,$=layui.jquery; initData(); }); function initData(){ console.log(parent.row); if(null!=parent.row){ //因为layui.each内部的逻辑问题导致的所以要先深拷贝一份然后再去val //parent.row:表格行对象 form.val('user',$.extend({}, parent.row||{})); $('#name').attr('readonly','readonly'); } } function getData(){ return form.val('user'); }
完成以上代码后,新增页面的效果图如下:
这时候我们试着新增信息,如下:
效果展示图:
注:这里如果用的LayUI包不是新版本的话会存在报错添加不了的情况,
开发者模式控制台提示错误名为:form val.....
解决方式:删除旧版LayUI的js文件,导入新版js,然后清除浏览器缓存,重新运行即可添加。
新增功能完成,后面就是其他两个功能的实现。
4.2删除
回到userManage.js页面,找到监听行工具事件的edit代码,如下:
将它修改为:
edit('编辑');
工作原理:调用删除方法发送给ajax来完成数据的删除功能,
所以我们需要把上面的提示框代码用ajax来替换,如下:
修改前:
最终的页面代码为:
var table,layer,$; var row; layui.use(['table','jquery','layer'], function(){ table = layui.table ,layer = layui.layer ,$ = layui.jquery; initTable(); $("#btn_search").click(function(){ query(); }); $("#btn_add").click(function(){ row = null; edit('新增'); }); }); //打开新增页面实现新增 function edit(title){ layer.open({ type: 2, //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层) title:title, area: ['660px', '340px'], //宽高 skin: 'layui-layer-rim', //样式类名 content: 'jsp/system/userEdit.jsp', //书本编辑页面 btn:['保存','关闭'], yes: function(index, layero){ //调用子页面中提供的getData方法,快速获取子页面的form表单数据 let data= $(layero).find("iframe")[0].contentWindow.getData(); console.log(data); //判断title标题 let methodName="add"; if(title=="编辑") methodName="edit"; $.post('user.action?methodName='+methodName, data,function(rs){ if(rs.success){ //关闭对话框 layer.closeAll(); //调用查询方法刷新数据 query(); }else{ layer.msg(rs.msg,function(){}); } },'json'); }, btn2: function(index, layero){ layer.closeAll(); } }); } //表格数据初始化 function initTable(){ table.render({ elem: '#test' ,url:'user.action?methodName=userRole' ,toolbar: '#toolbarDemo' //开启头部工具栏,并为其绑定左侧模板 ,defaultToolbar: ['filter', 'exports', 'print', { //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可 title: '提示' ,layEvent: 'LAYTABLE_TIPS' ,icon: 'layui-icon-tips' }] ,title: '用户数据表' ,cols: [[ {type: 'checkbox', fixed: 'left'} ,{field:'id', title:'ID', width:80, fixed: 'left', unresize: true, sort: true} ,{field:'loginName', title:'账户名', width:120, edit: 'text'} ,{field:'name', title:'用户名', width:150, edit: 'text', templet: function(res){ return '<em>'+ res.name +'</em>' }} ,{field:'pwd', title:'密码', width:80, edit: 'text', sort: true} ,{field:'rname', title:'角色名', width:100} ,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150} ]] ,page: true }); //头工具栏事件 table.on('toolbar(test)', function(obj){ var checkStatus = table.checkStatus(obj.config.id); switch(obj.event){ case 'getCheckData': var data = checkStatus.data; layer.alert(JSON.stringify(data)); break; case 'getCheckLength': var data = checkStatus.data; layer.msg('选中了:'+ data.length + ' 个'); break; case 'isAll': layer.msg(checkStatus.isAll ? '全选': '未全选'); break; //自定义头工具栏右侧图标 - 提示 case 'LAYTABLE_TIPS': layer.alert('这是工具栏右侧自定义的一个图标按钮'); break; }; }); //监听行工具事件 table.on('tool(test)', function(obj){ row = obj.data; //console.log(obj) if(obj.event === 'del'){ layer.confirm('确认删除吗?', {icon: 3, title:'提示'}, function(index){ $.post('user.action',{ 'methodName':'del', 'id':row.id },function(rs){ if(rs.success){ //调用查询方法刷新数据 query(); }else{ layer.msg(rs.msg,function(){}); } },'json'); layer.close(index); }); } else if(obj.event === 'edit'){ edit('编辑'); } }); } //表格重载的方法 function query(){ table.reload('test',{ where:{ name:$("#name").val() } ,request:{ pageName: 'page' ,limitName:'rows' } }); }
删除测试结果如下:
可以看到我们先前添加的“小文”已经被删除了。
修改效果演示:
最后LayUI之CRUD就到这里,祝大家在敲代码的路上一路通畅!