网页制作与网站建设策划书案例重庆门户网站推广方案
一、getById 与 new
我在修改数据时,产生疑问,注释掉是我一开始写得,new对象是答案提供的,我就好奇两者之间区别。

1. 使用 setmealMapper.getById 获取现有对象
 
Setmeal setmeal = setmealMapper.getById(setmealDTO.getId()); BeanUtils.copyProperties(setmealDTO, setmeal); // 仅覆盖 setmealDTO 中存在的字段 setmealMapper.update(setmeal);
优点:
-  
保留原有数据:从数据库中加载的
Setmeal对象包含所有字段的当前值,未被setmealDTO覆盖的字段会保持不变。 -  
适合部分更新:如果只需要更新部分字段(如名称、价格等),而不想影响其他字段(如创建时间、状态等),这种方式更合适。
 -  
数据一致性:确保数据库中的其他字段不会被意外覆盖或丢失。
 
缺点:
-  
额外数据库查询:需要先查询数据库,增加一次 IO 操作,可能影响性能。
 -  
代码复杂度:如果字段较多,可能需要手动处理某些字段的更新逻辑。
 
适用场景:
-  
需要保留部分字段(如创建时间、状态等)不被修改。
 -  
业务逻辑要求基于现有数据进行更新。
 
2. 使用 new Setmeal() 创建新对象
 
Setmeal setmeal = new Setmeal(); BeanUtils.copyProperties(setmealDTO, setmeal); // 完全使用 setmealDTO 的数据 setmealMapper.update(setmeal);
优点:
-  
简单直接:不需要额外的数据库查询,代码更简洁。
 -  
性能更高:减少一次数据库查询,适合对性能要求较高的场景。
 -  
适合完全覆盖:如果业务逻辑要求完全覆盖数据库中的记录,这种方式更合适。
 
缺点:
-  
丢失原有数据:如果
setmealDTO中没有包含某些字段(如创建时间、状态等),这些字段会被覆盖为默认值(如null或0),可能导致数据丢失。 -  
不适合部分更新:无法保留未被
setmealDTO覆盖的字段。 
适用场景:
-  
需要完全覆盖数据库中的记录。
 -  
setmealDTO包含了所有需要更新的字段。 -  
对性能要求较高,且不需要保留原有数据。
 
总结与建议
-  
如果需要保留部分字段(如创建时间、状态等),建议使用
setmealMapper.getById,确保数据一致性。 -  
如果完全覆盖数据且
setmealDTO包含所有字段,建议使用new Setmeal(),代码更简洁且性能更高。 
最佳实践
如果不确定哪种方式更合适,可以采用以下策略:
-  
默认使用
setmealMapper.getById,确保数据安全性和一致性。 -  
在性能敏感的场景下,如果确认
setmealDTO包含所有字段且不需要保留原有数据,可以使用new Setmeal()。 
if (needPartialUpdate) {Setmeal setmeal = setmealMapper.getById(setmealDTO.getId());BeanUtils.copyProperties(setmealDTO, setmeal); // 部分更新setmealMapper.update(setmeal);
} else {Setmeal setmeal = new Setmeal();BeanUtils.copyProperties(setmealDTO, setmeal); // 完全覆盖setmealMapper.update(setmeal);
} 
根据业务需求灵活选择,既能保证数据安全,又能优化性能。
看来我一开始写得也不错,嘻嘻~。
二、这段代码,为什么copy之后,还要update呢?
Setmeal setmeal = setmealMapper.getById(setmealDTO.getId()); // 从数据库获取对象 BeanUtils.copyProperties(setmealDTO, setmeal); // 将 DTO 的数据复制到实体对象 setmealMapper.update(setmeal); // 更新数据库
1. setmealMapper.getById
 
-  
从数据库中加载一个
Setmeal对象。 -  
这个对象是持久化对象,即它与数据库中的一条记录关联。
 
2. BeanUtils.copyProperties
 
-  
将
setmealDTO中的数据复制到setmeal对象中。 -  
这一步只是修改了内存中的
setmeal对象,并没有自动同步到数据库。 
3. setmealMapper.update
 
-  
将修改后的
setmeal对象同步到数据库。 -  
这一步才是真正将内存中的修改持久化到数据库中。
 
为什么需要 update?
 
-  
内存与数据库是分离的:
-  
Java 中的对象是内存中的数据结构,修改对象并不会自动同步到数据库。
 -  
数据库是一个独立的存储系统,需要通过 SQL 语句(如
UPDATE)来修改数据。 
 -  
 -  
BeanUtils.copyProperties只是内存操作:-  
它只是将
setmealDTO的属性值复制到setmeal对象中,修改的是内存中的对象状态。 -  
数据库并不知道这些修改,因此需要显式调用
update方法将修改同步到数据库。 
 -  
 -  
ORM 框架的工作方式:
-  
如果你使用的是 MyBatis 或 JPA 等 ORM 框架,它们并不会自动跟踪对象的变化。
 -  
你需要显式调用
update方法,告诉框架将对象的状态同步到数据库。 
 -  
 
类比理解
可以将这个过程类比为编辑文档:
-  
从文件柜中取出文档(
getById):你从数据库加载了一个对象。 -  
在文档上修改内容(
copyProperties):你在内存中修改了对象。 -  
将修改后的文档放回文件柜(
update):你需要将修改后的对象保存回数据库。 
如果你不执行第三步,文件柜中的文档(数据库中的数据)就不会被更新。
如果你不想手动调用 update
 
如果你希望修改对象后自动同步到数据库,可以考虑以下方式:
-  
使用 JPA(Hibernate):
-  
JPA 提供了自动脏检查机制,修改对象后,在事务提交时会自动同步到数据库。
 -  
示例:
Setmeal setmeal = setmealRepository.findById(setmealDTO.getId()).orElseThrow(); BeanUtils.copyProperties(setmealDTO, setmeal); // 不需要显式调用 update,事务提交时会自动同步
 
 -  
 -  
使用 MyBatis 的动态更新:
-  
可以配置 MyBatis 只更新变化的字段,而不是全部字段。
 
 -  
 
总结
-  
BeanUtils.copyProperties只是修改了内存中的对象,数据库并不知道这些变化。 -  
必须显式调用
setmealMapper.update将修改同步到数据库。 -  
如果你希望自动同步,可以考虑使用 JPA 或其他支持自动脏检查的框架。
 
三、补充
在写day04时发现少写了个通过套餐id查询菜品的接口,在此记录一下。
