当前位置: 首页 > 知识库问答 >
问题:

springboot - SpringDataJpa中 Specification怎样使用in查询?

满博
2024-01-26

SpringDataJpaSpecification怎样使用in查询

实体类Menu.java如下

@Entity@Getter@Table(name = "t_sys_menu")@org.hibernate.annotations.DynamicInsert@org.hibernate.annotations.DynamicUpdate@org.hibernate.annotations.Where(clause = SysConstants.WHERE_DELETE)public class Menu extends TreeEntity<Menu, Long> {    @Column(nullable = false, length = 50)    private String name;    @Column(length = 100)    private String path;    @Column(length = 100)    private String componentPath;    @Column(columnDefinition = "int unsigned")    private Integer level;    /**     * 0表示目录,1表示菜单,2表示按钮     */    @Column(nullable = false, columnDefinition = "tinyint unsigned")    private Integer type;    @Column(length = 20)    private String icon;    @JoinColumn    @ManyToOne(fetch = FetchType.LAZY)    private Application application;    @Column(nullable = true, length = 50)    private String permission;    @Convert(converter = Status.Converter.class)    @Column(nullable = false, columnDefinition = "tinyint unsigned")    private Status status;    private String visible;    /**     * 打开方式 页签 或是 新窗口     */    private String target;    @Column(columnDefinition = "int unsigned")    private Integer sort;    @Column(length = 200)    public String description;    @ManyToMany(fetch = FetchType.LAZY)    @JoinTable(name = "t_sys_role_menu", joinColumns = @JoinColumn(name = "menu_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))    private Collection<Role> roles;

想通过roles属性做in查询,代码如下

    private Specification<Menu> buildSearchSpecification(MenuDTO menuDTO) {        return (root, query, criteriaBuilder) -> {            List<Predicate> predicates = new ArrayList<>();            if (StringUtils.hasText(menuDTO.getRoleIds())) {                List<Role> roles = new ArrayList<>();                for (Long roleId : Convert.toList(Long.class, menuDTO.getRoleIds())) {                    roles.add(new Role(roleId));                }                predicates.add(root.get(Menu_.roles).in(roles));            }            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));        };    }

错误如下:

Parameter value [com.appmtce.pojo.entity.role.Role@20f81e2a] did not match expected type [java.util.Collection (n/a)]

我的Specification方式的in查询写的哪里不对,如何修改正确?

共有2个答案

程瑞
2024-01-26

我知道怎么弄了

predicates.add(root.get(Menu_.roles).in(roles));

改成了

predicates.add(root.join(Menu_.roles, JoinType.LEFT).in(roles));
程鸿煊
2024-01-26

你的代码中,in查询的参数类型不正确。in查询期望的是一个集合(Collection),而你传递的是一个Role对象。你需要将Role对象转换为对应的ID集合。

修改后的代码如下:

private Specification<Menu> buildSearchSpecification(MenuDTO menuDTO) {    return (root, query, criteriaBuilder) -> {        List<Predicate> predicates = new ArrayList<>();        if (StringUtils.hasText(menuDTO.getRoleIds())) {            List<Long> roleIds = Convert.toList(Long.class, menuDTO.getRoleIds());            predicates.add(root.get(Menu_.roles).in(roleIds));        }        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));    };}

在这个修改后的代码中,我们首先将menuDTO.getRoleIds()转换为Long类型的列表,然后将其传递给in方法。这样,in方法就能正确地处理一个集合类型的参数了。

 类似资料:
  • 我对规范、构建器、查询不是很有经验,我必须做一个相当复杂的查询,就像这样: 我有一个这样的DTO: 对我来说很难。我什么都试过了。我宁愿给你看一个具体的案例,以免产生误解。有人能帮我吗?我将非常感激! 我不需要使用规范,我只需要能够重现那个查询示例,规范似乎是最好的选择。 谢谢大家。

  • 本文向大家介绍怎样在react中使用innerHTML?相关面试题,主要包含被问及怎样在react中使用innerHTML?时的应答技巧和注意事项,需要的朋友参考一下 dangerouslySetInnerHTML https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

  • 我在GET api中有多个查询参数(如姓名、年龄、性别、位置等…n个数字)。现在我需要使用这些查询值来查询我的mongo数据库。现在用户可以发送从0到n的查询参数。 我正在尝试使用类似的东西 或者 但问题是,考虑到用户可以发送的所有排列和组合,我将不得不编写多个查询。有没有更好的方法来做到这一点?

  • RTMP的url其实很简单,vhost其实也没有什么新的概念,但是对于没有使用过的同学来讲,还是很容易混淆。 几乎每个新人都必问的问题:RTMP那个URL推流时应该填什么,什么是vhost,什么是app? Vhost(Virtual Host)就是虚拟域,用来隔离客户或业务。如下图所示: RTMP和HLS的优势参考:HLS Use Scenarios Vhost的主要应用场景包括: 一个分发网络支

  • OpenAPI Specification 的目标是为 REST API 定义一个标准的、与语言无关的接口,允许人和计算机在不访问源代码、文档或通过网络的情况下发现和理解服务的功能。 通过 OpenAPI 的正确定义,消费者可以用最简答的方式理解远程服务并与其交互,消除了调用服务时的猜测。 OpenAPI不需要重写现有的API。它不需要将任何软件绑定到服务,所描述的服务甚至可能不是您的。然而,它要

  • 我刚刚开始使用Spring Boot,我想使用RestTemplate调用一个查询并返回它的结果。 如何使用RESTTemplate调用查询?还是有更好的办法做这件事?