Using MyBatis-Plus saveOrUpdate with UpdateWrapper and QueryWrapper
This article explains how MyBatis-Plus's saveOrUpdate method works, why a primary‑key annotation is required, and how to control insert or update operations using UpdateWrapper or QueryWrapper, including code examples, common pitfalls, and practical tips for handling auto‑increment IDs.
When inserting data with MyBatis‑Plus, the saveOrUpdate method can automatically decide whether to insert or update based on the primary key, but it throws an exception if the entity lacks a @TableId annotation.
The entity class must declare the primary key, for example:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Subject {
@TableId(value = "subject_Code", type = IdType.AUTO)
private long subjectCode;
private String subjectNameCn;
private String subjectNameEn;
private String subjectHref;
private long subjectParentCode;
private long levelCode;
private int isDelete;
private long operateTimestamp;
}By default, saveOrUpdate checks the primary key; if it exists, it updates, otherwise it inserts. To perform the operation based on a non‑primary field, you can supply an UpdateWrapper (or QueryWrapper ) as a second argument.
UpdateWrapper<Subject> wrapper = new UpdateWrapper<Subject>()
.eq("subject_Name_Cn", subjectNameCn);
subjectService.saveOrUpdate(subject, wrapper);If the wrapper updates at least one row, the method returns true; otherwise it falls back to the default primary‑key‑based saveOrUpdate .
The default implementation is:
default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
return this.update(entity, updateWrapper) || this.saveOrUpdate(entity);
}When using auto‑increment IDs, forgetting the UpdateWrapper will cause every call to insert a new row because the primary key is not set, leading to duplicate data.
Tips: UpdateWrapper uses set to specify fields to modify, while QueryWrapper is for selecting rows. Only non‑null fields of the entity are updated, so missing values are left unchanged.
Be cautious when mixing wrappers with saveOrUpdate ; the wrapper’s condition determines whether an update occurs before the fallback insert, and improper use may result in unexpected duplicate inserts.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.