实习笔记:java页面的增删改查,分页,模糊查询

2022-09-05 14:31:41 浏览数 (1)

实习笔记

这是实习水了好几天来第一次被安排的任务,写一个个人用户中心模块的增删改查,我大概花了三天写完,离谱。。这里做一些笔记吧。 首先公司项目的技术是,springboot,前端用的springboot的内置模板Freemarker,但不是jsp页面,全是html和ftl页面,前后端交互的数据通过ajax请求来交互,前端ui用的layui框架 后端的话使用的是原生的jdbc对应的springtemplate来进行增删改查,分别controller,service,dao三层,并且将接口省去了,确实方便很多。。。。 我的任务就是对一个页面进行增删改查,如下图:

layui的官方网站
  • 引入layui:https://www.layuicdn.com/#Layui
  • layui开发文档:https://www.layui.site/doc/index.htm
  • 在线演示layui组件:https://www.layui.site/demo/index.htm
layui的cdn引入模板
代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
	<!-- 引入 layui.css -->
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.6.8/css/layui.css">
     <!-- 引入 layui.js -->
<script src="https://www.layuicdn.com/layui-v2.6.8/layui.js">
</head>
<body>
 
</body>
</html>

因为在一个页面中,有子页面,因此前端有两个页面,一个主页面person,一个提交页面personSub

整体页面逻

主页面person的js逻辑

