目录
为什么在servlet层向页面回显值的时候用了个r类,这是什么类
前言
上一篇讲到了layui遍历左侧菜单,点击菜单显示对应的tab选项卡,如果没有了解的小伙伴可以通过传送门进入,今天就来跟大家讲一下如何使用layui前端框架来完成我们的增删改查,
今日金句:
学会自己去看文档,自己学习
(用户管理)源码:
jsp主界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="/common/head.jsp" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- 引入 layui.js -->
<script src="static/js/system/userManage.js"></script>
<title>用户管理</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>
<!-- 数据表格及分页 -->
<!--layui-table:在其他地方通过该 filter 字符串来操作该表格(也就是在其他地方可以通过这个tb,使用操作这张表) -->
<table id="tb" lay-filter="tb" class="layui-hide" style="margin-top:-15px;"></table>
<!-- 对话框(新增和编辑共用一个页面) -->
<script type="text/html" id="toolbar">
<button class="layui-btn layui-btn-sm" lay-event="edit">编辑</button>
<button class="layui-btn layui-btn-sm" lay-event="del">删除</button>
<button class="layui-btn layui-btn-sm" lay-event="reset">重置密码</button>
</script>
</body>
</html>
主界面 js
//把需要用到的模块定义成全局变量
let layer,$,table;
var row;
layui.use(['jquery','layer','table'],function(){
layer=layui.layer,
$=layui.jquery,
table=layui.table;
//初始化表格
initTable();
//查询按钮的点击事件
$('#btn_search').click(function(){
select();//调用写好的查询的方法
});
//绑定新增按钮的点击事件
$('#btn_add').click(function(){
row=null;
open('新增');
});
});
//1.初始化数据表格
function initTable(){
table.render({ //执行渲染
elem: '#tb', //指定原始表格元素选择器(推荐id选择器)
url: 'user.action?methodName=listUserRole', //请求地址
height: 820, //自定义高度
loading: false, //是否显示加载条(默认 true)
cols: [[ //设置表头 field是数据库的字段名,title是显示在页面中的值
{field: 'id', title: '用户编号', width: 210},
{field: 'name', title: '用户名', width: 210},
{field: 'loginName', title: '登录账号', width: 210},
{field: 'rname', title: '用户角色名', width: 210},
{field: '', title: '操作', width: 220,toolbar:'#toolbar'},//#toolbar是工具栏的id
]]
,page:true
});
//在页面中的<table>中必须配置lay-filter="tb_goods"属性才能触发属性!!!
table.on('tool(tb)', function (obj) {//obj是指这张表中的数据
row = obj.data;//将这张表中的数据赋给row这个变量
//obj.event:获取触发事件的元素的 event 值,用于区分不同的操作
if (obj.event == "edit") {//如果这个值等于edit,那么调用open("编辑");
open("编辑");
}else if(obj.event == "del"){//如果这个值等于del,那么跳到user.action调用删除的方法
layer.confirm('确认删除吗?', {icon: 3, title:'提示'}, function(index){
$.post('user.action?methodName=del&id='+row.id,{
},function(del){
if(rs.success){
//调用查询方法刷新数据
select();
}else{
layer.msg(rs.msg,function(){});
}
},'json');
layer.close(index);
});
}else{
}
});
}
//2.点击查询
function select(){
//reload中填写的‘tb’是表格的id
table.reload('tb', {
url: 'user.action', //请求地址
method: 'POST', //请求方式,GET或者POST
loading: true, //是否显示加载条(默认 true)
page: true, //是否分页
where: { //设定异步数据接口的额外参数,任意设
'methodName':'listUserRole',
'name':$('#name').val()//获取输入框输入的值
},
request: { //自定义分页请求参数名
pageName: 'page', //页码的参数名称,默认:page
limitName: 'rows' //每页数据量的参数名,默认:limit
}
});
}
//3.对话框
function open(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="upd";
$.post('user.action?methodName='+methodName,
data,function(rs){
if(rs.success){
//关闭对话框
layer.closeAll();
//调用查询方法刷新数据
select();
}else{
layer.msg(rs.msg,function(){});
}
},'json');
},
btn2: function(index, layero){
layer.closeAll();
},
});
}
新增和修改的jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="/common/head.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="static/js/system/userEdit.js"></script>
<title>用户新增</title>
</head>
<style>
.layui-form-select dl{
max-height:150px;
}
</style>
<body>
<div style="padding:10px;">
<form class="layui-form layui-form-pane" lay-filter="user">
<input type="hidden" name="id"/>
<div class="layui-form-item">
<label class="layui-form-label">用户名称</label>
<div class="layui-input-block">
<input type="text" id="name" name="name" autocomplete="off" placeholder="请输入用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户角色</label>
<div class="layui-input-block">
<select name="rid">
<option value="">---请选择---</option>
<option value="1">管理员</option>
<option value="2">发起者</option>
<option value="3">审批者</option>
<option value="4">参与者</option>
<option value="5">会议管理员</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">登录账号</label>
<div class="layui-input-block">
<input type="text" name="loginName" lay-verify="required" placeholder="请输入账号" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">登录密码</label>
<div class="layui-input-block">
<input type="password" name="pwd" placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
</div>
</form>
</div>
</body>
</html>
新增和修改的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){//子调父
//点击编辑按钮的时候
//$.extend({}, parent.row || {}) 的作用是创建一个新的对象,并将 parent.row 中的键值对复制到该新对象中,达到给表单赋值的目的
form.val('user',$.extend({}, parent.row||{}));//将父页面传递的行数据赋值到名为 'user' 的表单中
$('#name').attr('readonly','readonly');//readonly:设置为只读状态
}
}
function getData(){
//<form class="layui-form layui-form-pane" lay-filter="user">
//取 user from中的值
return form.val('user');
}
Dao层
package com.wenhao.dao;
import java.util.List;
import java.util.Map;
import com.wenhao.entity.User;
import com.zking.util.BaseDao;
import com.zking.util.PageBean;
import com.zking.util.StringUtils;
/**
* dao层
* @author wenhao
*
*/
public class UserDao extends BaseDao<User> {
//增加
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 = ?";// 定义sql语句
return super.executeUpdate(sql, user,new String[] {"id"});
}
// 修改
public int upd(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"});
}
//查询角色的信息
//当实体类的属性与数据库的字段相同的时候使用 ➡List<User> BaseDao中的这一个方法
//当实体类的属性与数据库的字段不同使用➡List<Map<String, Object>>(可能有一个数据库中没有的字段,比如下面的这个给通过行转列查出角色名的方法,也可能是连表查询出来的字段,总之就是数据库字段与实体类属性值不对等的情况下使用)
public List<Map<String, Object>> listUserRole(User user, PageBean pageBean) throws Exception {
String sql = "select *,\r\n" +
"(case rid\r\n" +
"when 1 then '管理人员'\r\n" +
"when 4 then '参与者'\r\n" +
"else '其他角色' end) as rname\r\n" +
"from t_oa_user where 1=1 ";
String name = user.getName();
if (StringUtils.isNotBlank(name))
sql += " and name like '%" +name+ "%' ";
return super.executeQuery(sql, pageBean);
}
//查询所有
public List<User> list( User user, PageBean pageBean) throws Exception {
String sql="select * from t_oa_user";
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> list= super.executeQuery(sql, User.class, null);
if(list!=null&&list.size()==1) {
return list.get(0);
}else {
return null;
}
}
//注册
public int register(User user) throws Exception {
String sql = "insert into t_oa_user(name,loginName,pwd,rid) values(?,?,?,0);";// 定义sql语句
return super.executeUpdate(sql, user,new String[] {"name","loginName","pwd"});
}
}
Servlet
package com.wenhao.web;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wenhao.dao.UserDao;
import com.wenhao.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 ud = new UserDao();
// 登录
public void login(HttpServletRequest req, HttpServletResponse resp) {
try {
User login = ud.login(user);
ResponseUtil.writeJson(resp, login);
} catch (Exception e) {
e.printStackTrace();
}
}
// 注册
public void register(HttpServletRequest req, HttpServletResponse resp) {
try {
int register = ud.register(user);
if (register > 0) {
ResponseUtil.writeJson(resp, "OK");
} else {
ResponseUtil.writeJson(resp, "NO");
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 增加
public String add(HttpServletRequest req, HttpServletResponse resp) {
try {
// 影响行数
int add = ud.add(user);
if (add > 0) {
ResponseUtil.writeJson(resp, R.ok(0, "用户数据新增成功"));
} else {
ResponseUtil.writeJson(resp, R.error(0, "用户数据新增失败"));
}
} catch (Exception e) {
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据查询失败"));
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
// 删除
public String del(HttpServletRequest req, HttpServletResponse resp) {
try {
// 影响行数
int del = ud.del(user);
if (del > 0) {
ResponseUtil.writeJson(resp, R.ok(0, "用户数据删除成功"));
} else {
ResponseUtil.writeJson(resp, R.error(0, "用户数据删除失败"));
}
} catch (Exception e) {
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据删除失败"));
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
// 修改
public String upd(HttpServletRequest req, HttpServletResponse resp) {
try {
// 影响行数
int upd = ud.upd(user);
if (upd > 0) {
ResponseUtil.writeJson(resp, R.ok(0, "用户数据修改成功"));
} else {
ResponseUtil.writeJson(resp, R.error(0, "用户数据修改失败"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "用户数据修改失败"));
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
//查询用户的角色(权限)
public String listUserRole(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
List<Map<String, Object>> users = ud.listUserRole(user, pageBean);
// layui 的code 返回一定要是 0,不能是200,否者返回不了数据
ResponseUtil.writeJson(resp, R.ok(0, "查询成功", pageBean.getTotal(), users));
} catch (Exception e) {
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "查询失败"));
} catch (Exception e1) {
e1.printStackTrace();
}
}
return null;
}
//查询所有
public String list(HttpServletRequest req, HttpServletResponse resp) {
try {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
List<User> list = ud.list(user, pageBean);
// layui 的code 返回一定要是 0,不能是200,否者返回不了数据
ResponseUtil.writeJson(resp, R.ok(0, "查询成功", pageBean.getTotal(), list));
} catch (Exception e) {
e.printStackTrace();
try {
ResponseUtil.writeJson(resp, R.error(0, "查询失败"));
} catch (Exception e1) {
e1.printStackTrace();
}
}
return null;
}
@Override
public User getModel() {
return user;
}
}
今日问答
为什么在servlet层向页面回显值的时候用了个r类,这是什么类
工具类,专门用来做对应的事情的。类似于这样的类以后公司还会有很多,在上期的源码包中,com.zking.util下有对应的源码,想要的小伙伴可以去获取
关于servlet层中查询角色的方法
大家可能有个疑问:为什么我的返回类型是 List<Map<String, Object>>
因为这是专门针对于多表查询的方法,在公司中,基本不会用单表查询,如果想要打印多段数据,不可能总是去创建对应的实体类,所以就有了这个方法,不需要理解,只需要会用就行
代码给到大家:
package com.zking.util;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author 文昊
*
* @param <T>
*/
public class BaseDao<T> {
/**
* 适合多表联查的数据返回
* @param sql
* @param pageBean
* @return
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public List<Map<String, Object>> executeQuery(String sql, PageBean pageBean)
throws SQLException, InstantiationException, IllegalAccessException {
List<Map<String, Object>> list = new ArrayList<>();
Connection con = DBAccess.getConnection();
PreparedStatement pst = null;
ResultSet rs = null;
/*
* 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...)
*/
if (pageBean != null && pageBean.isPagination()) {
// 必须分页(列表需求)
String countSQL = getCountSQL(sql);
pst = con.prepareStatement(countSQL);
rs = pst.executeQuery();
if (rs.next()) {
pageBean.setTotal(String.valueOf(rs.getObject(1)));
}
// 挪动到下面,是因为最后才处理返回的结果集
// -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%'
// -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据
// -- countSql=select count(1) from (sql) t 符合条件的总记录数
String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据
pst = con.prepareStatement(pageSQL);
rs = pst.executeQuery();
} else {
// 不分页(select需求)
pst = con.prepareStatement(sql);// 符合条件的所有数据
rs = pst.executeQuery();
}
// 获取源数据
ResultSetMetaData md = rs.getMetaData();
int count = md.getColumnCount();
Map<String, Object> map = null;
while (rs.next()) {
map = new HashMap<>();
for (int i = 1; i <= count; i++) {
// map.put(md.getColumnName(i), rs.getObject(i));
map.put(md.getColumnLabel(i), rs.getObject(i));
}
list.add(map);
}
return list;
}
/**
*
* @param sql
* @param attrs
* map中的key
* @param paMap
* jsp向后台传递的参数集合
* @return
* @throws SQLException
* @throws NoSuchFieldException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public int executeUpdate(String sql, String[] attrs, Map<String, String[]> paMap) throws SQLException,
NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Connection con = DBAccess.getConnection();
PreparedStatement pst = con.prepareStatement(sql);
for (int i = 0; i < attrs.length; i++) {
pst.setObject(i + 1, JsonUtils.getParamVal(paMap, attrs[i]));
}
return pst.executeUpdate();
}
/**
* 批处理
* @param sqlLst
* @return
*/
public static int executeUpdateBatch(String[] sqlLst) {
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DBAccess.getConnection();
// 设置不自动提交
conn.setAutoCommit(false);
for (String sql : sqlLst) {
stmt = conn.prepareStatement(sql);
stmt.executeUpdate();
}
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
throw new RuntimeException(e1);
}
e.printStackTrace();
throw new RuntimeException(e);
} finally {
DBAccess.close(conn, stmt, null);
}
return sqlLst.length;
}
/**
* 通用的增删改方法
*
* @param book
* @throws Exception
*/
public int executeUpdate(String sql, T t, String[] attrs) throws Exception {
// String[] attrs = new String[] {"bid", "bname", "price"};
Connection con = DBAccess.getConnection();
PreparedStatement pst = con.prepareStatement(sql);
// pst.setObject(1, book.getBid());
// pst.setObject(2, book.getBname());
// pst.setObject(3, book.getPrice());
/*
* 思路: 1.从传进来的t中读取属性值 2.往预定义对象中设置了值
*
* t->book f->bid
*/
for (int i = 0; i < attrs.length; i++) {
Field f = t.getClass().getDeclaredField(attrs[i]);
f.setAccessible(true);
pst.setObject(i + 1, f.get(t));
}
return pst.executeUpdate();
}
/**
* 通用分页查询
*
* @param sql
* @param clz
* @return
* @throws Exception
*/
public List<T> executeQuery(String sql, Class<T> clz, PageBean pageBean) throws Exception {
List<T> list = new ArrayList<T>();
Connection con = DBAccess.getConnection();
;
PreparedStatement pst = null;
ResultSet rs = null;
/*
* 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...)
*/
if (pageBean != null && pageBean.isPagination()) {
// 必须分页(列表需求)
String countSQL = getCountSQL(sql);
pst = con.prepareStatement(countSQL);
rs = pst.executeQuery();
if (rs.next()) {
pageBean.setTotal(String.valueOf(rs.getObject(1)));
}
// 挪动到下面,是因为最后才处理返回的结果集
// -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%'
// -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据
// -- countSql=select count(1) from (sql) t 符合条件的总记录数
String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据
pst = con.prepareStatement(pageSQL);
rs = pst.executeQuery();
} else {
// 不分页(select需求)
pst = con.prepareStatement(sql);// 符合条件的所有数据
rs = pst.executeQuery();
}
while (rs.next()) {
T t = clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
f.set(t, rs.getObject(f.getName()));
}
list.add(t);
}
return list;
}
/**
* 将原生SQL转换成符合条件的总记录数countSQL
*
* @param sql
* @return
*/
private String getCountSQL(String sql) {
// -- countSql=select count(1) from (sql) t 符合条件的总记录数
return "select count(1) from (" + sql + ") t";
}
/**
* 将原生SQL转换成pageSQL
*
* @param sql
* @param pageBean
* @return
*/
private String getPageSQL(String sql, PageBean pageBean) {
// (this.page - 1) * this.rows
// pageSql=sql limit (page-1)*rows,rows
return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows();
}
}
为什么我代码没有错,却无法得到对应想要的结果?
可能是jar包或者一些引入的库,引入的文件信息版本有问题,所以最好是对应的文件,看对应版本的文档,避免出错
总结:
最近公司需要用这个layui,所以就浅浅学习了一下,对于很多小伙伴们看不懂源码的,我的建议其实就是建议大家多去一些框架的官网去看文档学习,这样学习起来心里是有底的,而且也大大提高了自己的学习能力,如果说公司换一种框架去开发了,至少可以有一种学习的方式或者底气吧