gpt4 book ai didi

java - 如何在 Spring Data 中选择不同的结果

转载 作者:太空宇宙 更新时间:2023-11-04 07:01:42 27 4
gpt4 key购买 nike

我在使用简单的 Spring Data 查询或 @Query 或 QueryDSL 在 Spring Data 中构建查询时遇到问题。

如何选择三列(学习、国家、登录)不同的行,并且查询结果将是用户对象类型的列表?

表:

-------------------------------------
| User |
-------------------------------------
| Id | Study | Country | Site | Login |
-------------------------------------

| 1 | S1 | US | 11 | user1 |
| 2 | S1 | US | 22 | user1 |
| 3 | S1 | US | 33 | user1 |

| .. | .. | .. | .. | .. |
-------------------------------------

我需要一个仅基于 Study 的查询将为每个 Login 返回唯一的用户和Country仅且不考虑 Site专栏。

方法签名如下:

List<User> findByStudyIgnoreCase(String study);

现在正在返回用户表中的所有行。因此,我在“学习”和“国家”中重复了有关用户分配的行,因为我在其他表中有 UI 演示,其中 Site不需要。

所以,我需要类似的东西:

select distinct Study, Country, Login from User

但返回对象必须是 User 对象,就像方法签名所说的那样(例如第一个匹配结果)。

如何做到这一点?

  1. 这种方式或者类似的方式可以吗?如何使其正确?

    @Query("SELECT DISTINCT s.study, s.country, s.login FROM user s where s.study = ?1 ")
    List<User> findByStudyIgnoreCase(String study);

  2. 是否可以使用 QueryDSL?

---- 编辑 ----

我尝试像 TimoWestkämper 建议的那样通过 QueryDSL 编写查询,但遇到问题。

    public List<User> findByStudyIgnoreCase(String study) {
QUser $ = QUser.user;
BooleanExpression studyExists = $.study.equalsIgnoreCase(study);

List<Users> usersList = from($)
.where(studyExists)
.distinct()
.list(Projections.bean(User.class, $.study, $.country, $.id.login));

return usersList;
}

调用上述查询后发生异常:

org.springframework.dao.InvalidDataAccessApiUsageException: The bean of type: com.domain.app.model.User has no property called: study; nested exception is java.lang.IllegalArgumentException: The bean of type: com.domain.app.model.User has no property called: study

为什么会发生这种情况?

---- 编辑 2 ----

我的User类:

@Entity
@Table(name="USER")
@Immutable
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter @EqualsAndHashCode @ToString
@FieldDefaults(level=AccessLevel.PRIVATE)
public class User {

@EmbeddedId
UserId id;

@Column(name="CONTACT_UNIQUE_ID")
String contactUniqueId;

String country;

@Column(name="COUNTRY_CODE")
String countryCode;

@Column(name="STUDY")
String study;

String firstname;

String lastname;

String email;

String role;
}

可嵌入UserId类:

@Embeddable
@Getter @EqualsAndHashCode @ToString
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level=AccessLevel.PRIVATE)
public class UserId implements Serializable {

private static final long serialVersionUID = 1L;

String site;
String login;

}

生成的QUser类:

@Generated("com.mysema.query.codegen.EntitySerializer")
public class QUser extends EntityPathBase<User> {

private static final long serialVersionUID = 1646288729;

private static final PathInits INITS = PathInits.DIRECT;

public static final QUser user = new User("user");

public final StringPath contactUniqueId = createString("contactUniqueId");

public final StringPath country = createString("country");

public final StringPath countryCode = createString("countryCode");

public final StringPath study = createString("study");

public final StringPath email = createString("email");

public final StringPath firstname = createString("firstname");

public final QUser id;

public final StringPath lastname = createString("lastname");

public final StringPath role = createString("role");

public QUser(String variable) {
this(User.class, forVariable(variable), INITS);
}

@SuppressWarnings("all")
public QUser(Path<? extends User> path) {
this((Class)path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT);
}

public QUser(PathMetadata<?> metadata) {
this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT);
}

public QUser(PathMetadata<?> metadata, PathInits inits) {
this(User.class, metadata, inits);
}

public QUser(Class<? extends User> type, PathMetadata<?> metadata, PathInits inits) {
super(type, metadata, inits);
this.id = inits.isInitialized("id") ? new QUser(forProperty("id")) : null;
}

}

最佳答案

我可以回答 Querydsl 部分。它的工作原理是通过

List<User> users = query.from(user)
.where(user.study.eq(arg))
.distinct()
.list(Projections.fields(User.class, user.study, user.country, user.login));

您将获得包含填充的研究、国家/地区和登录字段的用户实例。 User 实例不是托管 JPA 实体,而是填充的 bean。

或者,您可以像这样查询元组实例

List<Tuple> tuples = query.from(user)
.where(user.study.eq(arg))
.distinct()
.list(user.study, user.country, user.login);

但是当您使用 Spring Data 时,您可能想返回 Users。

关于java - 如何在 Spring Data 中选择不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22017361/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com