QuerydslPredicate和泛型类

19

我有很多控制器拥有相同的方法,唯一的区别在于实体类。

我想创建一个通用的BaseController,但是在QuerydslPredicate注释上遇到了问题(无法设置根,这是通用的)。

class abstract BaseController<T extends BaseEntity> {
   @Autowired
   private Repository<T, Long> repository;

   @RequestMapping(method = RequestMethod.GET)
   public Page<T> findAll(@QuerydslPredicate Predicate predicate, Pageable pageable) {
      return repository.findAll(predicate, pageable);
   }
}

QuerydslPredicateArgumentResolver中的extractTypeInfo方法返回的是T,但需要的是实体类。

我无法将根值设置为QuerydslPredicate(没有类)。

@QuerydslPredicate(root = T.class)

有关如何实现这一点的任何帮助?

你有没有想到任何解决方案? - TheKojuEffect
我有相同的问题,有解决方法吗? - Yunus Einsteinium
其实我认为问题在于Spring核心Predicate的设计上。Predicate应该被设计为Predicate<T>,这样它就能很好地适配了。 - Saurabh Kumar
看看这个链接,可能会有帮助:https://stackoverflow.com/questions/51111121/querydslbindercustomizer-not-working-in-spring-data-jpa-2-0-7/51113803 - I_Al-thamary
1个回答

3

我认为没有办法将通用类提供给注解。它应该是编译时常量。

但这怎么样?(大量代码,完整示例)。

Spring基础

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

实体

@MappedSuperclass
@Data
@NoArgsConstructor
@AllArgsConstructor
public abstract class BaseEntity {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "created_at")
    private Date createdAt;
}

@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {

    @Column(name = "username")
    private String userName;
}

@Entity
@Table(name = "another_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class AnotherUser extends BaseEntity {

    @Column(name = "another_username")
    private String anotherUserName;
}

控制器

public abstract class BaseEntityController<T extends BaseEntity> {

    private final BaseEntityRepository<T> repository;

    @Autowired
    protected BaseEntityController(BaseEntityRepository<T> repository) {
        this.repository = repository;
    }

    @GetMapping(value = "/index")
    public Page<T> index(Predicate predicate, Pageable pageable) {
        return repository.findAll(predicate, pageable);
    }
}

@RestController
@RequestMapping("/user")
public class UserController extends BaseEntityController<User> {

    protected UserController(BaseEntityRepository<User> repository) {
        super(repository);
    }

    @Override
    public Page<User> index(@QuerydslPredicate(root = User.class) Predicate predicate, Pageable pageable) {
        return super.index(predicate, pageable);
    }
}

@RestController
@RequestMapping("/anotheruser")
public class AnotherUserController extends BaseEntityController<User> {

    protected AnotherUserController(BaseEntityRepository<User> repository) {
        super(repository);
    }

    @Override
    public Page<User> index(@QuerydslPredicate(root = AnotherUser.class) Predicate predicate, Pageable pageable) {
        return super.index(predicate, pageable);
    }
}

仓库

@NoRepositoryBean
public interface BaseEntityRepository<T extends BaseEntity> extends CrudRepository<T, Integer>, QuerydslPredicateExecutor<T> {
}

@Repository
public interface UserEntityRepository extends BaseEntityRepository<User> {
}

@Repository
public interface AnotherUserEntityRepository extends BaseEntityRepository<AnotherUser> {
}

它尽可能地工作并抽象化。但是,您仍需要为每个@Entity生成额外的@Controller@Repository类。虽然它们将大多为空桩,但我认为您无法完全欺骗@Querydsl或Spring Data以正确使用泛型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接