代码语言:javascript复制
 var fwqxsqdata;
    var perCenTable;
    var isFirst = true;
    // 应用权限表格
    var YYQXSQtable;
 
    //服务权限申请
    layui.use(['table', 'element', 'laypage', 'form'], function () {
        var table = layui.table,
            $ = layui.jquery,
            element = layui.element
            , page = layui.laypage
            , form = layui.form; //Tab的切换功能,切换事件监听等,需要依赖element模块
        var height = $(window).height();
        var heightStr = 'full-300';
        if (height > 500 && height < 900) {
            heightStr = 'full-180';
        }
        var lbParmas = {
            page: 1,
            limit: 10,
            scenceIds: $("#scenceIds").val()
        };
        // 获取数据服务列表
        var getList = function () {
            lbParmas = {
                pageNo: 1,
                pageSize: 10,
                moudleName: $("#MoudleName").val()
            };
            postAjax(requestUrl   "/perCenterApi/selectGrzxXmMKList", lbParmas, function (data) {
                console.log(data)
                page.render({
                    elem: 'layuipage',
                    count: data.count,
                    contentType: "application/json;charset=UTF-8",
                    curr: lbParmas.pageNo,
                    limit: lbParmas.pageSize,
                    first: "首页",
                    last: "尾页",
                    layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'],
                    jump: function (obj, first) {
                        if (!first) {
                            lbParmas.pageNo = obj.curr;
                            lbParmas.pageSize = obj.limit;
                            lbParmas.scenceIds=$("#scenceIds").val();
                            getAjax(requestUrl   "/perCenterApi/selectGrzxXmMKList", lbParmas,function (data) {
                                perCenTable.reload({
                                    data: data.list
                                });
                                $('#perCenTable').parent().find('.layui-table-header').find('.layui-form-checkbox').hide();
                            })
                        }
                    }
                });
            perCenTable = table.render({
                elem: '#perCenTable',
                id: 'perCenTable'
                , cols: [
                    [ //标题栏
                        {type: 'checkbox'},
                        {field: 'id', title: 'id',hide:true},
                        {field: 'moduleName', title: '模块名称'},
                        {field: 'dispSn', title: '排序'},
                        {field: 'bz', title: '备注'},
                    ]
                ]
                , even: true
                , height: heightStr
                , data: data.list
                , page: false //是否显示分页
                , limit: Number.MAX_VALUE
            });
                $('#perCenTable').parent().find('.layui-table-header').find('.layui-form-checkbox').hide();
            }, function (res) {
            });
        };
        table.on('checkbox(perCenTable)',function(obj){
            $('#perCenTable').parent().find('.layui-table-header').find('.layui-form-checkbox').hide();
            if(obj.checked) {
                fwqxsqdata = obj;
            } else {
                fwqxsqdata = null;
                $(obj.tr).find('td div.laytable-cell-checkbox div.layui-form-checkbox').attr('class','layui-unselect layui-form-checkbox');
            }
        });
        getList('');
 
        //查询
        $("#Fsearch").click(function () {
            getList(lbParmas);
        });
        //重置
        $("#Freset").click(function () {
            $("#MoudleName").val("");
            getList();
        });
        function init(){
            lbParmas.scenceIds = $('#scenceIds').val();
            getList();
        }
        $("#mqSearchBtn").click(function () {
            init();
        })
        //新增
        $('#insertBtn').click(function () {
            var width = $(window).width();
            var height = $(window).height();
            var index = layer.open({
                type: 2,
                title: '新增',
                // area: [width   'px', height   'px'],
                area: ['75%', '70%'],
                content: 'personalCenterSubApi.html?flag=add',
                end: function () {
                    location.reload();
                }
            });
            // layer.full(index);
        });
        //编辑
        $('#updateBtn').click(function () {
            if (!fwqxsqdata) {
                layer.alert('请选择一条数据!');
                return;
            }
            var title = fwqxsqdata.data.serverName;
            var width = $(window).width();
            var height = $(window).height();
            console.log(fwqxsqdata.data.id);
            var index = layer.open({
                type: 2,
                title: title,
                // area: [width   'px', height   'px'],
                area: ['85%', '70%'],
 
                content: 'personalCenterSubApi.html?flag=update&id='   fwqxsqdata.data.id,
                end: function () {
                    location.reload();
                }
            });
            // layer.full(index);
        });
        //查看
        $('#chaKanBtn').click(function () {
            if (!fwqxsqdata) {
                layer.alert('请选择一条数据!');
                return;
            }
            var title = fwqxsqdata.data.serverName;
            var width = $(window).width();
            var height = $(window).height();
            var index = layer.open({
                type: 2,
                title: title,
                // area: [width   'px', height   'px'],
                area: ['85%', '70%'],
                content: 'personalCenterSubApi.html?flag=chakan&id='   fwqxsqdata.data.id
            });
            // layer.full(index);
        });
        //删除
        $('#delBtn').click(function () {
            if (!fwqxsqdata) {
                layer.alert('请选择一条数据!');
                return;
            }
            console.log(fwqxsqdata.data.id)
             var parmas = {
                id: fwqxsqdata.data.id
            };
            postAjax(requestUrl   "/perCenterApi/deleteGrzxMK?" , parmas, function (data) {
                if (data.msg == '删除成功') {
                    layer.alert('删除成功!');
                    fwqxsqdata = null;
                    $("#scenceIds").val("");
                    getList();
                } else {
                    layer.alert('删除失败!');
                }
            });
        });
 
    })

子页面personSub页面的js逻辑

