GraphQL Spring Boot中@BatchMapping如何获取字段参数
Spring Boot GraphQL @BatchMapping 获取字段参数方案
在Spring Boot GraphQL开发场景中,用@BatchMapping优化n+1问题时,会遇到Post类型的upvoted(username: String!)字段无法获取username参数的问题——原@SchemaMapping可以直接通过@Argument拿到参数,但批量映射时不知道如何获取这个字段级别的参数。
解决方案1:直接绑定参数列表
Spring GraphQL的@BatchMapping支持批量绑定源对象与对应参数,参数列表的索引会和源对象列表一一对应(即posts.get(i)对应username.get(i))。直接在方法参数中添加@Argument List<String> username即可:
@BatchMapping public Map<Post, Boolean> upvoted(List<Post> posts, @Argument List<String> username) { Map<Post, Boolean> result = new HashMap<>(); List<Long> postIds = posts.stream().map(Post::getId).collect(Collectors.toList()); // 遍历处理每个post与对应username的匹配关系 for (int i = 0; i < posts.size(); i++) { Post post = posts.get(i); String targetUser = username.get(i); // 替换为实际业务逻辑:检查当前post是否被targetUser点赞 result.put(post, checkPostUpvote(post.getId(), targetUser)); } return result; } // 模拟业务查询方法 private boolean checkPostUpvote(Long postId, String username) { // 实际可替换为数据库批量查询或缓存校验逻辑 return true; }
解决方案2:通过BatchLoaderEnvironment获取参数
如果需要处理复杂参数对象,或需要更灵活的参数提取逻辑,可以使用BatchLoaderEnvironment获取每个源对象对应的参数:
@BatchMapping public Map<Post, Boolean> upvoted(List<Post> posts, BatchLoaderEnvironment env) { Map<Post, Boolean> result = new HashMap<>(); // 获取每个Post对应的字段参数集合 List<Map<String, Object>> argumentsList = env.getArguments(); for (int i = 0; i < posts.size(); i++) { Post post = posts.get(i); // 从参数集合中提取username String targetUser = (String) argumentsList.get(i).get("username"); // 业务逻辑处理 result.put(post, checkPostUpvote(post.getId(), targetUser)); } return result; }
验证查询
使用你提供的查询语句测试,两种方案都能正确获取每个Post对应的username参数,完成批量查询并返回结果,同时解决n+1问题:
{ user(username: "1") { posts { upvoted(username: "2") } } }
内容的提问来源于stack exchange,提问作者999
相关产品推荐
相关产品推荐

