Skip to content

Commit ab1d5e5

Browse files
Aunixtoyouabel533
authored andcommitted
feat: 支持更新指定字段
1 parent 7c231c9 commit ab1d5e5

File tree

6 files changed

+95
-0
lines changed

6 files changed

+95
-0
lines changed

mapper/src/main/java/io/mybatis/mapper/BaseMapper.java

+11
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ default ExampleWrapper<T, I> wrapper() {
6262
@UpdateProvider(type = FnProvider.class, method = "updateByPrimaryKeySelectiveWithForceFields")
6363
<S extends T> int updateByPrimaryKeySelectiveWithForceFields(@Param("entity") S entity, @Param("fns") Fn.Fns<T> forceUpdateFields);
6464

65+
/**
66+
* 根据主键更新指定的字段
67+
*
68+
* @param entity 实体类型
69+
* @param updateFields 指定更新的字段
70+
* @return 1成功,0失败
71+
*/
72+
@Lang(Caching.class)
73+
@UpdateProvider(type = FnProvider.class, method = "updateForFieldListByPrimaryKey")
74+
<S extends T> int updateForFieldListByPrimaryKey(@Param("entity") S entity, @Param("fns") Fn.Fns<T> updateFields);
75+
6576
/**
6677
* 根据指定字段集合查询:field in (fieldValueList)
6778
* <p>

mapper/src/main/java/io/mybatis/mapper/fn/FnProvider.java

+21
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ public String getSql(EntityTable entity) {
5252
});
5353
}
5454

55+
/**
56+
* 根据主键更新指定的字段
57+
*
58+
* @param providerContext 上下文
59+
* @return cacheKey
60+
*/
61+
public static String updateForFieldListByPrimaryKey(ProviderContext providerContext) {
62+
return SqlScript.caching(providerContext, new SqlScript() {
63+
@Override
64+
public String getSql(EntityTable entity) {
65+
return "UPDATE " + entity.tableName()
66+
+ set(() ->
67+
entity.updateColumns().stream().map(column ->
68+
choose(() ->
69+
whenTest("fns != null and fns.fieldNames().contains('" + column.property() + "')", () -> column.columnEqualsProperty("entity.") + ","))
70+
).collect(Collectors.joining(LF)))
71+
+ where(() -> entity.idColumns().stream().map(column -> column.columnEqualsProperty("entity.")).collect(Collectors.joining(" AND ")));
72+
}
73+
});
74+
}
75+
5576
/**
5677
* 根据实体字段条件查询唯一的实体,根据实体字段条件批量查询,查询结果的数量由方法定义
5778
*

mapper/src/test/java/io/mybatis/mapper/fn/UserFnMapperTest.java

+25
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,31 @@ public void testUpdateByPrimaryKeySelectiveWithForceFields() {
4646
}
4747
}
4848

49+
@Test
50+
public void testUpdateForFieldListByPrimaryKey() {
51+
SqlSession sqlSession = getSqlSession();
52+
try {
53+
// 元数据(1, '张无忌', '男', 1)
54+
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
55+
User user = mapper.selectByPrimaryKey(1L).get();
56+
user.setUserName("test");
57+
user.setSex("女");
58+
user.setStatus(false);
59+
int count = mapper.updateForFieldListByPrimaryKey(user, Fn.of(User::getUserName, User::getStatus));
60+
Assert.assertEquals(1, count);
61+
user = mapper.selectByPrimaryKey(1L).get();
62+
// 断言 sex 不会被更新
63+
Assert.assertEquals("男", user.getSex());
64+
// 断言userName被成功更新
65+
Assert.assertEquals("test", user.getUserName());
66+
// 短信 status不会被更新,user status 为不允许更新字段, 所以这里不会更新
67+
Assert.assertEquals(user.getStatus(), true);
68+
} finally {
69+
//不要忘记关闭sqlSession
70+
sqlSession.close();
71+
}
72+
}
73+
4974
@Test
5075
public void testSelectColumnsOne() {
5176
SqlSession sqlSession = getSqlSession();

service/src/main/java/io/mybatis/service/AbstractService.java

+7
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ public T update(T entity) {
8484
return entity;
8585
}
8686

87+
@Override
88+
public T update(T entity, Fn<T, Object>... updateFields) {
89+
Assert.isTrue(baseMapper.updateForFieldListByPrimaryKey(
90+
entity, Fn.of(updateFields)) == 1, UPDATE_FAILURE);
91+
return entity;
92+
}
93+
8794
@Override
8895
public T updateSelective(T entity) {
8996
Assert.isTrue(baseMapper.updateByPrimaryKeySelective(entity) == 1, UPDATE_FAILURE);

service/src/main/java/io/mybatis/service/EntityService.java

+9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public interface EntityService<T, I extends Serializable> {
5555
*/
5656
T update(T entity);
5757

58+
/**
59+
* 更新(指定字段)
60+
*
61+
* @param entity 实体类
62+
* @param updateFields 需要更新的字段
63+
* @return 返回更新成功后的实体,远程服务调用时,由于序列化和反序列化,入参和返回值不是同一个对象
64+
*/
65+
T update(T entity, Fn<T, Object>... updateFields);
66+
5867
/**
5968
* 更新(非空字段)
6069
*

service/src/test/java/io/mybatis/service/ServiceTest.java

+22
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,28 @@ public void testUserService() {
182182
Assert.assertTrue(userService.findOne(user) != null);
183183
}
184184

185+
@Test
186+
public void testUpdate() {
187+
// 元数据 (1, 'admin', 1)
188+
UserService userService = context.getBean(UserService.class);
189+
User user = userService.findById(1);
190+
Assert.assertNotNull(user);
191+
192+
user.setName("administrator");
193+
user.setRoleId(11);
194+
userService.update(user, User::getName);
195+
user = userService.findById(1);
196+
Assert.assertEquals("administrator", user.getName());
197+
Assert.assertEquals(1, (int) user.getRoleId());
198+
199+
user.setName("admin");
200+
user.setRoleId(11);
201+
userService.update(user, User::getRoleId);
202+
user = userService.findById(1);
203+
Assert.assertEquals("administrator", user.getName());
204+
Assert.assertEquals(11, (int) user.getRoleId());
205+
}
206+
185207
@Test
186208
public void testIssues50() {
187209
UserService userService = context.getBean(UserService.class);

0 commit comments

Comments
 (0)