You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:49:01