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

如何连接多个queryDSL表

楚昀
2023-03-14

>

  • 帐户表:accountId(PK)电子邮件密码

    account_profile表:accountId(PK)(fk到account)昵称

    团体表:articleId(PK)accountId(fk to account)标题内容

    现在我想要下面的JPQL是查询DSL代码

    select r from community r join r.account.profile a where a.nickname = :nickname
    

    我有实体元模型-QAccount、QAccountProfile、QCommunity

    此外,我必须通过分页获得结果,因此应该使用pageable对象调用查询。

    这是我的工作还不起作用。

    JPAQuery</*What generic type expected?*/> query = new JPAQuery</*???*/>(entityManager);
    Predicate predicate = query.from(QCommunity.community).join(/*join directly accountProfile? or account? is it QEntity or real entity?*/);
    
    // where should I place nickname matching condition ?
    
    
    ...
    
    list = (repository.findAll(predicate, pageable)).getContent();
    

    昵称匹配条件应该放在哪里?

    编辑:追加实体信息

    Account.java

    @Entity
    @Table(name="account", uniqueConstraints={
        @UniqueConstraint(columnNames="account_seq"),
        @UniqueConstraint(columnNames="email")
    })
    @DynamicInsert
    @DynamicUpdate
    @Data
    @EqualsAndHashCode
    @ToString(includeFieldNames=true)
    @RequiredArgsConstructor(staticName="of")
    @NoArgsConstructor
    public class Account implements Serializable{
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="account_seq", nullable=false, unique=true)
        private Integer accountId;
    
        @Column(name="email", nullable=false, unique=true)
        @NonNull
        private String email;
    
        @NonNull
        private String password;
    
        @OneToOne(cascade=CascadeType.ALL, mappedBy="account")
        private AccountProfile profile;
    
        @OneToOne(cascade=CascadeType.ALL, mappedBy="account")
        private AccountSecurity security;
    }
    

    AccountProfile.java

    @Entity
    @Table(name="account_profile", uniqueConstraints={
        @UniqueConstraint(columnNames={"account_seq"}),
        @UniqueConstraint(columnNames={"nickname"})
    })
    @DynamicInsert
    @DynamicUpdate
    @Data
    @EqualsAndHashCode
    @ToString(includeFieldNames=true)
    @RequiredArgsConstructor(staticName="of")
    @NoArgsConstructor
    public class AccountProfile implements Serializable{
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @OneToOne(cascade=CascadeType.ALL)
        @JoinColumn(name="account_seq", referencedColumnName="account_seq")
        private Account account;
    
        @Column(name="nickname", nullable=false)
        @NonNull
        private String nickname;
    
    }
    

    Community.java

    @Entity
    @Table(name="community", uniqueConstraints = {
            @UniqueConstraint(columnNames="article_seq")
    })
    @DynamicInsert
    @DynamicUpdate
    @Data
    @NoArgsConstructor
    @EqualsAndHashCode
    @ToString(includeFieldNames=true)
    public class Community {
    
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="article_seq", nullable=false, unique=true)
        private Long articleId;
    
        @ManyToOne(cascade=CascadeType.ALL)
        @JoinColumn(name="account_seq", referencedColumnName="account_seq")
        private Account account;
    
        @Column(name="title", nullable=false)
        private String title;
    
        @Column(name="content", nullable=false)
        private String content;
    
        @Temporal(TemporalType.TIMESTAMP)
        @Column(name="reg_dt")
        private Date date;
    
        @Column(name="read_cnt", nullable=false)
        private int readCount;
    
        @Column(name="attach_url")
        private String attachUrl;
    
        @Column(name="attach_filename")
        private String attachFileName;
    
        @OneToMany(cascade=CascadeType.ALL, mappedBy="article")
        private Set<CommunityReply> replies;
    }
    

    编辑:问题已解决

    为了帮助像我一样面临这个问题的人,我将发布我的工作代码。代码正在搜索任何具有匹配的特定昵称的社区文章。

    @PersistenceContext
        private EntityManager entityManager;
    
    
        private List<Community> getList(int pageNo, String keyword, int rowsOnPage){
    
            int offset = (pageNo -1) * rowsOnPage;
            int limit = rowsOnPage;
    
            JPAQuery<Community> query = new JPAQuery<Community>(entityManager);
    
            QCommunity qCommunity = QCommunity.community;
            QAccount qAccount = QAccount.account;
            QAccountProfile qAccountProfile = QAccountProfile.accountProfile;
    
            return query
                .from(qCommunity)
                .innerJoin(qCommunity.account ,qAccount)
                .innerJoin(qAccount.profile, qAccountProfile)
                .where(qAccountProfile.nickname.like("%"+keyword+"%"))
                .orderBy(qCommunity.articleId.desc())
                .offset(offset)
                .limit(limit)
            .fetch();
        }
    
  • 共有1个答案

    姬墨竹
    2023-03-14

    首先,为QueryDSL查询声明一个自定义的扩展基存储库类。

    首先是接口:

    @NoRepositoryBean
    public interface ExtendedQueryDslJpaRepository<T, ID extends Serializable> 
            extends JpaRepository<T, ID>, QueryDslPredicateExecutor<T> {
    
        <T1> Page<T1> findAll(JPQLQuery jpqlQuery, Pageable pageable);
    }
    

    然后是实现:

    public class ExtendedQueryDslJpaRepositoryImpl<T, ID extends Serializable>
            extends QueryDslJpaRepository<T, ID> implements ExtendedQueryDslJpaRepository<T, ID> {
    
        private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;
    
        private final EntityPath<T> path;
        private final PathBuilder<T> builder;
        private final Querydsl querydsl;
    
        private EntityManager entityManager;
    
        public ExtendedQueryDslJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
            this(entityInformation, entityManager, DEFAULT_ENTITY_PATH_RESOLVER);
        }
    
        public ExtendedQueryDslJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, 
               EntityManager entityManager, EntityPathResolver resolver) {
    
            super(entityInformation, entityManager);
            this.path = resolver.createPath(entityInformation.getJavaType());
            this.builder = new PathBuilder(this.path.getType(), this.path.getMetadata());
            this.querydsl = new Querydsl(entityManager, this.builder);
            this.entityManager = entityManager;
        }
    
        @Override
        public <T1> Page<T1> findAll(JPQLQuery jpqlQuery, Pageable pageable) {
    
            // Count query
            final JPQLQuery<?> countQuery = jpqlQuery;
    
            // Apply pagination
            JPQLQuery<T1> query = querydsl.applyPagination(pageable, jpqlQuery);
    
            // Run query
            return PageableExecutionUtils.getPage(query.fetch(), pageable, countQuery::fetchCount);
        }
    }
    
    @Configuration
    @EnableJpaRepositories(basePackageClasses = ..., repositoryBaseClass = ExtendedQueryDslJpaRepositoryImpl.class)
    

    然后,您的存储库应该从新接口扩展(它当然扩展了JPararePository):

    @Repository
    public interface CommunityRepository extends ExtendedQueryDslJpaRepository<Community, Long> {
    }
    

    然后,可以尝试以下代码:

    String nickname = "nick";
    
    QAccount account = QAccount.account;
    QAccountProfile accountProfile = QAccountProfile.accountProfile;
    QCommunity community = QCommunity.community;
    
    JPQLQuery query = new JPAQuery(entityManager);
    
    BooleanBuilder predicate = new BooleanBuilder();
    predicate.and(accountProfile.nickname.eq(nickname));
    
    // select r from community r join r.account.profile a where a.nickname = :nickname
    query.from(community)
         .join(community.account, account)
         .join(account.accountProfile, accountProfile)
         .where(predicate);
    
    repository.findAll(query, pageable);
    

    希望能有所帮助。

     类似资料:
    • null item_warehouse 公司(fk代表项目)MBCONO 项目编号(fk表示项目)mbitno 环境(fk for Item)mbenv 仓库编号MBWHLO 其他属性(不重要) 在Item_wharehouse类中,我手动添加了foreignKey(因为它没有在实际的db模式中定义) 我的问题是找不到join方法的第二个参数类型。 我做错了什么?我错过了什么?有可能完成我想要的吗

    • 我试图将QueryDSL与Spring Data JPA一起使用。

    • 下面的代码片段是从JoinedStreams的javadoc复制的 这两个流仅基于一个键(通过< code>t =计算)进行连接 我会问我如何基于多个键进行连接,例如,one.a = two.a和

    • 下面的代码适用于一个if语句,但没有给出另一个if语句的结果,它在第一个查询中显示了'flights'表,但在另一个条件之后,没有显示另一个名为'ISB to Muree'的表。

    • 问题内容: 目前,我的连接 mongoose.js 具有以下代码: 需要连接的文件是 test.js : 如何更新mongoose.js以使用mongoose.createConnection(…)函数使用多个连接? 当我进行如下更改时,我仅从一个连接的更改开始: 我得到“未定义不是函数”。如果我使用此代码: 我收到“错误:尝试打开未关闭的连接” 有什么建议吗? 问题答案: mongoose通过

    • 我有一些元素,我想通过JSPlumb社区版将它们连接起来。我在javascript中有以下代码行: 我想做的是在运行时制作两个和一个,并将两个源endpoint连接到目标endpoint,但当我将一个源endpoint连接到目标endpoint时,目标不会接受第二个源endpoint。我该怎么做?