Spring フレームワークを使用しています。パッケージとアイテムの 2 つのテーブルがあり、関係は 1 つのパッケージに多くのアイテムがあります。テーブルのデザインは次のようなものです。
パッケージ
@Entity
@Table(name = "TB_PACKAGE")
public class Packages implements Serializable{
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "PACKAGE_ID")
private String packageId;
@Valid
@OneToMany(mappedBy = "packages", cascade = { CascadeType.ALL })
private List<Item> item;
アイテム
@Entity
@Table(name = "TB_ITEM")
public class Item implements Serializable{
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "ITEM_ID")
private String itemId;
@ManyToOne
@JoinColumn(name="PACKAGE_ID")
private Packages packages;
@Transient
private String packageId;
これは、CriteriaBuilder を使用してテーブルを結合するコードを記述し、このような結果を得る方法です。
SQL:
SELECT * FROM Packages p JOIN Item i ON p.packageId = i.packageId;
ジャワ:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Packages> cq = cb.createQuery(Packages.class);
Root<Packages> pRoot = cq.from(Packages.class);
Join<Packages, Item> packagesItem = pRoot.join("item");
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtils.isNotEmpty(itemName)) {
predicates.add(cb.like(cb.lower(packagesItem.<String>get("itemName")), "%" + itemName.toLowerCase() + "%"));
}
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
cq.distinct(true);
TypedQuery<Packages> query = em.createQuery(cq);
return query.getResultList();
パラメータとして「電話」を入力すると、JSON としてレコードが出力されるはずです。
"packageId": "P1",
"item": [
{
"itemId": "Item 1",
"temName" "Phone"
}
]
ただし、パッケージは常に次のようにすべての子をロードします。
"packageId": "P1",
"item": [
{
"itemId": "Item 1",
"temName" "Phone"
},
{
"itemId": "Item 2",
"temName" "Laptop"
},
{
"itemId": "Item 3",
"temName" "Mouse"
}
]
FetchType.Lazy、QueryDsl、Native Query、HQL など、すべて試してみましたが、まだ運がありません。誰にも解決策がありますか?