如何将Spring Data JPA的分页实体映射为自定义的类型
问题
使用Spring Data JPA可以让操作数据库数据变得极为简单:定义一个实体类、然后再创建一个Interface继承JpaRepository,通过这个Interface的实例便可以对数据库进行增删改查。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class User {
private String username;
private String password; }
@Repository public interface UserRepository extends JpaRepository<User, String>, QuerydslPredicateExecutor<User> { }
@RestController @RequestMapping("/users") @Slf4j public class UserController { @Autowired private UserRepository userRepository; public Object listUser(Predicate predicate, Pageable pageable) { return userRepository.findAll(predicate, pageable); } }
|
数据库实体Entity是不可以直接返回给调用者的,因为有可能实体中包含像“用户密码”、“家庭住址”这样的敏感信息,或者“创建时间”、“最后更新时间”这样的无用信息。
因此,在查询出实体之后,就需要额外的一个转换动作,将数据库实体转换成视图对象或传输对象,但是数据仓库repository,返回的结果是一个org.springframework.data.domain.Page类型,如何能转换成自定义的类型呢?
方案
不要试图去操作这个“不可变”的对象(Page),例如List<User> content = userRepository.findAll(predicate, pageable).getContent();
,乖乖的用这个接口中提供的map方法!
方案一
不使用Lamdba表达式,创建一个java.util.function.Function逆名内部类,覆写apply方法进行转换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @RestController @RequestMapping("/users") @Slf4j public class UserController { @Autowired private UserRepository userRepository; public Page<UserDto> listUser(Predicate predicate, Pageable pageable) { Page<User> entities = userRepository.findAll(predicate, pageable); Page<UserDto> result = entities.map(new Function<User, UserDto>() { @Override public UserDto apply(User user) { UserDto dto = new UserDto(); dto.setUsername(user.getCode()); return dto; } }); return result; } }
|
方案二
使用Lamdba表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @RestController @RequestMapping("/users") @Slf4j public class UserController { @Autowired private UserRepository userRepository; public Page<UserDto> listUser(Predicate predicate, Pageable pageable) { Page<UserDto> entities = userRepository.findAll(predicate, pageable).map(UserDto::fromEntity); return entities; } }
public class UserDto { private String username;
public static UserDto fromEntity(User user) { UserDto userDto = new UserDto(); userDto.setUsername(user.getCode()); return userDto; } }
|
代码片段
1 2 3 4 5 6 7 8 9
| public Page<UserDto> listUser(Predicate predicate, Pageable pageable) { return userRepository.findAll(predicate, pageable).map(user -> { UserDto dto = new UserDto(); return dto; }); }
|
参考