2017-9-20 1-N维护

这次维护1-N的两张表,学习总结如下。

采用的框架是Spring4+SpringMVC+Hibernate/MyBatis,辅助gradle构建工具和dubbo中间件和本地maven仓库,项目中还有redis、webService等技术,这里没用到就先不提。过程涉及表示层、业务逻辑层和数据库层。这次我用了hibernate和MyBatis,所以也算增加了一层持久层。

可以考虑加入国际化支持;

一. 关于增删改查

1. <新增>

表示层

  • 数据的完整性和合法性的校验: 根据数据库设计要求,对要求非空的字段在表示层进行值的控制;
//验证表单
$.fn.formValidate = function () {
    var ret = true;
    this.each(function (i, formElem) {
        ret = $(":input", $(formElem)).validate();
        return ret;
    });
    return ret;
};
  • 校验表单值的格式正确与否,比如日期、下拉框、单选框和多选框,同时对下拉这种需要从数据字典读取的值,查看tag是否正确引用、显示和传值;
  • 对有特定业务逻辑的字段,采用js进行控制。比如起始日期不大于结束日期等;
  • form表单中,考虑到区别新增和更新的需要,应在表单塞入对象的主键值,以JSTL取值为例,如下:
<form:hidden path="XXX" value="${XXXX}"/>
  • 1-N的insert的不同:
    在1-N的新增中,1的表的非空字段是不允许为空的,N的表可以没有记录,可以有记录;
    对于N的表的新增,采用动态添加的方法,每点击一次 + 号,采用jsrender动态添加一组input值,这组新增的input可以删去,但不会传到业务逻辑层;
    刚开始用var size = $("#table tbody tr").length;记录要渲染的行数index,后来测试发现问题:一组input再删去再添加一组,tr的index值会重复。于是设置了一个JS的全局变量记录点击 + 号的次数,即产生的input框的组数。

业务逻辑层
采用hibernate存储数据,先存储主表返回主表PK,再遍历子表,把id值塞入子表对象中存储。这里注意前台字段大小写的转化是否正确(class:text-uppercase)。

2. <查询>
表示层&业务逻辑层

  • 查询参数的合法性和完整性:
    首先,根据业务逻辑,控制查询参数是否非空,每个查询参数传输是否正确;
    其次,在查询操作完成后,查询框的查询参数是否能回填。在这一点上犯过好几次错误,都是因为在控制层返回ModelAndView对象时忘记塞入传过来的queryDTO对象,谨记!!

  • 对于主次表的查询,这里要注意的有两点:
    首先是SQL语句的实现;
    其次是前端的分页插件和实现效果。

先谈一下SQL语句。因为对hibernate关联查询的持久化语句不是很熟悉,平时只做了些简单的insert、delete、update及分页查询的操作,所以这次的主次表的查询,使用的是比较熟练的MyBatis进行查询(直接写我需要的SQL当然方便啦~)。

把关联查询的条件放到子表的查询条件中,在子表条件存在时进行关联查询,否则会漏掉主表有记录而子表无记录的情况;
把结果进行distinct,筛选掉重复数据;
注意查询字段里,有下划线的字段要另起别名,这里要研究下MyBatis。
子表的查询里,把关联查询条件是直接放在where语句下面,也不需要用distinct筛选了。

其次是前端分页插件,先是只用了一个插件,在点击子表查询按钮时,返回一个以html解析的jsp页面,重写了插件方法,能实现分页,但两个分页互相影响。原本打算采用js控制,但意识到表示层删除js代码,仍然会加载js方法。作罢。

新增了一个bootstrap-table方法,关于这个插件的api和使用方法网上很多,就不详述了。jsp页面数据传到控制器时,框架里尚未配置转化为json的方法,于是用了下@ResponseBody和ResultDTO,封装在对象里,前台自己解析。

responseHandler: res,
 // 解析返回数据
        function res(res) {
            if (res) {
                return {
                    "rows" : res.result,
                    "total" : res.detail
                };
            } else {
                return {
                    "rows" : [],
                    "total" : 0
                };
            }
        }

同时,这里我用的是POST方式传数据,contentType: "application/x-www-form-urlencoded",而是要设置的。不然会导致后台无法接收到分页的startIndet等分页参数(查询参数可以正常传递)。

3. <更新>

  • 查询对象的展示、动态编辑与业务逻辑层的存储
    根据主表id取到主表数据,再遍历塞入子表数据封装进对象中,在前台进行展示;
    主表支持修改,子表也支持修改删除。这里要注意已存在的数据与又新增的数据的保存,
    主表取出数据,校验非空后直接update;子表是先要判断是否是已删除的操作行,是否是已存在的;

4. <删除>
包括主表数据的直接删除和子表数据的删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值