当前位置: 首页 > 知识库问答 >
问题:

在Spring数据JPA存储库中使用泛型

严劲
2023-03-14
import org.springframework.data.jpa.repository.JpaRepository;

public interface FacilityRepository extends JpaRepository<Facility, Long> {
}


public interface FacilityService {
    public Facility create(Facility facility);
}

@Service
public class FacilityServiceImpl implements FacilityService {

    @Resource
    private FacilityRepository countryRepository;

    @Transactional
    public Facility create(Facility facility) {
        Facility created = facility;
        return facilityRepository.save(created);
    }
}

我突然想到,可以用三个基于泛型的类来替换每个对象类型的多个类,从而节省大量的样板代码。我不是很清楚该怎么做,事实上这是不是一个好主意?

共有1个答案

郎长卿
2023-03-14

首先,我知道我们在这里提高了一些标准,但这已经比您在没有Spring Data JPA的帮助下编写的代码要少得多了。

其次,我认为您首先不需要服务类,如果您所做的只是将一个调用转发到存储库。如果您的业务逻辑需要在事务中编排不同的存储库,或者有其他业务逻辑要封装,我们建议您在存储库前面使用服务。

一般来说,你当然可以做这样的事情:

interface ProductRepository<T extends Product> extends CrudRepository<T, Long> {

    @Query("select p from #{#entityName} p where ?1 member of p.categories")
    Iterable<T> findByCategory(String category);

    Iterable<T> findByName(String name);
}
class MyClient {

  @Autowired
  public MyClient(ProductRepository<Car> carRepository, 
                  ProductRepository<Wine> wineRepository) { … }
}

并且它会像预期的那样工作。然而,有几件事需要注意:

这只有在域类使用单表继承时才起作用。我们在引导时能够获得的关于domain类的唯一信息是它将是product对象。因此,对于findAll()甚至findByName(…)这样的方法,相关的查询将以select p from Product p where…开始。这是因为反射查找永远不能生成wincar,除非您为它创建一个专用的存储库接口来捕获具体的类型信息。

一般来说,我们建议为每个聚合根创建存储库接口。这意味着并不是每个域类本身都有回购。更重要的是,在存储库上对服务进行1:1的抽象也完全失去了意义。如果您构建服务,并不是为每个存储库都构建一个服务(猴子可以这样做,我们不是猴子,是吗?)。一个服务公开了一个更高级别的API,是更多的用例驱动程序,并且通常协调对多个存储库的调用。

 类似资料:
  • 问题内容: 我有许多需要保留到数据库的简单对象类型。我正在使用Spring JPA来管理这种持久性。对于每种对象类型,我需要构建以下内容: 在我看来,有可能用三个基于泛型的类替换每种对象类型的多个类,从而节省了大量的样板代码。我不确定该怎么做,实际上,如果这是个好主意? 问题答案: 首先,我知道我们在这里提高了一些标准,但这已经比没有Spring Data JPA的帮助而编写的代码少得多。 其次,

  • 它是否将其存储在缓存中?我有一个应用程序,但应用程序中没有任何地方。属性是提到的db详细信息。我可以通过邮递员存储数据和查询它。

  • 是否有一种方法可以使通用Spring数据JPA存储库正确处理类似的方法?例如只返回狗,而不返回所有动物?或者至少,最好的变通方法是什么? 它的工作几乎完美,保存每一个动物在自己的桌子上,等等。唯一的问题是:同时返回水豚和狗。这个答案解释说: 这只有在域类使用单表继承时才起作用。我们在引导时能得到的关于domain类的唯一信息是它将是Product对象。因此,对于像findAll()甚至findBy

  • 问题内容: Spring Boot入门级 控制器类 实体 数据jpa存储库接口 服务等级 gradle文件 我收到以下错误 如果我从中删除注释,它将抛出`NullPointerException 我在这里尝试过 问题答案: 您的Spring配置不正确。 在已经提供了依赖。当您使用特定版本声明它时: 您不必再次声明它,因为您指定的版本可能不同,并且与启动程序提供的版本不兼容。 并且根据您的错误,似乎

  • 我想知道是否可以使用Spring数据JPA调用存储过程,它具有resultset和multiple out参数。 我发现了相同https://github.com/spring-projects/spring-data-examples/issues/80的Git问题 如果问题解决了,有人能举一个Spring Boot的例子吗?