跳到主要内容

不完整对象

保存指令的参数是动态对象,如果动态只有部分属性被指定了,那么该对象就是一个不完整对象。

为了说明不完整对象的价值,让我们来看一个实际的例子,将id为8的Bookstore修改为null。

看起来,似乎有两种方法可以实现这个功能:

  • 通过修改语句执行一条UPDATE语句

  • 得到一个Book对象,修改其null属性,并保存它

大部分开发人员都比较偏好第二种方法,因此,本文讨论第二种方式。

JPA示范

在介绍Jimmer保存不完整对象的功能之前,让我们先来看看如何使用JPA实现这个功能

JPA示范
EntityManager entityManager = ...从当前事务上下文中获取JPA会话对象,略...
Book book = entityManager.find(Book.class, 8L);

book.setStore(null); // JPA中实体是可变的,将关联修改为null

// 这里调用merge仅为了清晰,可以不调,因为事务提交时JPA必然修改数据库
entityManager.merge(book);

除了要将store修改为null外,我们并不知道其他属性的现有值。在JPA中,苦于基于简单的POJO的实体是形状固定静态类型,我们不得不查询对象的所有属性,修改store属性 (其他属性保持不变),再次保存这个对象。

哪怕对象有上百个属性,我们也不得不这样做,这形成了非常明显的浪费。

Jimmer示范

sqlClient.update(
Immutables.createBook(draft -> {
draft.setId(8L);
draft.setStore(null);
})
);
  • 明确使用update (或save(book, SaveMode.UPDATE_ONLY)) 明确表示这是一个更新操作,避免UPSERT模式带来的试探性查询,简化讨论。

  • 凭空捏造一个Book对象,只对其id属性和store属性赋值,而其他所有属性都处于未知状态。

    这个不完整对象告诉Jimmer,除store属性外,不修改其他任何属性。

Jimmer将直接生成如下SQL

update BOOK
set
STORE_ID = ? /* <null: long> */
where
ID = ? /* 8 */
信息

所以,请忘记以前那种低效的模式:查询->修改->保存