Spring Data非数据库映射查询:如何将结果存入列表?
在Spring Data中无需实体类,将查询结果存入列表的实现方案
嘿,我来帮你搞定这个需求!你完全不需要创建实体类或者做数据库模型映射,就能在控制器里获取查询结果并存入列表使用。下面给你几种实用的实现方式:
方式一:返回List<Object[]>(简单直接)
这种方式适合查询字段较少的场景,查询结果会以对象数组的形式返回,每个数组元素对应你查询的一个字段。
1. 定义自定义Repository
不需要绑定到任何实体类,直接继承Repository接口即可:
@Repository public interface CustomQueryRepo extends Repository<Object, Long> { // 原生SQL查询,nativeQuery=true表示使用原生SQL @Query(value = "SELECT id, username, email FROM users WHERE age > ?1", nativeQuery = true) List<Object[]> getUsersAboveAge(int age); }
2. 在控制器中注入并使用
直接调用Repository方法拿到列表,然后按需处理:
@RestController @RequestMapping("/demo") public class QueryController { private final CustomQueryRepo queryRepo; // 构造注入(Spring推荐的注入方式) public QueryController(CustomQueryRepo queryRepo) { this.queryRepo = queryRepo; } @GetMapping("/users") public ResponseEntity<List<Object[]>> getUsers() { List<Object[]> userList = queryRepo.getUsersAboveAge(18); // 遍历列表做业务处理 for (Object[] user : userList) { Long userId = (Long) user[0]; String username = (String) user[1]; String email = (String) user[2]; // 这里可以执行你的业务逻辑,比如打印、封装成DTO等 } return ResponseEntity.ok(userList); } }
方式二:返回List<Map<String, Object>>(可读性更强)
如果不想记数组索引,这种方式会把查询字段名作为Map的key,取值更直观:
修改Repository方法
@Repository public interface CustomQueryRepo extends Repository<Object, Long> { @Query(value = "SELECT id, username, email FROM users WHERE age > ?1", nativeQuery = true) List<Map<String, Object>> getUsersAboveAgeAsMap(int age); }
控制器中使用
List<Map<String, Object>> userMapList = queryRepo.getUsersAboveAgeAsMap(18); for (Map<String, Object> userMap : userMapList) { Long userId = (Long) userMap.get("id"); String username = (String) userMap.get("username"); // 直接通过字段名取值,不用关心顺序 }
方式三:使用接口投影(类型安全,推荐)
如果想要类型安全的操作,又不想创建实体类,可以定义一个投影接口,Spring会自动帮你生成实现类:
1. 定义投影接口
只声明你需要的字段对应的getter方法:
public interface UserProjection { Long getId(); String getUsername(); String getEmail(); }
2. 修改Repository方法
返回这个投影接口的列表:
@Repository public interface CustomQueryRepo extends Repository<Object, Long> { @Query(value = "SELECT id, username, email FROM users WHERE age > ?1", nativeQuery = true) List<UserProjection> getUsersAboveAgeAsProjection(int age); }
3. 控制器中使用
直接调用getter方法,无需强转,类型安全:
List<UserProjection> userProjections = queryRepo.getUsersAboveAgeAsProjection(18); for (UserProjection user : userProjections) { System.out.println("用户名:" + user.getUsername()); // 操作起来非常方便 }
关键总结
- 完全不需要创建实体类,也不用做数据库模型映射
- 三种方式各有适用场景:
Object[]:简单快捷,适合字段少的情况Map<String, Object>:直观易读,不用记字段顺序- 接口投影:类型安全,代码更规范,推荐字段多的场景
- 所有列表都可以直接在控制器中获取并使用,满足你的需求
内容的提问来源于stack exchange,提问作者Manjil Lama
相关产品推荐
相关产品推荐

