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

Spring Boot-如何创建不同JpaRepository接口的工厂

邢俊悟
2023-03-14

我有一个服务层,可以像这样自动连接存储库

@Service
public class OrderService {

    @Autowired
    private OrderRepository repository;

    public List<Order> retrieveOrders(String storeId) {
        try {

            return repository.getOrders(storeId)

        } catch(Exception e) {
            ...
        }
    }
}

我有了新的要求,根据商店的数量,存储库查询逻辑应该改变。我正在考虑抽象我的存储库并使用工厂模式。当前存储库是一个接口,并扩展了JpaRepository此外,它的所有函数都使用@Query注释来定义JPQL。这是一个只有一个函数的例子,但是在我的实际存储库中有几个函数

public interface OrderRepository extends JpaRepository {

    @Query("select o " +
        " from Orders o " +
        " where o.storeId = :storeId")
    public List<Order> getOrders(@Param(value = "storeId") String storeId);

}

新要求指出,对于特定的 storeId,SQL 需要更改为如下所示的内容:

public interface OrderRepositoryStore886 extends JpaRepository {

    @Query("select o " +
        " from Order o " +
        " where o.storeId = :storeId " +
        "     and o.status IN (1,3,10,15) " +
        "     and EXISTS (SELECT c from CollabOrder WHERE c.orderId = o.orderId)")
    public List<Order> getOrders(@Param(value = "storeId") String storeId);

}

但是,所有剩余的存储都应该使用第一个SQL查询。

我正在尝试弄清楚如何根据 storeId 有条件地@Autowire存储库。我正在考虑创建一个工厂,但我不知道如何创建一个返回接口对象的工厂(我对 java 仍然相当陌生,这可能微不足道,但我还没有弄清楚)。如果我尝试将存储库接口转换为类,它会迫使我覆盖所有抽象的 JpaRepository 方法,这是不必要的额外代码。

共有1个答案

云胤
2023-03-14

你已经走上正轨了。我会解决这个问题,但是创建一个返回正确bean接口的工厂方法。

这种方法的唯一缺点是你不能自动连接你的豆子。您应该即时实例化它们。

create table orders
(
  id                      integer      not null,
  constraint pk_orders primary key(id)
);

@Entity
@Table(name = "orders")
@ToString
@Getter
@Setter
public class Order {

    @Id
    private long id;
}


public interface OrderRepository extends JpaRepository<Order, Long> {
    @Query("SELECT t FROM Order t")
    Order getOrder(String storeId);
}


@Repository
public interface OrderRepositoryStore100 extends OrderRepository {
    @Query("SELECT t FROM Order t WHERE t.id = 100")
    Order getOrder(@Param(value = "id") String storeId);
}

@Repository
public interface OrderRepositoryStore286 extends OrderRepository {
    @Query("SELECT t FROM Order t WHERE t.id = 286")
    Order getOrder(@Param(value = "id") String storeId);
}

public class OrderRepositoryStoreFactory {

    private static final String REPOSITORY_BASE_NAME = "orderRepositoryStore";

    public static OrderRepository getRepository(ApplicationContext context, String storeId) {

        return (OrderRepository) context.getBean(REPOSITORY_BASE_NAME + storeId);
    }
}

@Service
public class OrderService {

    @Autowired
    private ApplicationContext context;

    public Order retrieveOrders(String storeId) {
        try {

            OrderRepository repository = OrderRepositoryStoreFactory.getRepository(context, storeId);

            return repository.getOrder(storeId);

        } catch(Exception e) {
            return null;
        }
    }
}



@SpringBootApplication
public class FactoryApplication implements CommandLineRunner {

    @Autowired
    private ApplicationContext context;

    @Autowired
    private OrderService orderService;

    public static void main(String[] args) {
        SpringApplication.run(FactoryApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Order order = orderService.retrieveOrders("100");
        System.out.println(order);

        order = orderService.retrieveOrders("286");
        System.out.println(order);
    }
}

下面是输出:

2020-05-03 20:23:34.567 信息 33955 --- [ main] com.factory.FactoryApplication : 在 3.003 秒内启动工厂应用程序(JVM 运行为 3.615) 订单(id=100) 订单(id=286)

希望这有帮助

 类似资料:
  • 即使我的接口MonRepo(扩展JpaRepository)没有注释任何注释,告诉spring为这个类创建一个bean(例如。服务、控制器、组件等)。如何创建此类的 Bean。我确信创建了一个 bean,因为我在另一个类中自动连接了 monRepo,并且它工作得很好。 MonRepo公司 其中 monRepo 自动连线的类 除了我的类,我没有在任何地方使用过enableJpaRepository注

  • 我用@query创建了UsersRepository 我得到错误,我可以在没有@query的情况下这样做吗?我可以用@onetomany做这个吗?如何在Jpa OneTomany上实现select?我想得到没有帖子的所有用户。

  • 把大象装进冰箱分几步?三步:把冰箱门打开,把大象装进去,关门,搞定~ 新建接口分几步?也是三步: 获取权限 找到一个项目 新建接口 搞定~ 获取权限 新用户登录拥有 个人空间 分组下的全部权限,个人空间分组仅自己可见,因此可以在这里任意试用 YApi 的功能。 除此以外没有任何项目或分组的权限,只能浏览已存在分组下面的公开项目。 如果找不到想找的项目,可能是尚未成为项目成员,此时应联系 项目组长

  • 泛型可译: 可翻译的: 我需要获取的实例,但我不能: 那么,如何创建实例并填充ths接口的teh相关属性呢?因为我需要在测试方法中给出这个实例作为返回值:

  • 如何通过Xml配置连接JpaRepository的a(子类/子接口)? 所以我有一个JpaRepository的“实现” 和实体 和一个我需要注入MyDepartmentJpaRepo的类 以及“管理器”的界面,以确保完整性。 问题出在应用程序上下文.xml。 所以……spring-boot-data让人们将(子接口JpaRepository)定义为一个INTERFACE 因此,当您尝试用xml定

  • 我尝试了很多事情 be.fgov.minfin.virtualprinter.model.StatusMap中的字段statusDescriptionDao需要一个类型为