Spring 启动 JPA 和条件 API - Select 单列
Spring boot JPA & Criteria API - Select single column
我正在尝试从 table 中检索单个列,但出现有关 return 类型的编译错误。
SQL
select oComment from comment where oNote = note and version > 0;
我有 Comment
table 和 Note
table。评论 table 有 comment, note and version
列。评论本身就是一个注释。现在我想检索版本大于 0 的注释的所有评论。但是这里我只想要注释类型的注释列。
Comment.java
@Entity
@Table(name="comment")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="comments")
public class Comment implements Serializable {
private static final long serialVersionUID = -4420192568334549165L;
public Comment() {
}
@Id
@OneToOne
@JoinColumn(name="commentuuid",referencedColumnName="noteuuid")
private Note oComment;
@Id
@OneToOne
@JoinColumn(name="noteuuid",referencedColumnName="noteuuid")
private Note oNote;
}
Note.java
@Entity
@Table(name = "note")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="notes")
public class Note implements Serializable{
private static final long serialVersionUID = 4089174391962234433L;
@Column(name="title")
private String m_szTitle;
@Column(name="htmlcontent")
private String m_sbHtmlContent;
@Column(name="textcontent")
private String m_sbTextContent;
@Id
@Column(name="noteuuid", columnDefinition="varchar(36)")
private String noteUuid;
}
CustomRepositoryMethod
public List<Note> findAllByNote(Note oNote, int iOffset, int iResultSize) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
Root<Comment> oComment = cq.from(Comment.class);
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(oComment.get("oNote"), oNote));
predicates.add(cb.greaterThan(oComment.get("version"), 0));
Subquery<Note> subquery = cq.subquery(Note.class);
Root<Note> note = subquery.from(Note.class);
cb.desc(note.get("m_dtCreationDate"));
cq.where(predicates.toArray(new Predicate[0]));
cq.multiselect(oComment.<Note>get("oComment"));
return (List<Note>)em.createQuery(cq).setFirstResult(iOffset).setMaxResults(iResultSize).getResultList();
}
错误
return 语句出错,
Cannot cast from List<Comment> to List<Note>
没有必要编写自定义存储库方法,因为您正在创建的存储库方法已经在 spring-data 中生成。
如果您的存储库扩展了 CrudRepository,您将免费获得您正在寻找的方法。
模式是 findAllBy[propertyOfClass]。
但请注意,您的实体中实际上没有 NOTE 集合。
也许您应该先将 OneToOne 关联更改为 OneToMany。
您的条件查询的根是 Comment
而不是 Note
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
Root<Comment> oComment = cq.from(Comment.class);
而你正在尝试
return (List<Note>)em.createQuery(cq).setFirstResult(iOffset)
.setMaxResults(iResultSize).getResultList();
在这种情况下编译错误是不可避免的,因为em.createQuery(cq).getResultList()
将returnList<Comment>
而不是List<Note>
在CustomRepositoryMethod中先替换
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
至 CriteriaQuery<Note> cq = cb.createQuery(Note.class)
行
cb.createQuery
parameter accept result Class in docs 你可以看到。
更新
// assuming query like
// select oComment from comment inner join Note on comment.noteuuid=Note.noteuuid where Note.noteUuid = 1 and version > 0;
CriteriaBuilder cb = em.getCriteriaBuilder();
// data type of oComment
CriteriaQuery<Note> query = cb.createQuery(Note.class);
// from comment
Root<Comment> comment = query.from(Comment.class);
//join
Join<Comment, Note> note = comment.join(comment.get("oNote"));
//version Condition
Predicate version=cb.greaterThan(comment.get("version"),0 );
//Note condition
predicate note=cb.equal(note.get("noteuuid"),note.getNoteUuid());
// get oComment and where condtion
query.select(comment.get("oComment")).where(cb.and(version,note));
return em.createQuery(query).setFirstResult(iOffset).setMaxResults(iResultSize).getResultList();
可以构建为条件查询如下:
CriteriaQuery<Country> q = cb.createQuery(Country.class);
Root<Country> c = q.from(Country.class);
q.select(c.get("currency")).distinct(true);
select
方法接受一个 Selection 类型的参数并将其设置为 SELECT 子句内容。
我正在尝试从 table 中检索单个列,但出现有关 return 类型的编译错误。
SQL
select oComment from comment where oNote = note and version > 0;
我有 Comment
table 和 Note
table。评论 table 有 comment, note and version
列。评论本身就是一个注释。现在我想检索版本大于 0 的注释的所有评论。但是这里我只想要注释类型的注释列。
Comment.java
@Entity
@Table(name="comment")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="comments")
public class Comment implements Serializable {
private static final long serialVersionUID = -4420192568334549165L;
public Comment() {
}
@Id
@OneToOne
@JoinColumn(name="commentuuid",referencedColumnName="noteuuid")
private Note oComment;
@Id
@OneToOne
@JoinColumn(name="noteuuid",referencedColumnName="noteuuid")
private Note oNote;
}
Note.java
@Entity
@Table(name = "note")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="notes")
public class Note implements Serializable{
private static final long serialVersionUID = 4089174391962234433L;
@Column(name="title")
private String m_szTitle;
@Column(name="htmlcontent")
private String m_sbHtmlContent;
@Column(name="textcontent")
private String m_sbTextContent;
@Id
@Column(name="noteuuid", columnDefinition="varchar(36)")
private String noteUuid;
}
CustomRepositoryMethod
public List<Note> findAllByNote(Note oNote, int iOffset, int iResultSize) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
Root<Comment> oComment = cq.from(Comment.class);
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(oComment.get("oNote"), oNote));
predicates.add(cb.greaterThan(oComment.get("version"), 0));
Subquery<Note> subquery = cq.subquery(Note.class);
Root<Note> note = subquery.from(Note.class);
cb.desc(note.get("m_dtCreationDate"));
cq.where(predicates.toArray(new Predicate[0]));
cq.multiselect(oComment.<Note>get("oComment"));
return (List<Note>)em.createQuery(cq).setFirstResult(iOffset).setMaxResults(iResultSize).getResultList();
}
错误 return 语句出错,
Cannot cast from List<Comment> to List<Note>
没有必要编写自定义存储库方法,因为您正在创建的存储库方法已经在 spring-data 中生成。
如果您的存储库扩展了 CrudRepository,您将免费获得您正在寻找的方法。
模式是 findAllBy[propertyOfClass]。
但请注意,您的实体中实际上没有 NOTE 集合。
也许您应该先将 OneToOne 关联更改为 OneToMany。
您的条件查询的根是 Comment
而不是 Note
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
Root<Comment> oComment = cq.from(Comment.class);
而你正在尝试
return (List<Note>)em.createQuery(cq).setFirstResult(iOffset)
.setMaxResults(iResultSize).getResultList();
在这种情况下编译错误是不可避免的,因为em.createQuery(cq).getResultList()
将returnList<Comment>
而不是List<Note>
在CustomRepositoryMethod中先替换
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
至 CriteriaQuery<Note> cq = cb.createQuery(Note.class)
cb.createQuery
parameter accept result Class in docs 你可以看到。
更新
// assuming query like
// select oComment from comment inner join Note on comment.noteuuid=Note.noteuuid where Note.noteUuid = 1 and version > 0;
CriteriaBuilder cb = em.getCriteriaBuilder();
// data type of oComment
CriteriaQuery<Note> query = cb.createQuery(Note.class);
// from comment
Root<Comment> comment = query.from(Comment.class);
//join
Join<Comment, Note> note = comment.join(comment.get("oNote"));
//version Condition
Predicate version=cb.greaterThan(comment.get("version"),0 );
//Note condition
predicate note=cb.equal(note.get("noteuuid"),note.getNoteUuid());
// get oComment and where condtion
query.select(comment.get("oComment")).where(cb.and(version,note));
return em.createQuery(query).setFirstResult(iOffset).setMaxResults(iResultSize).getResultList();
可以构建为条件查询如下:
CriteriaQuery<Country> q = cb.createQuery(Country.class);
Root<Country> c = q.from(Country.class);
q.select(c.get("currency")).distinct(true);
select
方法接受一个 Selection 类型的参数并将其设置为 SELECT 子句内容。