JavaWeb开发:历史变更记录(基于SSM框架)

一、效果展示

后端为SSM框架,前端采用Layui,相关简介可参考之前的博客:JavaWeb后端开发框架SSM+前端框架Layui简介

1、初始数据表格

在这里插入图片描述

2、修改内容:

将“现在地址”一栏中的“南京”修改为“北京”:

在这里插入图片描述
在这里插入图片描述

3、修改后:

在这里插入图片描述
历史变更记录的表格中包含的字段为:(护理机构)名称、修改时间、变更字段名称、变更前内容、变更后内容,以及一些其它自己设定的内容

在这里插入图片描述

二、实现

本次博客仅专注于后端开发,前端内容使用框架(如:数据表格的显示、两个Tab的显示与切换等等)。

1、表单提交

在上一节中,采用的“修改信息”页面是使用Layui表单进行设计的,当触发“submit”事件后,使用AJAX传递方式将表单内容传递至后端。

layui表单的设计及提交可参考博客: 用layui实现表单提交(包含图片)

<script>
        layui.use('form', function(){
            var form = layui.form;
            //submit是button的type;handin是自定义的按键id
            form.on('submit(handin)', function(data){	
                console.log("开始提交");
                console.log(data.field);	//前端调试,查看传递的数据
                $.ajax({
                    url:'/department/updateDepartment',	//连接到后端的controller层
                    method:'POST',	//传递方式
                    data:data.field,	//传递的数据
                    dataType:'JSON',	//数据采用Json类型
                    //事件触发成功后返回res值,并进入以下自定义函数
                    success:function(res){		
                        console.log("res.msg:"+res.msg);
                        if(res.msg=="ok"){		//controller层的返回值
                            console.log("成功提交"+data.field);
                            //提交成功后刷新页面
                            layer.msg("提交成功",{icon: 1, time: 1500},function()	{location.reload();}); 
                        }else{
                            console.log("请确保“结算代码”输入正确"+data.field);
                            layer.msg("请确保“结算代码”输入正确",{ icon: 5,anim: 6,offset: "auto"});
                        }
                    },
                    error:function (data) {
                        console.log("提交失败",data);
                    }
                });
                return false;
            })
        })

此时页面的控制台资源中可以查看到前端传递的数据(即data.field),如下图:

在这里插入图片描述

2、Controller层

Controller层接收数据

