我在使用簡單的Spring數據查詢或@Query或QueryDSL在Spring Data中構建查詢時遇到了問題。如何在Spring數據中選擇不同的結果
如何選擇對於三列(Study,Country,Login)將是不同的行,並且作爲查詢的結果將是User的對象類型列表?
表:
-------------------------------------
| User |
-------------------------------------
| Id | Study | Country | Site | Login | -------------------------------------
| 1 | S1 | US | 11 | user1 |
| 2 | S1 | US | 22 | user1 |
| 3 | S1 | US | 33 | user1 |
| .. | .. | .. | .. | .. |
-------------------------------------
我需要它僅僅基於Study
將返回唯一用戶爲每個查詢和Country
而且沒有考慮到Site
列。
方法簽名是象下面這樣:
List<User> findByStudyIgnoreCase(String study);
而現在正在返回從表的用戶所有行。所以我在研究和國家中重複了有關用戶分配的行,因爲我在其他表中不需要Site
的其他表中的UI演示文稿。
所以,我需要這樣的:
select distinct Study, Country, Login from User
但返回的對象必須是用戶對象就像方法簽名稱(例如第一個匹配的結果)。
怎麼辦?
以這種方式或類似的方式可能嗎?如何使其正確?
@Query("SELECT DISTINCT s.study, s.country, s.login FROM user s where s.study = ?1 ") List<User> findByStudyIgnoreCase(String study);
使用QueryDSL這可能嗎?
---- ----編輯
我試圖通過QueryDSL編寫查詢像TimoWestkämper建議,但我有一個問題。
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
爲什麼會發生?
---- EDIT 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;
}
}
這是可能的嗎?你爲什麼不嘗試它? –
@JBNizet我試過了,而不是用戶我只有學習,國家和登錄值的對象,所以它不是我所期待的... – Roman
這是相當期望的,因爲您的查詢選擇研究,國家和登錄。 –