我对JPA 2很新,它是CriteriaBuilder/CriteriaQuery API:
我想计算CriteriaQuery的结果而不实际检索它们.这是可能的,我没有找到任何这样的方法,唯一的方法是这样做:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> cq = cb
.createQuery(MyEntityclass);
// initialize predicates here
return entityManager.createQuery(cq).getResultList().size();
Run Code Online (Sandbox Code Playgroud)
这不是正确的方法......
有解决方案吗?
是否可以使用JPA查询从对象中仅选择属性A和B而不使用条件查询?
要选择所有属性,我只需执行以下操作:
SELECT i FROM ObjectName i WHERE i.id = 10
Run Code Online (Sandbox Code Playgroud)
但是我在遗留系统上有一个具有许多属性的对象,并且想要选择几个,即使我知道选择几个属性通常很快.
这可能不使用标准查询吗?
谢谢!
我有以下EJB结构.不要怀疑Animal
和Inventory
,这些类只是在这里以简化的方式演示结构(更新:我修改了类名以构造一个更好的可理解的例子.另一个实现IdTag
可能是a BarcodeId
).请注意,IdTag
与Animal
或之间没有反比关系Inventory
,我们假设它RfidTag.code
是唯一的.我阅读使用Criteria Query和Hibernate多态查询检索多态Hibernate对象,但这些讨论似乎没有回答我的问题.
public interface ItemWithIdTag
{
IdTag getIdTag();
void setIdTag(IdTag idTag);
}
@Entity public class Animal implements ItemWithIdTag,Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO) private long id;
@OneToOne(cascade = CascadeType.ALL)
private IdTag idTag;
}
@Entity public class Inventory implements ItemWithIdTag,Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO) private long id;
@OneToOne(cascade = CascadeType.ALL)
private IdTag idTag;
}
@Entity @Table(name = "IdTag") @Inheritance(strategy= InheritanceType.JOINED)
public …
Run Code Online (Sandbox Code Playgroud) 也许这是一个愚蠢的问题,但我在文档中找不到答案:如何使用JPA2设置CriteriaQuery的限制?
谢谢
这是一个示例实体:
public class Account{
@Id
Long id
Double remaining;
@ManyToOne
AccountType type
}
public class AccountType{
@Id
Long id;
String name;
}
Run Code Online (Sandbox Code Playgroud)
现在我使用Join创建一个条件查询,如下所示:
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createquery();
Root<Account> accountRoot = criteriaQuery.from(Account.class);
Join<Account, AccountType> typeJoin = accountRoot.join(Account_.type);
criteriaQuery.multiSelect(
typeJoin,
criteriaBuilder.sum(accountRoot.get(Account_.remaining))
);
criteriaQuery.groupBy(typeJoin);
Query query = getEntityManager().createQuery(criteriaQuery);
query.getResultList();
Run Code Online (Sandbox Code Playgroud)
上面的代码生成如下的Sql命令:
select accType.id, accType.name, sum(acc.remaining)
from account acc join accType on acc.accounttype_id = accType.id
group by accType.id
Run Code Online (Sandbox Code Playgroud)
上面的代码在PosgreSQL中工作,但无法在Oracle中运行,因为在其中选择未出现在group by子句中的accType.name.
更新:
我认为我的问题不清楚.我的问题不是关于PostgreSQL或Oracle的行为group by
.我的问题是:
我使用typeJoin
in group by …
我需要使用大量条件连接和 where 子句进行条件查询,在这种情况下,代码往往会变得复杂并且可能会产生重复连接。
例如,我有以下表和 JPA 实体的结构:
ACCOUNT
ACCOUNT_ID
ACCOUNT_TYPE
PERSON
NAME
AGE
ACCOUNT_ID ( FK TO ACCOUNT )
ADDRESS_ID ( FK TO ADDRESS )
ADDRESS
ADDRESS_ID
LOCATION
COUNTRY
Run Code Online (Sandbox Code Playgroud)
所以假设我使用静态元模型实现来应用条件查询。
这是可以生成重复连接的错误代码示例:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Account> cq = cb.createQuery(Account.class);
cq.select(accountRoot).where(
cb.and(
cb.equal(accountRoot.join(Account_.person).get(Person_.name),"Roger"),
cb.greaterThan(accountRoot.join(Account_.person).get(Person_.age),18),
cb.equal(accountRoot.join(Account_.person)
.join(Person_.address).get(Address_.country),"United States")
)
)
TypedQuery<Account> query = entityManager.createQuery(cq);
List<Account> result = query.getResultList();
Run Code Online (Sandbox Code Playgroud)
上面的代码将生成一个具有同一个表的多个连接的 SQL:
Select
account0_.account_id as account1_2_,
account0_.account_type as account2_2_
from
account account0_
inner join
person person1_
on account0_.account_id=person1_.account_id
inner join
address address2_
on person1_.address_id=address2_.address_id
inner …
Run Code Online (Sandbox Code Playgroud) 我喜欢类型安全CriteriaQuery带来了JPA 2.0,但它也带来了一些样板代码.例如,假设我有一个名为NamedEntity的实体,它只有一个id和一个名为"name"的String字段(假设它将唯一约束设置为true).以下是NamedEntityManager的外观:
public class NamedEntityManager
{
//inject using your framework
EntityManager entityManager;
//retrieve all existing entities of type NamedEntity from DB
public Iterable<NamedEntity> queryAll()
{
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<NamedEntity> query = builder.createQuery(NamedEntity.class);
return entityManager.createQuery(query).getResultList();
}
//retrieve a single entity of type NamedEntity from DB using specified name
public NamedEntity queryByName(String name)
{
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<NamedEntity> query = builder.createQuery(NamedEntity.class);
Root<NamedEntity> root = query.from(NamedEntity.class);
query = query.where(root.<NamedEntity>get("name").in(name));
//skipped the try/catch block for the sake of brevity
return …
Run Code Online (Sandbox Code Playgroud) 考虑以下:
@Entity
public class Book
{
private List<String> authors;
@ElementCollection
public List<String> getAuthors() {
return authors;
}
public void setAuthors(List<String> authors) {
this.authors = authors;
}
}
Run Code Online (Sandbox Code Playgroud)
如何输入JPA2 CriteriaQuery表达式,比方说,让我找到所有超过2位作者的书籍?
大家好我想在CriteriaQuery中做这个,我搜索了这么久但我找不到任何可以做到的,有人可以帮助我吗?
SELECT b.name
FROM Empl a
LEFT OUTER JOIN Deplo b ON (a.id_depl = b.id_depl) AND b.id_place = 2;
Run Code Online (Sandbox Code Playgroud)
我只是试图在左连接子句中做一个条件,我看到".on"函数,但我不知道它是否会起作用以及它是如何工作的,因为我试图做这样的事情:
Join Table1, Table2j1 = root.join(Table1_.table2, JoinType.LEFT).on(cb.and(cb.equal(table2_.someid, someId)));
Run Code Online (Sandbox Code Playgroud)
但它需要一个布尔表达式.
我有 2 张桌子
ID | 姓名 |
---|---|
1 | 亚历克斯 |
ID | 姓名 | 地位 | 企业ID |
---|---|---|---|
7 | 苹果12 | 积极的 | 1 |
8 | 苹果11 | 积极的 | 1 |
6 | iphone13 | 禁用 | 1 |
这种关系是一对多的(一个企业有多个产品)。我想和Enterprise
他们所有人Product
一起得到一个条件是Status
这样Product
的ACTIVE
我怎样才能得到json的结果是
{
"id": "1",
"name": "Alex",
"products": [
{
"id": "7",
"name": "Iphone12",
},
{
"id": "8",
"name": "Iphone11",
}
]
}
Run Code Online (Sandbox Code Playgroud) criteriaquery ×10
java ×8
jpa ×6
jpa-2.0 ×5
hibernate ×3
clause ×1
criteria-api ×1
group-by ×1
inheritance ×1
jpa-2.1 ×1
json ×1
left-join ×1
orm ×1