Spring Data JPA +本机查询-根据配置文件替换查询字符串

时间:2018-10-05 09:36:39

标签: spring spring-data-jpa spring-data spring-repositories

我有服务

@Service
public class MessageServiceImpl implements MessageService {

    private final MessageRepository smevMessageRepository;
    private final Environment environment;

    public MessageServiceImpl(MessageRepository messageRepository, Environment environment) {
        this.messageRepository= messageRepository;
        this.environment = environment;
    }

    @Override
    public List<Message> findReadyToSend() {
        if (environment.acceptsProfiles("postgre")) {
            return messageRepository.findReadyToSendPostgre();
        }
        return messageRepository.findReadyToSendOracle();
    } 

这是我的资料库:

@Repository
public interface MessageRepository extends JpaRepository<Message, String> {

    @Query(value = "select sm.* from MESSAGES sm ...", nativeQuery = true)
    List<Message> findReadyToSendOracle();

    @Query(value = "select sm.* from MESSAGES sm ...", nativeQuery = true)
    List<Message> findReadyToSendPostgre();

如果我使用oracle profile启动spring boot服务器,我会调用findReadyToSendOracle方法,如果是postgre profile-findReadyToSendPostgre方法。这行得通。但是这种解决方案是不好的。我认为。因为我写了用于配置文件检查的硬代码。我的存储库有两种用于不同数据库的方法。

如何正确实施?

1 个答案:

答案 0 :(得分:0)

在适应JPQL时面临的问题是什么?使用本机/自定义功能?看起来似乎太困难了,但是您可能会发现使用JPA 2.1+中的条件+函数 function 的方法,请看this article

另一方面,我在这里发现了我的旧解决方法可能会有所帮助。有一种简单的解决方法,可以使用带有@Profile批注的一些快捷方式和一些其他接口。

如果您为扩展JpaRepository的本机查询方法提供接口,例如:

@NoRepositoryBean
public interface MessageRepository extends JpaRepository<Message, String>{

    List<Message> findByReady();

}

注意@NoRepositoryBean,避免使用概要文件专门化来重复豆。

然后,仅根据您的需要提供实现:

@Repository
@Profile("oracle")
public interface MessageOracleRepository extends MessageRepository {

    @Query(value = "select m.* from Message m where m.ready = false", nativeQuery = true)
    List<Message> findByReady();

}

...和...

@Repository
@Profile("mysql")
public interface MessageMySQLRepository extends MessageRepository {

    @Query(value = "select m.* from Message m where m.ready = true", nativeQuery = true)
    List<Message> findByReady();

}

现在,您只需要提供所需的配置文件,注入并使用正确的本机查询即可。

如您所见,为简单起见,我简化了查询。用修改后的代码看一下这个repository