我有服务
@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
方法。这行得通。但是这种解决方案是不好的。我认为。因为我写了用于配置文件检查的硬代码。我的存储库有两种用于不同数据库的方法。
如何正确实施?
答案 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。