前言
针对web界面开发,今天对于一些细节做了一点总结与回想,好久不做web开发了,今天竟然都忘记了以前的界面组件、后端orm映射框架的一些基础知识了,今天主要总结的内容是,当界面提交一个表单后,vue是如何监听到表单的变化的,如果对于传统的orm框架,如mybatis及hibernate 它们又是怎样实现的。
orm框架的响应
当我们在使用某些后端框架进行表单提交操作时,我们有时需要知道表单的数据是否发生了变更,以避免重复提交或其他不必要的操作。下面将介绍如何通过Hibernate框架来判断表单数据变更,并了解后端框架的响应机制。
首先,让我们来看一下客户端的表单提交过程。当用户填写表单并点击提交按钮时,表单数据将通过HTTP协议发送到服务器。在服务器端,后端框架将获得表单数据,并且将其映射到对应的实体对象中。这里我们以Hibernate框架为例。
当表单数据映射到实体对象后,我们就需要判断表单数据是否发生了变更。Hibernate框架提供了一个saveOrUpdate方法来判断实体对象的状态,并将其自动保存到数据库中。如果表单数据发生了变更,Hibernate会在数据库中自动更新实体对象的属性值。如果表单数据没有发生变更,则不会进行任何数据库操作。这样,我们可以避免重复提交和其他不必要的操作,提高系统的性能和效率。
在程序中,我们可以多次调用saveOrUpdate方法,但如果表单数据没有发生变更,Hibernate会忽略多余的操作。在第一次调用时,Hibernate将实体对象保存到数据库中,并将其转化为持久化状态;在后继的调用中,Hibernate会检测到该对象已经处于持久化状态,避免重复更新数据库。
总之,了解如何判断表单数据是否发生变更,以及后端框架响应的机制,对于我们编写高效、可靠的程序非常有帮助。在使用Hibernate框架时,我们可以通过调用saveOrUpdate方法来进行数据持久化操作,并且避免重复提交和其他不必要的操作。
关于一些组件
接着我又调研了一下常用的框架组件,比如jeecgboot框架中的多行编辑组件,这种情况当列表新增了一些记录后,每一次保存又是如何知道哪些记录修改过,哪些没有修改过,保存时是如何做到只更新变更的记录,而不去处理未做修改的记录呢?
jeecg JgEditable Table行编辑表格 的特性,以及保存表格数据时,如何区分哪些记录变更了,哪些没有变更,如何只保存变更的数据,这种情况也可结合后台springboot框架来说明
JgEditable Table行编辑表格是 Jeecg 框架提供的一种编辑表格方式,它可以让用户通过行内编辑的方式来进行数据录入,十分方便。与普通的表格不同的是,JgEditable Table 表格支持对单行数据进行编辑,并在保存时只保存有变更的数据,从而提高了数据的录入效率,减少了不必要的数据提交操作。
JgEditable Table 表格提供了以下特性:
- 可编辑单元格
通过设置表格的编辑模式,可以将单元格变为可编辑状态,让用户可以直接在单元格内进行数据的编辑。
- 行新增和删除
在表格末尾或自定义位置,提供了添加或删除一行的功能,并同时提供实时统计列信息的功能。
- 行内编辑器
对于一些特殊类型的字段,可以自定义使用哪种类型的编辑器进行编辑。例如,对于日期类型的字段,可以使用日期选择器作为编辑器。
当需要保存表格数据时,我们通常需要通过比较前后的数据来确定哪些数据发生了变更。Jeecg 框架提供了一种比较方便的方式来实现这一目标。我们可以在保存时,在后台利用 ORM 框架对前台传过来的数据进行保存。在保存之前,我们可以通过比较更新前后的数据,判断哪些数据发生了变化,并只保存发生变化的数据,提高了数据的录入效率,减少了不必要的数据提交操作。
以 Spring Boot 框架为例,我们可以使用 Mybatis-plus ORM 框架来实现这一功能。Mybatis-plus 提供了如下方法来进行新增、修改和删除操作:
-
insert(entity):插入一条数据。
-
updateById(entity):根据 ID 更新一条数据。
-
deleteById(id):根据 ID 删除一条数据。
同时,Mybatis-plus 还提供了 Wrapper 来进行复杂查询和更新操作。通过继承 MyBaseMapper 接口,我们可以为数据表设置自定义的 Mapper,然后在 Service 层进行调用。
在保存 JgEditable Table 表格数据时,我们可以通过将前台传过来的 JSON 数据转化为实体类,然后调用 Mybatis-plus 提供的方法来进行数据的保存。在进行保存操作前,我们需要通过比较更新前后的数据,判断哪些数据发生了变化,并只保存发生变化的数据。
示例代码如下(假设表格数据对应的实体类为 DemoEntity):
@Service
public class DemoService {
@Autowired
private DemoMapper demoMapper;
public void save(List<DemoEntity> dataList) {
for (DemoEntity data : dataList) {
DemoEntity oldData = demoMapper.selectById(data.getId()); // 根据 ID 查询更新前的数据
if (oldData == null) {
demoMapper.insert(data); // 插入一条新数据
} else {
if (!oldData.equals(data)) {
demoMapper.updateById(data); // 根据 ID 更新一条已有数据
}
}
}
}
}
在上述代码中,我们通过 demoMapper.selectById()
方法查询了更新前的数据,然后通过比较更新前后的数据,判断哪些数据发生了变化,并调用 demoMapper.insert()
方法或 demoMapper.updateById()
方法来进行保存,从而实现了只保存变更的数据的功能。
vue如何监听表单的变化
紧接着,我又想到了vue 中watch也有这个特性,便又想到了这个问题,下面是其原理:
在 Vue 中可以通过 watch
捕捉表单中的值变化事件。当我们需要监听表单变化时,我们可以利用如下的方法来监听:
watch: {
formData: {
handler(newData, oldData) {
console.log('表单数据已改变')
},
deep: true
}
}
其中,formData
是我们需要监听的表单对象。
Vue 的监听原理是当对象或数组变化时,Vue 会将其转化成 Dep 以及 Watcher。在 Vue 中,每一个响应式对象都会被附加一个信使 (Dep)。当一个属性转变为响应式时,它就会被绑定在当前的 Dep 上,当这个属性发生变化时,它会通知这个 Dep,Dep 触发 watcher 实例对象的 update() 方法。在这个方法中,我们可以实现对变化的监听和后续的处理。
在上例中,我们监听了 formData
这个对象,当这个对象发生变化,Vue 会自动触发依赖于 formData
的 watcher 的 update() 方法,从而执行我们设置的 handler。
需要注意的是,这里的 deep 属性要设置为 true,这是因为对于对象内部的属性修改,Vue 默认不会执行监听操作。例如,在上例中,我们监听的是一个表单对象,表单对象内包含了多个属性,如果仅监听整个对象变化,当表单内部的某个属性改变时,不会触发监听,故需要添加 deep: true。
总结起来便是:
- vue watch如何监听form表单是否变更了,有多种方法,其中一种常用的方法是在data中定义一个form对象,用来存储表单的数据,然后在watch中定义一个form的侦听器,用来监听form对象的变化。可以在侦听器中设置handler函数,当form对象发生变化时,这个函数会被触发,并执行相应的逻辑。可以在handler函数中设置一个标志变量,用来记录表单是否变更过。
- 这种方法的原理是利用了vue的响应式系统,它可以在数据发生变化时通知视图更新。当我们在data中定义一个form对象时,vue会对这个对象进行劫持,并收集依赖。当我们在watch中定义一个form的侦听器时,vue会将这个侦听器添加到form对象的依赖列表中。当我们修改form对象的属性时,vue会触发form对象的setter方法,并通知所有依赖更新。这时,watch中的handler函数就会被调用,并执行相应的逻辑 。
- 这种方法的优点是简单易用,不需要额外的库或插件;缺点是可能会受到对象属性顺序的影响,如果两个对象的内容相同,但是属性顺序不同,那么它们转换后的字符串也会不同。因此,在使用这种方法时,需要保证对象属性顺序的一致性。
其他实现方案
保存表格数据时,如何区分哪些记录变更了,哪些没有变更,如何只保存变更的数据,有多种方法,其中一种常用的方法是在获取表格数据时,使用JSON.stringify方法将每条记录转换为字符串,并保存为一个数组,例如oldDataArray。然后在修改表格数据后,再次使用JSON.stringify方法将每条记录转换为字符串,并保存为另一个数组,例如newDataArray。最后比较这两个数组中的每个元素是否相等,如果不相等,则说明该记录有变更过,如果相等,则说明该记录没有变更过。然后将有变更过的记录筛选出来,并发送给后台springboot框架进行保存。
这种方法的原理是利用了JSON.stringify方法的特性,它可以将一个对象转换为一个标准的JSON字符串,这个字符串包含了对象的所有属性和值,并且按照一定的顺序排列。因此,如果两个对象的内容完全相同,那么它们转换后的字符串也一定相同;反之,如果两个对象的内容有任何不同,那么它们转换后的字符串也一定不同。