[英]how to set unidirectional one-to-one relationship using hibernate annotation on a non-primary key?
[英]Spring Hibernate Query One to One relationship with non primary key
我正在使用 Hibernate 在 Spring 上開發 Web 應用程序。
此 Web 應用程序基本上是一個在線商業網站,其中包含特定類別下的許多產品。
本應用支持一個產品多種語言,單個產品圖片支持不同尺寸的圖片,以便根據不同的用戶設備進行優化。 因此,用戶可以根據自己的設備類型(例如移動設備、iPad、桌面設備)選擇他們希望使用的語言來查看產品描述,並會獲得不同尺寸的產品圖像。
所以,我現在有六個表,如下所示。
產品表包含如圖所示的產品
product_info 表包含不同語言的產品(如英語、西班牙語和韓語)的相同描述,如下圖所示。
product_image 包含產品相同圖片的不同尺寸圖像的相對路徑,如下圖所示。
假設用戶請求 category_id = 1(家具)、support_language_id = 1(英語)和 device_type_id = 1(移動)下的產品列表。 然后,我想查詢如下內容,但使用 HQL。
Select * from product pr
left join product_info pf
on p.id = pf.product_id
left join product_image pi
on p.id = pi.product_id
where category_id = category_id of user choice
and support_language_id = support_language_id of user choice
and device_type_id = device_type_id of user device
當我執行這個 HQL 查詢時,我希望得到一個產品對象列表,每個產品對象只有一個 product_info 對象和一個 product_image 對象,基於用戶選擇的 category_id、support_language_id 和 device_type_id。
按照上面的例子,我將得到一個 id = 1 的產品對象,因為只有一個 category_id = 1 的對象。然后,products 對象將有 id = 1 的 product_info 對象和 id = 1 的 product_image 對象。
如何使用 Hibernate 在 JPA 中實現這種關系?
我已經嘗試過這種方式,但最終會出現錯誤,例如與非主鍵或其他鍵綁定。 所以我首先想知道我的數據庫設計是否存在結構問題。
你們能給我提供一個完整的工作代碼示例,其中包含所有這些 JPA 注釋,例如 @JoinColumn、@OneToMany、@OneToOne 等等,好嗎?
只要可以獲得所需的結果,您就可以更改、添加和刪除列或表。
這里有一個不使用注解,只使用hql的解決方案,不知道能不能滿足你。
select p from Product p,ProductInfo pf,ProductImage pi where p.id = pf.productId and p.id = pi.productId and...
很簡單,假設您沒有 10 年前的 JPA 版本,那么您可以創建兩個接口(在本例中為存儲庫)並按照 JPA 命名約定命名方法。 這意味着,如果您定義了一個 ProductInfo 類:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "product_info_id")
private long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
private Product product;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "language_id")
private Language language;
private String description;
}
這將是您需要的相應 Repository 方法,是的,如果您想讓它干凈和簡單,您將需要傳遞整個產品。
@Repository
public interface ProductImageRepository extends JpaRepository<ProductImage, Long> {
public Optional<ProductImage> findByProductAndDevice(Product product, Device device);
}
ProductImage 也是如此
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductImage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "product_image_id")
private long id;
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "device_id")
private Device device;
private String image;
}
誰的存儲庫方法將是
@Repository
public interface ProductImageRepository extends JpaRepository<ProductImage, Long> {
public Optional<ProductImage> findByProductAndDevice(Product product, Device device);
}
然后你會想要一些包含產品信息的東西
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductToDisplay {
private Product product;
private String description;
private String imageLocation;
}
然后根據您擁有的信息創建該對象的服務
@Service
public class ProductToDisplayService {
@Autowired
private ProductInfoRepository productInfoRepository;
@Autowired
private ProductImageRepository productImageRepository;
@Autowired
private ProductRepository productRepository;
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private LanguageRepository languageRepository;
public ProductToDisplay getProduct(long productID, long languageID, long deviceID) throws Exception {
Product product =
productRepository.findById(productID).orElseThrow(()-> new Exception(
"There is no such product"));
return new ProductToDisplay(product,
productInfoRepository.findByProductAndLanguage(product,
languageRepository.findById(languageID).orElseThrow(()-> new Exception(
"There is no such product"))).orElseThrow(()-> new Exception(
"There is no such product info")).getDescription(),
productImageRepository.findByProductAndDevice(product,
deviceRepository.findById(deviceID).orElseThrow(()-> new Exception(
"There is no such product"))).orElseThrow(()-> new Exception(
"There is no such product Image")).getImage());
}
}
這可能看起來有點令人困惑,對此我很抱歉,但這更清楚一點
public ProductToDisplay getProductClear(long productID, long languageID,
long deviceID) throws Exception {
Product product =
productRepository.findById(productID).orElseThrow(()-> new Exception(
"There is no such product"));
Language language = languageRepository.findById(languageID).orElseThrow(()-> new Exception(
"There is no such language"));
ProductInfo prodInfo = productInfoRepository.findByProductAndLanguage(product, language)
.orElseThrow(()-> new Exception(
"There is no such product info"));
Device device = deviceRepository.findById(deviceID).orElseThrow(()-> new Exception(
"There is no such image"));
ProductImage prodImg = productImageRepository.findByProductAndDevice(product, device)
.orElseThrow(()-> new Exception(
"There is no such product Image"));
return new ProductToDisplay(product,
prodInfo.getDescription(), prodImg.getImage());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.