Customize base repository implementation

pull/98/head
johnniang 2019-02-20 00:51:31 +08:00
parent 180bfc06b4
commit 385306ffd9
2 changed files with 94 additions and 0 deletions

View File

@ -1,11 +1,13 @@
package cc.ryanc.halo; package cc.ryanc.halo;
import cc.ryanc.halo.repository.base.BaseRepositoryImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/** /**
* <pre> * <pre>
@ -19,6 +21,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication @SpringBootApplication
@EnableCaching @EnableCaching
@EnableJpaAuditing @EnableJpaAuditing
@EnableJpaRepositories(basePackages = "cc.ryanc.halo.repository", repositoryBaseClass = BaseRepositoryImpl.class)
public class Application { public class Application {
public static void main(String[] args) { public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class, args); ApplicationContext context = SpringApplication.run(Application.class, args);

View File

@ -0,0 +1,91 @@
package cc.ryanc.halo.repository.base;
import cc.ryanc.halo.logging.Logger;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Implementation of base repository.
*
* @param <DOMAIN> domain type
* @param <ID> id type
*/
public class BaseRepositoryImpl<DOMAIN, ID> extends SimpleJpaRepository<DOMAIN, ID> implements BaseRepository<DOMAIN, ID> {
private final Logger log = Logger.getLogger(getClass());
private final JpaEntityInformation<DOMAIN, ID> entityInformation;
private final EntityManager entityManager;
public BaseRepositoryImpl(JpaEntityInformation<DOMAIN, ID> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityInformation = entityInformation;
this.entityManager = entityManager;
}
@Override
public List<DOMAIN> findAllByIdIn(Iterable<ID> ids, Sort sort) {
Assert.notNull(ids, "The given Iterable of Id's must not be null!");
log.debug("Customized findAllById method was invoked");
if (!ids.iterator().hasNext()) {
return Collections.emptyList();
}
if (!this.entityInformation.hasCompositeId()) {
ByIdsSpecification<DOMAIN> specification = new ByIdsSpecification<>(this.entityInformation);
TypedQuery<DOMAIN> query = super.getQuery(specification, sort);
return query.setParameter(specification.parameter, ids).getResultList();
} else {
List<DOMAIN> results = new ArrayList<>();
ids.forEach(id -> super.findById(id).ifPresent(results::add));
return results;
}
}
@Override
public long deleteByIdIn(Iterable<ID> ids) {
log.debug("Customized deleteByIdIn method was invoked");
// Find all domains
List<DOMAIN> domains = findAllById(ids);
// Delete in batch
deleteInBatch(domains);
// Return the size of domain deleted
return domains.size();
}
private static final class ByIdsSpecification<T> implements Specification<T> {
private static final long serialVersionUID = 1L;
private final JpaEntityInformation<T, ?> entityInformation;
@Nullable
ParameterExpression<Iterable> parameter;
ByIdsSpecification(JpaEntityInformation<T, ?> entityInformation) {
this.entityInformation = entityInformation;
}
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Path<?> path = root.get(this.entityInformation.getIdAttribute());
this.parameter = cb.parameter(Iterable.class);
return path.in(this.parameter);
}
}
}