Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 支持更新指定字段 #118

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions mapper/src/main/java/io/mybatis/mapper/BaseMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ default ExampleWrapper<T, I> wrapper() {
@UpdateProvider(type = FnProvider.class, method = "updateByPrimaryKeySelectiveWithForceFields")
<S extends T> int updateByPrimaryKeySelectiveWithForceFields(@Param("entity") S entity, @Param("fns") Fn.Fns<T> forceUpdateFields);

/**
* 根据主键更新指定的字段
*
* @param entity 实体类型
* @param updateFields 指定更新的字段
* @return 1成功,0失败
*/
@Lang(Caching.class)
@UpdateProvider(type = FnProvider.class, method = "updateForFieldListByPrimaryKey")
<S extends T> int updateForFieldListByPrimaryKey(@Param("entity") S entity, @Param("fns") Fn.Fns<T> updateFields);

/**
* 根据指定字段集合查询:field in (fieldValueList)
* <p>
Expand Down
21 changes: 21 additions & 0 deletions mapper/src/main/java/io/mybatis/mapper/fn/FnProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,27 @@ public String getSql(EntityTable entity) {
});
}

/**
* 根据主键更新指定的字段
*
* @param providerContext 上下文
* @return cacheKey
*/
public static String updateForFieldListByPrimaryKey(ProviderContext providerContext) {
return SqlScript.caching(providerContext, new SqlScript() {
@Override
public String getSql(EntityTable entity) {
return "UPDATE " + entity.tableName()
+ set(() ->
entity.updateColumns().stream().map(column ->
choose(() ->
whenTest("fns != null and fns.fieldNames().contains('" + column.property() + "')", () -> column.columnEqualsProperty("entity.") + ","))
).collect(Collectors.joining(LF)))
+ where(() -> entity.idColumns().stream().map(column -> column.columnEqualsProperty("entity.")).collect(Collectors.joining(" AND ")));
}
});
}

/**
* 根据实体字段条件查询唯一的实体,根据实体字段条件批量查询,查询结果的数量由方法定义
*
Expand Down
25 changes: 25 additions & 0 deletions mapper/src/test/java/io/mybatis/mapper/fn/UserFnMapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,31 @@ public void testUpdateByPrimaryKeySelectiveWithForceFields() {
}
}

@Test
public void testUpdateForFieldListByPrimaryKey() {
SqlSession sqlSession = getSqlSession();
try {
// 元数据(1, '张无忌', '男', 1)
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectByPrimaryKey(1L).get();
user.setUserName("test");
user.setSex("女");
user.setStatus(false);
int count = mapper.updateForFieldListByPrimaryKey(user, Fn.of(User::getUserName, User::getStatus));
Assert.assertEquals(1, count);
user = mapper.selectByPrimaryKey(1L).get();
// 断言 sex 不会被更新
Assert.assertEquals("男", user.getSex());
// 断言userName被成功更新
Assert.assertEquals("test", user.getUserName());
// 短信 status不会被更新,user status 为不允许更新字段, 所以这里不会更新
Assert.assertEquals(user.getStatus(), true);
} finally {
//不要忘记关闭sqlSession
sqlSession.close();
}
}

@Test
public void testSelectColumnsOne() {
SqlSession sqlSession = getSqlSession();
Expand Down
7 changes: 7 additions & 0 deletions service/src/main/java/io/mybatis/service/AbstractService.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ public T update(T entity) {
return entity;
}

@Override
public T update(T entity, Fn<T, Object>... updateFields) {
Assert.isTrue(baseMapper.updateForFieldListByPrimaryKey(
entity, Fn.of(updateFields)) == 1, UPDATE_FAILURE);
return entity;
}

@Override
public T updateSelective(T entity) {
Assert.isTrue(baseMapper.updateByPrimaryKeySelective(entity) == 1, UPDATE_FAILURE);
Expand Down
9 changes: 9 additions & 0 deletions service/src/main/java/io/mybatis/service/EntityService.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public interface EntityService<T, I extends Serializable> {
*/
T update(T entity);

/**
* 更新(指定字段)
*
* @param entity 实体类
* @param updateFields 需要更新的字段
* @return 返回更新成功后的实体,远程服务调用时,由于序列化和反序列化,入参和返回值不是同一个对象
*/
T update(T entity, Fn<T, Object>... updateFields);

/**
* 更新(非空字段)
*
Expand Down
22 changes: 22 additions & 0 deletions service/src/test/java/io/mybatis/service/ServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,28 @@ public void testUserService() {
Assert.assertTrue(userService.findOne(user) != null);
}

@Test
public void testUpdate() {
// 元数据 (1, 'admin', 1)
UserService userService = context.getBean(UserService.class);
User user = userService.findById(1);
Assert.assertNotNull(user);

user.setName("administrator");
user.setRoleId(11);
userService.update(user, User::getName);
user = userService.findById(1);
Assert.assertEquals("administrator", user.getName());
Assert.assertEquals(1, (int) user.getRoleId());

user.setName("admin");
user.setRoleId(11);
userService.update(user, User::getRoleId);
user = userService.findById(1);
Assert.assertEquals("administrator", user.getName());
Assert.assertEquals(11, (int) user.getRoleId());
}

@Test
public void testIssues50() {
UserService userService = context.getBean(UserService.class);
Expand Down
Loading