代码语言:javascript复制
layui.use(['table', 'element', 'laypage', 'form'], function () {
        var table = layui.table,
            $ = layui.jquery,
            element = layui.element
            , upload = layui.upload
            , page = layui.laypage
            , form = layui.form; //Tab的切换功能,切换事件监听等,需要依赖element模块
 
 
        var flag = getUrlParam('flag');
        $('#id').val(getUrlParam('id'));//id
        //跳转页面动态
        if (flag == 'update') {
            var param = {
                id: getUrlParam  ('id')
            };
            //下拉框加载
            postAjax(requestUrl   "/perCenterApi/getModuleByParCode", param, function (data) {
                $.each(data, function(index, value) {
                    $("#moduleCode").append('<option value='   value.code   '>'   value.name   '</option>');
                });
                layui.form.render("select");
 
                postAjax(requestUrl   "/perCenterApi/selectGrzxXm", param, function (data) {
                    $('#showPic').show()
                    $('#showPic').unbind()
                    $('#showPic').click(function () {
                        layer.open({
                            type: 2,
                            area :['70%','70%'],
                            content: requestUrl   '/perCenterApi/getPicUrl?id='   getUrlParam('id')
                        });
                    })
                    $('#moduleCode').find("option:selected").text(data.data.moduleName)//模块名称
                    form.render('select');
                    $('#dispSn').val(data.data.dispSn);//排序
                    $('#remark').val(data.data.bz);//备注
                });
                $('select').attr('disabled', 'disabled');
            });
 
        } else if (flag == 'chakan') {
            $('#saveBtn').hide();
            var param = {
                id: getUrlParam('id')
            };
            postAjax(requestUrl   "/perCenter/getModuleByParCode", param, function (data) {
                $.each(data, function (index, value) {
                    $("#moduleCode").append('<option value='   value.code   '>'   value.name   '</option>');
                });
                layui.form.render("select");
                postAjax(requestUrl   "/perCenterApi/selectGrzxXm", param, function (data) {
 
                    console.log(data)
                    // $('#moduleCode').val(data.data.moduleName);//模块名称
                    //下拉框设置值得这么写
                    $('#moduleCode').find("option:selected").text(data.data.moduleName)
                    $('#dispSn').val(data.data.dispSn);//排序
                    $('#remark').val(data.data.bz);//备注
                    form.render('select');
                });
 
                $('input,textarea,select').attr('disabled', 'disabled');
            });
        }else{
            postAjax(requestUrl   "/perCenterApi/getModuleByParCode", param, function (data) {
                $.each(data, function(index, value) {
                    $("#moduleCode").append('<option value='   value.code   '>'   value.name   '</option>');
                });
                layui.form.render("select");
            });
        }
        // 提交
        $('#saveBtn').click(function (data) {
            var moduleCode = $('#moduleCode').val();
            if (moduleCode == '') {
                layer.alert('模块名称不能为空');
                return;
            }
            let moduleName = $("#moduleCode").find("option:selected").text();
            $('#moduleName').val(moduleName)
 
            var dispSn = $('#dispSn').val();//排序
            if (dispSn == '') {
                layer.alert('排序不能为空');
                return;
            }
            var bz = $('#remark').val();//排序
            $('#bz').val(bz);
 
            var datas = new FormData(document.getElementById('perCenSub'));
 
            if (flag == 'update') {
                postAjaxForm(requestUrl   "/perCenterApi/updateGrzxMK", datas, function (res) {
                    if (res.msg == '修改成功') {
                        layer.alert('修改成功!',function () {
                            colseWindow();
                        });
                    } else {
                        layer.alert('修改失败!');
                    }
                });
            } else if (flag == 'add') {
                let moduleName = $("#moduleCode").find("option:selected").text();
                //先进行判断
                console.log(moduleName)
                var param = {
                    moduleName: moduleName
                };
                var a = false;
                postAjax(requestUrl   "/perCenterApi/selectGrzxXmByName", param, function (data) {
                    console.log(moduleName)
                    console.log(data)
                    if(data.data==null){
                        a=false
                    }else{
                        if(moduleName == data.data.moduleName)
                            a = true
                    }
                    console.log(a)
                    if(a==false){
                        postAjaxForm(requestUrl   "/perCenterApi/addGrzxMk", datas, function (res) {
 
                            console.log("log:" res.msg)
                            if (res.msg == '新增成功') {
                                layer.alert('新增成功!',function () {
                                    colseWindow();
                                });
                            } else {
                                layer.alert('新增失败!');
                            }
                        });
                    }else{
                        layer.alert('新增失败!');
                    }
 
                });
 
            }
        });
        // 关闭页面
        $('#closeBtn').click(function () {
            colseWindow();
        });
        //关闭子页面跳转父页面
        function colseWindow() {
            var index = parent.layer.getFrameIndex(window.name);
            parent.layer.close(index);
        }
    });
下面演示一个功能的全部代码

前面已经知道了,逻辑代码中,使用layui.use方面进行页面刷新,用户进入页面后,处于观看状态,这时为用户准备了很多按钮,每一个按钮都绑定一个事件,这里介绍一两个功能。

新增一条数据

主页面绑定的按钮新增事件
代码语言:javascript复制
        //新增
        $('#insertBtn').click(function () {
            var width = $(window).width();
            var height = $(window).height();
            var index = layer.open({
                type: 2,
                title: '新增',
                // area: [width   'px', height   'px'],
                area: ['75%', '70%'],
                content: 'personalCenterSubApi.html?flag=add',
                end: function () {
                    location.reload();
                }
            });
            // layer.full(index);
        });