@RequestMapping(value = "/updateDepartment", method = RequestMethod.POST,produces={"application/json;charset=UTF-8"})
    @ResponseBody
    public String updateDepartment(Department department, HttpSession session) {
    //Department为在Model中定义的类,department变量接收前端传来的数据
        try {
            System.out.println("开始更新");
            //进入service层
            String abc=departmentService.updateDepartment(department, session);	
            System.out.println("controller层返回:"+abc);
            if(abc=="ok"){
                return "{\"msg\":\"ok\"}";
            }else{
                return "{\"msg\":\"error\"}";
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("更新异常!", e);
            return "操作异常,请您稍后再试";
        }
    }

3、Service层

   
    public interface DepartmentService {
    // 申明函数
    String updateDepartment(Department department, HttpSession session);
	}

4、ServiceImplement层

在该层中定义updateDepartment的具体函数方法。

历史变更记录功能需要解决的主要问题在于:

  1. 记录修改前的表单内容
  2. 记录修改后的表单内容
  3. 区别出整个表单中被更改了的内容及其字段名称,也就是哪些内容被改变了
  4. 记录下更改的时间
  5. 存入历史变更记录表中,并更新旧表内容
(1)记录下修改前的表单内容

在新的表单提交后,后端只是接收了数据,还没有更改数据,因此原来表格中的内容即原始信息。
那么,要怎么找到这一条修改前的原始信息呢?通常来说,在设计数据库表时,会默认将 id 作为整个表格中的主键,即相当于是一个唯一标识码,因此可通过前端传来的数据的 id 来找到原始数据的内容。在找到原始信息后,将数据存入HashMap中。

if (department.getId() != null) {
//     根据ID找到修改前的数据
      System.out.println("service层:department的ID:"+department.getId()); 
      Department departmentInfobyID=departmentDao.findDepartmentInfobyID(department.getId());
      System.out.println("service层:存在此机构");

//    将旧数据存入HashMap
	  Map<String,Object> oldDepartment = new HashMap<String,Object>();
	  //此处仅列举几个变量为例
      oldDepartment.put("department_name", departmentInfobyID.getDepartment_name());
      oldDepartment.put("department_phone_number", departmentInfobyID.getDepartment_phone_number());
      oldDepartment.put("department_address", departmentInfobyID.getDepartment_address());
      oldDepartment.put("department_settlement_scope", departmentInfobyID.getDepartment_settlement_code());
      oldDepartment.put("department_first_settle_date", departmentInfobyID.getDepartment_first_settle_date());
      
      System.out.println("service层:旧的数据:oldDepartment:"+oldDepartment);
}

此处涉及到findDepartmentInfobyID函数,需先在Dao层中定义:

    /** 查询/根据id
     * @param id
     */
    Department findDepartmentInfobyID(@Param("id") Integer id);

并在mapper层定义相同函数名称的方法:

    <!--根据ID查询信息-->
    <select id="findDepartmentInfobyID" resultType="Model.Department">
        select * from db_chx_department
        where id = #{id}
    </select>
(2)记录修改后的数据

修改后的数据即刚传输进来的数据,同样将其存入HashMap中。

//           将新数据存入HashMap
	Map<String,Object> newDepartment = new HashMap<String,Object>();
	newDepartment.put("department_name", department.getDepartment_name());
	newDepartment.put("department_phone_number", department.getDepartment_phone_number());
	newDepartment.put("department_address", department.getDepartment_address());
	newDepartment.put("department_settlement_scope", department.getDepartment_settlement_code());
	newDepartment.put("department_first_settle_date", department.getDepartment_first_settle_date());
	System.out.println("service层:新的数据:newDepartment::"+newDepartment);

(3)记录下修改时间
//     记录修改时间
       Date date = new Date();
       Timestamp timestamp = new Timestamp(date.getTime());
       departmentInfobyID.setDepartment_change_time(timestamp);
       System.out.println("修改时间:"+departmentInfobyID.getDepartment_change_time());
(4)比较新旧数据

  遍历oldDepartment中的每一个键值对,比较新旧表在相同键时的值是否一致,若不一致,则建立新表以存储历史变更信息,若一致则不用存储。

//	遍历 oldDepartment 中的每一个键值对
	for(Map.Entry<String,Object>entry:oldDepartment.entrySet()){ 
	
//      获取当前遍历到的键
        String keyContent=entry.getKey();
        System.out.println("获取的key值:"+keyContent);
        
//      获取当前键的 value 值(新+旧)
		// 判断当前键的值是否为空,将值存入oldValue
        Object oldValue = entry.getValue()==null?"":entry.getValue(); 
        // 根据当前键,查找到新表对应键的数据:newDepartment.get(entry.getKey()),
        // 并判断其值是否为空,存入newValue
        Object newValue = newDepartment.get(entry.getKey())==null?"":newDepartment.get(entry.getKey()); //
        System.out.println("比较循环前的数据(旧):"+oldValue);
        System.out.println("比较循环前的数据(新):"+newValue);
        
//      比较:如果二者value不同
        if(!oldValue.equals(newValue)){
            System.out.println("不同");
            // 建立新表,用于存储变更信息
            Map<String,Object> insertInfo = new HashMap<String,Object>();
            
// 		    根据当前键,设置对应的中文名称,用于后期显示“变更字段名称“
            switch (keyContent){
                case "department_name": insertInfo.put("department_changed_title","机构名称");break;
                case "department_phone_number": insertInfo.put("department_changed_title","联系电话");break;
                case "department_address":insertInfo.put("department_changed_title","机构地址");break;
                case "department_settlement_scope":insertInfo.put("department_changed_title","结算范围");break;
                case "department_first_settle_date":insertInfo.put("department_changed_title","首次可结算日期");break;
            }
            
//		    在新建表中添加需要记录下的键值对,如:变更字段名称、变更前后信息、变更时间等
            insertInfo.put("department_name", department.getDepartment_name());
            insertInfo.put("department_settlement_code", department.getDepartment_settlement_code());
            insertInfo.put("department_change_time", department.getDepartment_change_time());
            insertInfo.put("department_new_content", newValue);
            insertInfo.put("department_history_content", oldValue);
            System.out.println("变更后的表:"+insertInfo);
            
//          以哈希表形式传入更改后的数据
			System.out.println("进入dao层:InsertHistoryChange");
            this.departmentDao.InsertHistoryChange(insertInfo);
        }else{
//          若value相同,则不传
            System.out.println("相同");
        }
//          更新原表中的数据
            this.departmentDao.updateById(department);
            System.out.println("update成功(Impl)");
    }
            return "ok"; //愚蠢的返回方式

控制台输出变更后的表信息,由于只更改了一个内容,故而只输出了一条信息;若变更多个内容,则会显示多条信息。

在这里插入图片描述
在Dao层定义函数,并在mapper层定义方法:
1)将变更信息插入历史变更记录表中

    <!--历史变更-->
    <insert id="InsertHistoryChange" useGeneratedKeys="true" parameterType="java.util.HashMap">
        insert into db_chx_department_history_change
        (department_name,department_settlement_code,department_change_time,
        department_changed_title,department_new_content,department_history_content)
        values
        (#{department_name},#{department_settlement_code},#{department_change_time},
        #{department_changed_title},#{department_new_content},#{department_history_content})
    </insert>

2)更新旧表

    <update id="updateById" parameterType="Model.Department">
        update db_chx_department
        <set>
            <if test="department_name != null"> department_name = #{department_name},</if>
            <if test="department_phone_number != null">department_phone_number = #{department_phone_number}, </if>
            <if test="department_address != null">department_address = #{department_address},</if>
            <if test="department_settlement_scope != null">department_settlement_scope = #{department_settlement_scope},</if>
            <if test="department_settlement_code != null"> department_settlement_code = #{department_settlement_code}</if>
        </set>
        where id = #{id}
    </update>


以上即完成了整个历史变更功能。

该代码问题在于:在记录修改前后的信息、以及根据键来设置中文名称时,需要逐条罗列数据库表的字段,使代码较为冗长…等一个解决的好方法…

阿巴阿巴阿巴…小萌新报道…如有错误,欢迎指正…在这里插入图片描述


  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值