我在一个依赖多个数据库的项目中使用Spring Data JPA。
在一个数据库(称为ContactDB)中,我们有Contact
通过{{1上的User
与另一个数据库中的userId
绑定(称为UserDB) }}
在UserDB中,Contact
可以包含多个User
个实体。请参阅下面为每个数据库定义的实体类。
Store
实体:
Contact
package com.mycompany.cdb.entity;
@Entity
@Table(name = "CONTACT", schema = "cSchema")
public class Contact {
private Long contactId;
private Long userId;
private String firstNm;
private String lastNm;
//other fields, getters with jpa column definition annotations, setters, etc.
}
实体:
User
每个数据库都有自己的配置类,用于配置package com.mycompany.udb.entity;
@Entity
@Table(name = "USER", schema = "uSchema")
public class User {
private Long userId;
private Collection<Store> stores;
//other fields, getters with jpa column difinition annotations, setters, etc.
}
,TransactionManager
等。
ContactDB配置类有EntityManagerFactory
查找EntityManagerFactory
包中的实体,而UserDB的com.mycompany.cdb.entity
查找EntityManagerFactory
包中的实体。
这一切都设置正确,适用于当前的应用程序。
现在,我正在尝试为使用com.mycompany.udb.entity
进行过滤的PagingAndSortingRepository
实体添加Contact
。
Specification
以下是我已实施的@Repository
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor {
}
示例,该示例将按Specification
和firstNm
进行过滤。
lastNm
我在服务类中使用public class PagingAndSortingContactSpecification {
public static Specification<Contact> findByFirstNameAndLastName(final String firstNm, final String lastNm) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate firstNmPredicate = null;
final Predicate lastNmPredicate = null;
if (!StringUtils.isEmpty(firstNm)) {
firstNmPredicate = cb.like(cb.lower(root.get(Contact_.firstNm), firstNm));
}
if (!StringUtils.isEmpty(lastNm)) {
lastNmPredicate = cb.like(cb.lower(root.get(Contact_.lastNm), lastNm));
}
return cb.and(firstNmPredicate, lastNmPredicate);
}
};
}
}
称之为Specification
。
PagingAndSortingContactRepository
现在,我需要创建一个@Inject
private PagingAndSortingContactRepository pagingAndSortingContactRepository;
public Page<Contact> getContactsByFirstNmLastNm(String firstNm, String lastNm, Pageable pageable) {
return pagingAndSortingContactRepository
.findAll(PagingAndSortingContactSpecification.findByFirstNameAndLastName(firstNm, lastNm),pageable);
}
,根据与其对应的Specification
实体绑定的Contact
个实体过滤掉Store
个实体。
我相信如果User
可以映射到User
实体,但由于它们位于不同的数据库中,这可能是可以实现的,这是不可能的。
那么,是否可以创建一个Contact
来接收商店ID列表,以过滤掉Specification
与Contact
绑定的实体User
Store
1}}与传入的列表对应的实体?
这样的事情:(这不是有效的语法。只是试图帮助演示我想要完成的事情。)
public static Specification<Contact, User> findByStores(final Collection<Long> storeIds) {
return new Specification<Contact, User>() {
@Override
public Predicate toPredicate(Root<Contact, User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.in(root.get(User_.stores), storeIds);
}
};
}