通过绑定id为insertBtn的按钮点击事件,然后利用layui框架的open函数打开一个页面内置窗口(为什么要这么做?因为你新增,你得新增数据啊,当然数据就填写在这个新增的窗口中)

新开窗口的页面逻辑

可以看到,这里没有页面加载函数,事实上,也不需要,通过前面首页传来的参数flag,分别调用新增,修改,查看函数。并且,绑定了两个按钮。下面看下这个新增的详细代码

代码语言:javascript复制
else{
            postAjax(requestUrl   "/perCenterApi/getModuleByParCode", param, function (data) {
                $.each(data, function(index, value) {
                    $("#moduleCode").append('<option value='   value.code   '>'   value.name   '</option>');
                });
                layui.form.render("select");
            });
        }

你可能会好奇,为什么新增有两端代码(下面一段),前面一段是什么?其实,是加载下拉框。这里我不能再访问那个页面路径了,因此选个效果图看看:

$.each(data, function(index, value)则是一个jq中的遍历函数,将其渲染到下拉框中,通过css中的id选择,选择到下拉框

代码语言:javascript复制
<select id="moduleCode" name="moduleCode" lay-filter="moduleCode">
<option value="" id="option">请选择</option>
<#-- <option value="1">QUICK</option>-->
<#-- <option value="2">TEST</option>-->
</select>

此时,用户再次处于查看状态,再写前端逻辑时,一定要注意到用户的状态!下面我把这种状态称为停滞状态,方便记忆。停滞状态的用户需要通过点击等事件来响应操作,这时就能想到了这个页面只有两个绑定事件,一个提交按钮,一个关闭按钮,因此,新增就在提交按钮里!但是提交按钮,不都是让你新增的,还有修改,因此需要一个flag判断,还记得首页我们请求发送到这个页面带了一个参数flag=add吗?

代码语言:javascript复制
else if (flag == 'add') {
                let moduleName = $("#moduleCode").find("option:selected").text();
                //先进行判断
                console.log(moduleName)
                var param = {
                    moduleName: moduleName
                };
                var a = false;
                postAjax(requestUrl   "/perCenterApi/selectGrzxXmByName", param, function (data) {
                    console.log(moduleName)
                    console.log(data)
                    if(data.data==null){
                        a=false
                    }else{
                        if(moduleName == data.data.moduleName)
                            a = true
                    }
                    console.log(a)
                    if(a==false){
                        postAjaxForm(requestUrl   "/perCenterApi/addGrzxMk", datas, function (res) {
 
                            console.log("log:" res.msg)
                            if (res.msg == '新增成功') {
                                layer.alert('新增成功!',function () {
                                    colseWindow();
                                });
                            } else {
                                layer.alert('新增失败!');
                            }
                        });
                    }else{
                        layer.alert('新增失败!');
                    }
 
                });
            }

这里有个业务需求就是不能新增重复的名称,因此再新增之前,进行了一次查询,这个先不看了,可以看到新增直接发送请求来到了/perCenterApi/addGrzxMk这里,接下来看下controller代码之前,看下提交的参数datas,这个参数datas在前面的代码中声明是这样的

代码语言:javascript复制
var datas = new FormData(document.getElementById('perCenSub'));

因为,datas的类型是object,并且是一个类似。而这里用到了FormData函数,需要传入一个表单对象,会将表单中的值全部映射到datas,并且postajax提交时,注明一下postajaxForm,

代码语言:javascript复制
//这里的讲下formdata对象,其实就是一个map键值对集合,可以通过formdata函数将表单中的对象转为集合通过ajax方便传值
//我们可以通过name来访问表单中的字段
formdata.get("username");  //获取username的值
formdata.get("pwd");       //获取pwd的值
//我们也可以添加数据
formdata.append("token","fegahgag54")
后端controller层代码
代码语言:javascript复制
    @RequestMapping(value = "/addGrzxMk",name = "新增模块信息")
    @ResponseBody
    public ResultModel addGrzxMk(String bz,
                                 String moduleName,
                                 String dispSn,
                                 HttpServletResponse response,
                                 HttpServletRequest request ){
        ResultModel resultModel = new ResultModel();
        String msg = "";
        boolean success = true;
        UserInfo userInfo = WebUtil.getCurrUserInfo(request,response);
        GarzaXmas garzaXmas = new GarzaXmas();
        garzaXmas.setBz(bz);
        garzaXmas.setModuleName(moduleName);
        garzaXmas.setDispSn(dispSn);
        garzaXmas.setRyId(userInfo.getUserId());
 
        msg = personalCenterService.addGrzxMk(garzaXmas);
        resultModel.setSuccess(success);
        resultModel.setMsg(msg);
        return resultModel;
    }

这里用到了springmvc的知识点:

为什么提交的url来到了controller对应的这个addGrzxMk这里?

这里是可以说是springmvc的原理,其实老大哥tomcat本来也有这个原理,不就是servlet吗?通过注解配置WebServlet(“/hello”)实现,至于这些:

  • tomcat中如何实现url输入路径,配置注解@WebServlet就找到对应的servlet方法?
  • 那为什么现在改了@requestmapping注解,或者说为什么要用springmvc?springmvc的底层原理路由是怎么样的
  • spring在当中是扮演了怎么样的角色,和tomcat的关系,和springmvc的关系?

这里开一个新文章来说说这些问题

spring,tomcat,springmvc之间的关系

那么继续,既然获得了ajax请求过来的数据,那么就好办, 新增嘛,肯定是声明一个新增的这个类对象来封装这些数据。代码中该对象变量是garzaXmas。这里为什么不是用对象来接收?很简单,因为前端传来的值并不是这个对象的所有字段都包含了。另外一点就是,如果是查询,删除,修改这些需求的话,是根据id或者名称来的,那么函数之间传参直接用一个string类型的字符串可以吗?可以,但不建议,因为习惯都是通过对象在逻辑之间传递,并且后续你查询,如果是加where条件呢?你又得改代码,加参数。

下面来看下service层的代码吧
代码语言:javascript复制
public String addGrzxMk(GarzaXmas grzxXmry) {
        int i = 0 ;
        try {
            i = personalCenterDao.addGrzxMk(grzxXmry);
            if (i >0){
                return "新增成功";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "新增失败";
    }

没啥好说的

下面是dao层的代码
代码语言:javascript复制
 public int addGrzxMk(GarzaXmas grzxXmry) {
 
        String uuid = UUID.randomUUID().toString();
        String sql ="Insert into t_grzx_mk(id,ry_id,module_name,disp_sn,bz) values(?,?,?,?,?)";
        LobHandler handler = new DefaultLobHandler();
        Integer execute = jt.execute(sql, new AbstractLobCreatingPreparedStatementCallback(handler) {
                    @Override
                    protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
                        int index = 1;
                        ps.setObject(index  , uuid);
                        ps.setObject(index  , grzxXmry.getRyId());
                        ps.setObject(index  , grzxXmry.getModuleName());
                        ps.setObject(index  , grzxXmry.getDispSn());
                        ps.setObject(index  , grzxXmry.getBz());
                    }
                }
        );
        this.close();
        return execute;
    }

这里也没啥好说的,唯一点就是使用了DefaultLobHandler这个类,来实现插入一些BLOB(二进制大型对象)和 CLOB(字符大型对象)数据,参考链接:

https://www.cnblogs.com/dalianpai/p/13725105.html

至此,插入功能就结束了,其他删改查的功能我不会重复写,但这里列出一些需要注意的细节

查删改中的细节

既然新增不能插入重复的数据,那么修改也需要先进行一次判断吗?不用,可以直接将下面列表进行固定,锁住。
input文本框渲染值和下拉框如何渲染值
代码语言:javascript复制
postAjax(requestUrl   "/perCenter/getModuleByParCode", param, function (data) {
                $.each(data, function (index, value) {
                    $("#moduleCode").append('<option value='   value.code   '>'   value.name   '</option>');
                });
                layui.form.render("select");
                postAjax(requestUrl   "/perCenterApi/selectGrzxXm", param, function (data) {
                    console.log(data)
                    // $('#moduleCode').val(data.data.moduleName);//模块名称
                    //下拉框设置值得这么写
                    $('#moduleCode').find("option:selected").text(data.data.moduleName)
                    $('#dispSn').val(data.data.dispSn);//排序
                    $('#remark').val(data.data.bz);//备注
                    form.render('select');
                });
                $('input,textarea,select').attr('disabled', 'disabled');
            });

这里是查看ajax请求返回的数据并渲染到前端的代码,至于前面的下拉框锁住就是最后一句代码: $(‘input,textarea,select’).attr(‘disabled’, ‘disabled’);不过这里是全部锁住了,因为是查看嘛。

最顶层的查询和重置

这个模块涉及的知识点是;分页和模糊查询

代码语言:javascript复制
        //查询
        $("#Fsearch").click(function () {
            getList(lbParmas);
        });
        //重置
        $("#Freset").click(function () {
            $("#MoudleName").val("");
            getList();
        });

实现的代码简单,关键还是之前写了刷新页面列表的函数getList,这个函数的查询可不是返回一个对象或者对象列表,而是返回一个页面对象。对的也就是分页功能。这里用到了layui的分页助手。下面看下这个函数吧

前端代码
代码语言:javascript复制
 postAjax(requestUrl   "/perCenterApi/selectGrzxXmMKList", lbParmas, function (data) {
                console.log(data)
                page.render({
                    elem: 'layuipage',
                    count: data.count,
                    contentType: "application/json;charset=UTF-8",
                    curr: lbParmas.pageNo,
                    limit: lbParmas.pageSize,
                    first: "首页",
                    last: "尾页",
                    layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'],
                    jump: function (obj, first) {
                        if (!first) {
                            lbParmas.pageNo = obj.curr;
                            lbParmas.pageSize = obj.limit;
                            lbParmas.scenceIds=$("#scenceIds").val();
                            getAjax(requestUrl   "/perCenterApi/selectGrzxXmMKList", lbParmas,function (data) {
                                perCenTable.reload({
                                    data: data.list
                                });
                                $('#perCenTable').parent().find('.layui-table-header').find('.layui-form-checkbox').hide();
                            })
                        }
                    }
                });
controller层代码
代码语言:javascript复制
   @RequestMapping(value = "/selectGrzxXmMKList",name = "查询个人拥有的模块信息")
    @ResponseBody
    public Map<String,Object> selectGrzxXmMK(HttpServletRequest request, HttpServletResponse response, Integer pageNo,
                                             Integer pageSize,String moudleName,String id){
        UserInfo userInfo= WebUtil.getCurrUserInfo(request, response);
        Map map = new HashMap<String,Object>();
 
        List<GarzaXmas> garzaXmasList = personalCenterService.selectGrzxXmMK(id,userInfo,moudleName,pageNo,pageSize);
        int count = personalCenterService.selectGrzxXmMKCount(userInfo);
        map.put("list",garzaXmasList);
        map.put("count",count);
        return map;
    }

从controller可以看到,查询数据库需要的参数是pageSize,pageNo。如果没有模糊查询的话是不需要moudleName这个参数的,id参数多余的别用看。事实上也正是如此,分页查询使用limit正是需要pageSize和pageNo,模块名称则是用来where,看下面sql:

代码语言:javascript复制
sb.append("select id,MODULE_NAME moduleName,BZ bz,DISP_SN dispSnn"  
                " from t_grzx_mk where RY_ID = ? ");
        if (Utils.availableStr(moduleName)){
            sb.append(" and MODULE_NAME like '%"   moduleName   "%'");
        }
        sb.append("LIMIT "   (pageNo-1 ) * pageSize   ","   pageSize);

总结

到此,这个小页面的增删改查笔记就写完了。如果文章有不对的地方,欢迎大佬们评论留言指出!

废江博客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 转载请注明原文链接:实习笔记:java页面的增删改查,分页,模糊查询

0 人点赞