如何在GraphQL一对一关系中按productTypeId查询Product
问题描述
希望实现通过productTypeId查询Product的功能,Product与ProductType为一对一关系。目前已实现查询全部Product或通过productId查询单个Product,但无法通过关联字段productTypeId进行查询,以下是当前的代码实现:
GraphQL Schema
type Query { products:[Product] (work) productById(productId:Int):Product(work) productByTypeId(productTypeId:Int):Product(not work) } type Product{ productId: ID!, productName: String, productCode:String, unitInStock: Float, unitPrice:Float, orderLevel:Int, discount: Float, imageUrl: String, backgroundImgUrl: String, productType: ProductType productCategory:Category } type ProductType{ productTypeId:ID! productTypeName:String, imageUrl: String, backgroundImageUrl:String } type Category{ categoryId:ID! categoryName:String, categoryCode:String, imageUrl: String, backgroundImageUrl:String }
Controller层
@QueryMapping public List<Product> productByTypeId(@Argument Integer productTypeId) { return productRepo.findByTypeId(productTypeId); }
Repository层
Page<Product> findByTypeId(@Param("productTypeId") Integer productTypeId, Pageable pageable); @Query(value = "select p.* from pos_product p where product_type__id =:productTypeId", nativeQuery = true)
解决方案
1. 修正GraphQL Schema定义
当前productByTypeId返回单个Product,但即使是一对一关系,建议返回列表以兼容后续可能的业务变化,同时修正语法格式:
type Query { products:[Product] # 正常工作 productById(productId:Int):Product # 正常工作 productByTypeId(productTypeId:Int):[Product] # 修改返回类型为列表 }
2. 修正Repository层实现
现有Repository存在返回类型与Controller不匹配、参数缺失的问题,可选择以下两种方式修复:
方式一:使用Spring Data JPA方法命名查询(推荐)
利用JPA的方法命名规则,直接通过关联对象的属性查询,无需编写原生SQL:
// 通过Product关联的productType对象的productTypeId属性查询 List<Product> findByProductTypeProductTypeId(Integer productTypeId);
方式二:修正原生SQL查询
如果坚持使用原生SQL,需统一返回类型和参数:
@Query(value = "select p.* from pos_product p where product_type__id = :productTypeId", nativeQuery = true) List<Product> findByTypeId(@Param("productTypeId") Integer productTypeId);
注意:确认数据库中
Product表的关联字段确实为product_type__id,如果是常规下划线分隔的product_type_id,需同步修改SQL中的字段名。
3. 同步修正Controller层调用
确保Controller调用的Repository方法与修正后的定义一致:
@QueryMapping public List<Product> productByTypeId(@Argument Integer productTypeId) { // 对应方式一的方法 return productRepo.findByProductTypeProductTypeId(productTypeId); // 若用方式二,替换为:return productRepo.findByTypeId(productTypeId); }
额外检查点
- 确认
Product实体类中正确映射了与ProductType的一对一关联:
@OneToOne @JoinColumn(name = "product_type_id") // 此处name需与数据库字段名一致 private ProductType productType;
- 若严格遵循一对一关系,需确保数据库中
product_type_id字段设置了唯一约束,避免一个ProductType对应多个Product。
内容的提问来源于stack exchange,提问作者BOOM
相关产品推荐
相关产品推荐

