Product和ProductTag形成一对多关系,如下所示。
@Entity
public class Product {
@Id
Long id;
@OneToMan(mappedBy = "product")
List<ProductTag> productTags;
}
@Entity
public class ProductTag {
@Id
Long id;
String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
Product product;
}
现在,我有一个API,可以搜索产品,然后返回带有标签的产品。每次调用product.getProductTags()
时,Hibernate都会触发一个SQL查询。由于MySQL服务器离应用服务器很远,因此我想缓存product.getProductTags()
调用。我该如何实现?
使用特定查询来获取标签并将其存储在缓存中:
public TagRepository extends JpaRepository<Tag, Long> {
@Cacheable("tagsByProducts")
@Query("Select t from ProductTag t where t.product = ?product")
List<Tag> findByProduct(Product product);
}
[您需要某种方法来退出缓存:由@CacheEvict("tagsByProducts")
]
但是说实话:我怀疑将JPA实体存储在缓存中是个好主意!我认为这将导致许多奇怪的问题。因此,更好的查询方式是仅查询标签名称(或content
),而不查询标签实体。
public TagRepository extends JpaRepository<Tag, Long> {
@Cacheable("tagsByProducts")
@Query("Select t.content from ProductTag t where t.product = ?product")
List<String> findTagContentByProduct(Product product);
}
@Entity
public class Product {
@Id
Long product_id;
@OneToMany(casacade=CascadeType.ALL,
fetch=FetchType.Eager,mappedBy = "product")
@JsonManagedReference(value="product-tag")
List<ProductTag> productTags;
}
@Entity
public class ProductTag {
@Id
Long id;
String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
@JsonBackReference(value="product-tag")
Product product;
}