如何在此 Java 8+ 应用程序中正确使用地图运算符以检索、修改和更新数据库上的对象?
How to correctly use the map operator in this Java 8+ application in order to retrieve, modify and update an object on the DB?
我正在开发一个基于 Spring Boot 的 Java 8+ 项目,我发现在尝试对我的代码使用“函数式”方法时遇到了一些困难。我承认我仍然使用 Java 7 方法,我正在尝试使用现代构造改进我的代码。
我有这个服务class方法:
/`
* Deactivate an user retrieved by its user ID
* @throws NotFoundException
*/
@Override
public Optional<User> deactivateUser(int userId) throws NotFoundException {
Optional<User> retrievedUser = this.userRepository.findById(userId);
return Optional.ofNullable(retrievedUser)
.map((user) -> retrievedUser.get())
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
}
如您所见,它首先使用 Spring Data JPA 存储库检索 Optional<User>
对象。
然后我尝试使用功能方法(使用 map()
运算符)来实现以下行为:
检索包含在使用存储库检索的 Optional<User>
对象中的 User
对象。
如果检索到的 Optional<User>
对象不为空 --> 在 return 这个对象之前做一些操作。
如果检索到的 Optional<User>
对象为空 --> 抛出 NotFoundException()
异常。
我觉得第1点和第3点没问题。问题是我不明白如何正确地将一些逻辑放入 map()
函数中,目前我有这样的东西:
.map((user) -> retrievedUser.get())
具体是什么意思?我认为它将 retrievedUser.get()
检索到的 User
对象放入 returned 的 user
变量中。我的推理正确吗? (我完全不确定)。
我的问题是,在 return 这个 User
对象之前,我需要执行一些操作(基本上更新一个名为 isActive
的字段,将其设置为 false
然后使用 Spring Data JPA save()
方法更新它)。我该怎么做?你能举个例子吗?我认为对我来说这可能是一个例子,我在 map()
运算符中有一个多行函数(也是一个首先执行 retrievedUser.get()
操作并将其打印到另一行的函数,那么我应该能够自己执行所需的逻辑)。
您可以编写一个接受用户和 return 用户的函数来执行 (2) 的逻辑。例如:
public User processUser(User user) {
user.setActive(false);
return user;
}
然后在map算子中引用这个函数:
return Optional.ofNullable(retrievedUser
.map((user) -> processUser(user))
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
您可以进一步使用方法参考将其简化为:
return Optional.ofNullable(retrievedUser
.map(this::processUser)
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
map method takes a Function object as a parameter. The Function is a generic interface that only has one method that acts like a callback, so in order to achieve your desired result, you have to implement this interface and pass it to the method. To do so, you can implement it by using a lambda expression(这是您尝试做的方式)。在这种情况下,将调用该函数并传递您的存储库找到的对象。
你可能想要这样的东西:
return Optional.ofNullable(retrievedUser)
.map((user) -> {
// do your operation with the object
return user;
})
.map(updatedUser -> userRepository.save(updatedUser))
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
请注意,在 lambda 表达式中,您处理的是 User
而不是 Optional<User>
,因此无需在此处使用 .get()
。
您还应该注意 orElse
/orElseThrow
类函数 return 对象的实例而不是 Optional,因此您必须更改 return 类型你的方法。
This article 如果想了解每个操作的作用以及如何使用它们,这是一本很好的读物。
我正在开发一个基于 Spring Boot 的 Java 8+ 项目,我发现在尝试对我的代码使用“函数式”方法时遇到了一些困难。我承认我仍然使用 Java 7 方法,我正在尝试使用现代构造改进我的代码。
我有这个服务class方法:
/`
* Deactivate an user retrieved by its user ID
* @throws NotFoundException
*/
@Override
public Optional<User> deactivateUser(int userId) throws NotFoundException {
Optional<User> retrievedUser = this.userRepository.findById(userId);
return Optional.ofNullable(retrievedUser)
.map((user) -> retrievedUser.get())
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
}
如您所见,它首先使用 Spring Data JPA 存储库检索 Optional<User>
对象。
然后我尝试使用功能方法(使用 map()
运算符)来实现以下行为:
检索包含在使用存储库检索的
Optional<User>
对象中的User
对象。如果检索到的
Optional<User>
对象不为空 --> 在 return 这个对象之前做一些操作。如果检索到的
Optional<User>
对象为空 --> 抛出NotFoundException()
异常。
我觉得第1点和第3点没问题。问题是我不明白如何正确地将一些逻辑放入 map()
函数中,目前我有这样的东西:
.map((user) -> retrievedUser.get())
具体是什么意思?我认为它将 retrievedUser.get()
检索到的 User
对象放入 returned 的 user
变量中。我的推理正确吗? (我完全不确定)。
我的问题是,在 return 这个 User
对象之前,我需要执行一些操作(基本上更新一个名为 isActive
的字段,将其设置为 false
然后使用 Spring Data JPA save()
方法更新它)。我该怎么做?你能举个例子吗?我认为对我来说这可能是一个例子,我在 map()
运算符中有一个多行函数(也是一个首先执行 retrievedUser.get()
操作并将其打印到另一行的函数,那么我应该能够自己执行所需的逻辑)。
您可以编写一个接受用户和 return 用户的函数来执行 (2) 的逻辑。例如:
public User processUser(User user) {
user.setActive(false);
return user;
}
然后在map算子中引用这个函数:
return Optional.ofNullable(retrievedUser
.map((user) -> processUser(user))
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
您可以进一步使用方法参考将其简化为:
return Optional.ofNullable(retrievedUser
.map(this::processUser)
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
map method takes a Function object as a parameter. The Function is a generic interface that only has one method that acts like a callback, so in order to achieve your desired result, you have to implement this interface and pass it to the method. To do so, you can implement it by using a lambda expression(这是您尝试做的方式)。在这种情况下,将调用该函数并传递您的存储库找到的对象。
你可能想要这样的东西:
return Optional.ofNullable(retrievedUser)
.map((user) -> {
// do your operation with the object
return user;
})
.map(updatedUser -> userRepository.save(updatedUser))
.orElseThrow(() -> new NotFoundException(String.format("The user having ID %s was not found", userId))));
请注意,在 lambda 表达式中,您处理的是 User
而不是 Optional<User>
,因此无需在此处使用 .get()
。
您还应该注意 orElse
/orElseThrow
类函数 return 对象的实例而不是 Optional,因此您必须更改 return 类型你的方法。
This article 如果想了解每个操作的作用以及如何使用它们,这是一本很好的读物。