版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liudongdong19/article/details/84454022
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.data.jpa.repository.support;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.function.Consumer;
import java.util.function.LongSupplier;
import java.util.function.Supplier;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.provider.PersistenceProvider;
import org.springframework.data.jpa.repository.query.QueryUtils;
import org.springframework.data.jpa.repository.support.QueryHints.NoHints;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
@Repository
@Transactional(
readOnly = true
)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!";
private final JpaEntityInformation<T, ?> entityInformation;
private final EntityManager em;
private final PersistenceProvider provider;
@Nullable
private CrudMethodMetadata metadata;
public SimpleJpaRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
Assert.notNull(entityInformation, "JpaEntityInformation must not be null!");
Assert.notNull(entityManager, "EntityManager must not be null!");
this.entityInformation = entityInformation;
this.em = entityManager;
this.provider = PersistenceProvider.fromEntityManager(entityManager);
}
public SimpleJpaRepository(Class<T> domainClass, EntityManager em) {
this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);
}
public void setRepositoryMethodMetadata(CrudMethodMetadata crudMethodMetadata) {
this.metadata = crudMethodMetadata;
}
@Nullable
protected CrudMethodMetadata getRepositoryMethodMetadata() {
return this.metadata;
}
protected Class<T> getDomainClass() {
return this.entityInformation.getJavaType();
}
private String getDeleteAllQueryString() {
return QueryUtils.getQueryString("delete from %s x", this.entityInformation.getEntityName());
}
private String getCountQueryString() {
String countQuery = String.format("select count(%s) from %s x", this.provider.getCountQueryPlaceholder(), "%s");
return QueryUtils.getQueryString(countQuery, this.entityInformation.getEntityName());
}
@Transactional
public void deleteById(ID id) {
Assert.notNull(id, "The given id must not be null!");
this.delete(this.findById(id).orElseThrow(() -> {
return new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!", this.entityInformation.getJavaType(), id), 1);
}));
}
@Transactional
public void delete(T entity) {
Assert.notNull(entity, "The entity must not be null!");
this.em.remove(this.em.contains(entity) ? entity : this.em.merge(entity));
}
@Transactional
public void deleteAll(Iterable<? extends T> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
Iterator var2 = entities.iterator();
while(var2.hasNext()) {
T entity = var2.next();
this.delete(entity);
}
}
@Transactional
public void deleteInBatch(Iterable<T> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
if (entities.iterator().hasNext()) {
QueryUtils.applyAndBind(QueryUtils.getQueryString("delete from %s x", this.entityInformation.getEntityName()), entities, this.em).executeUpdate();
}
}
@Transactional
public void deleteAll() {
Iterator var1 = this.findAll().iterator();
while(var1.hasNext()) {
T element = var1.next();
this.delete(element);
}
}
@Transactional
public void deleteAllInBatch() {
this.em.createQuery(this.getDeleteAllQueryString()).executeUpdate();
}
public Optional<T> findById(ID id) {
Assert.notNull(id, "The given id must not be null!");
Class<T> domainType = this.getDomainClass();
if (this.metadata == null) {
return Optional.ofNullable(this.em.find(domainType, id));
} else {
LockModeType type = this.metadata.getLockModeType();
Map<String, Object> hints = this.getQueryHints().withFetchGraphs(this.em).asMap();
return Optional.ofNullable(type == null ? this.em.find(domainType, id, hints) : this.em.find(domainType, id, type, hints));
}
}
protected QueryHints getQueryHints() {
return (QueryHints)(this.metadata == null ? NoHints.INSTANCE : DefaultQueryHints.of(this.entityInformation, this.metadata));
}
public T getOne(ID id) {
Assert.notNull(id, "The given id must not be null!");
return this.em.getReference(this.getDomainClass(), id);
}
public boolean existsById(ID id) {
Assert.notNull(id, "The given id must not be null!");
if (this.entityInformation.getIdAttribute() == null) {
return this.findById(id).isPresent();
} else {
String placeholder = this.provider.getCountQueryPlaceholder();
String entityName = this.entityInformation.getEntityName();
Iterable<String> idAttributeNames = this.entityInformation.getIdAttributeNames();
String existsQuery = QueryUtils.getExistsQueryString(entityName, placeholder, idAttributeNames);
TypedQuery<Long> query = this.em.createQuery(existsQuery, Long.class);
if (!this.entityInformation.hasCompositeId()) {
query.setParameter((String)idAttributeNames.iterator().next(), id);
return (Long)query.getSingleResult() == 1L;
} else {
Iterator var7 = idAttributeNames.iterator();
while(var7.hasNext()) {
String idAttributeName = (String)var7.next();
Object idAttributeValue = this.entityInformation.getCompositeIdAttributeValue(id, idAttributeName);
boolean complexIdParameterValueDiscovered = idAttributeValue != null && !query.getParameter(idAttributeName).getParameterType().isAssignableFrom(idAttributeValue.getClass());
if (complexIdParameterValueDiscovered) {
return this.findById(id).isPresent();
}
query.setParameter(idAttributeName, idAttributeValue);
}
return (Long)query.getSingleResult() == 1L;
}
}
}
public List<T> findAll() {
return this.getQuery((Specification)null, (Sort)Sort.unsorted()).getResultList();
}
public List<T> findAllById(Iterable<ID> ids) {
Assert.notNull(ids, "The given Iterable of Id's must not be null!");
if (!ids.iterator().hasNext()) {
return Collections.emptyList();
} else if (!this.entityInformation.hasCompositeId()) {
SimpleJpaRepository.ByIdsSpecification<T> specification = new SimpleJpaRepository.ByIdsSpecification(this.entityInformation);
TypedQuery<T> query = this.getQuery(specification, (Sort)Sort.unsorted());
return query.setParameter(specification.parameter, ids).getResultList();
} else {
List<T> results = new ArrayList();
Iterator var3 = ids.iterator();
while(var3.hasNext()) {
ID id = var3.next();
this.findById(id).ifPresent(results::add);
}
return results;
}
}
public List<T> findAll(Sort sort) {
return this.getQuery((Specification)null, (Sort)sort).getResultList();
}
public Page<T> findAll(Pageable pageable) {
return (Page)(isUnpaged(pageable) ? new PageImpl(this.findAll()) : this.findAll((Specification)null, pageable));
}
public Optional<T> findOne(@Nullable Specification<T> spec) {
try {
return Optional.of(this.getQuery(spec, Sort.unsorted()).getSingleResult());
} catch (NoResultException var3) {
return Optional.empty();
}
}
public List<T> findAll(@Nullable Specification<T> spec) {
return this.getQuery(spec, Sort.unsorted()).getResultList();
}
public Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable) {
TypedQuery<T> query = this.getQuery(spec, pageable);
return (Page)(isUnpaged(pageable) ? new PageImpl(query.getResultList()) : this.readPage(query, this.getDomainClass(), pageable, spec));
}
public List<T> findAll(@Nullable Specification<T> spec, Sort sort) {
return this.getQuery(spec, sort).getResultList();
}
public <S extends T> Optional<S> findOne(Example<S> example) {
try {
return Optional.of(this.getQuery(new SimpleJpaRepository.ExampleSpecification(example), example.getProbeType(), (Sort)Sort.unsorted()).getSingleResult());
} catch (NoResultException var3) {
return Optional.empty();
}
}
public <S extends T> long count(Example<S> example) {
return executeCountQuery(this.getCountQuery(new SimpleJpaRepository.ExampleSpecification(example), example.getProbeType()));
}
public <S extends T> boolean exists(Example<S> example) {
return !this.getQuery(new SimpleJpaRepository.ExampleSpecification(example), example.getProbeType(), (Sort)Sort.unsorted()).getResultList().isEmpty();
}
public <S extends T> List<S> findAll(Example<S> example) {
return this.getQuery(new SimpleJpaRepository.ExampleSpecification(example), example.getProbeType(), (Sort)Sort.unsorted()).getResultList();
}
public <S extends T> List<S> findAll(Example<S> example, Sort sort) {
return this.getQuery(new SimpleJpaRepository.ExampleSpecification(example), example.getProbeType(), (Sort)sort).getResultList();
}
public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) {
SimpleJpaRepository.ExampleSpecification<S> spec = new SimpleJpaRepository.ExampleSpecification(example);
Class<S> probeType = example.getProbeType();
TypedQuery<S> query = this.getQuery(new SimpleJpaRepository.ExampleSpecification(example), probeType, (Pageable)pageable);
return (Page)(isUnpaged(pageable) ? new PageImpl(query.getResultList()) : this.readPage(query, probeType, pageable, spec));
}
public long count() {
return (Long)this.em.createQuery(this.getCountQueryString(), Long.class).getSingleResult();
}
public long count(@Nullable Specification<T> spec) {
return executeCountQuery(this.getCountQuery(spec, this.getDomainClass()));
}
@Transactional
public <S extends T> S save(S entity) {
if (this.entityInformation.isNew(entity)) {
this.em.persist(entity);
return entity;
} else {
return this.em.merge(entity);
}
}
@Transactional
public <S extends T> S saveAndFlush(S entity) {
S result = this.save(entity);
this.flush();
return result;
}
@Transactional
public <S extends T> List<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
List<S> result = new ArrayList();
Iterator var3 = entities.iterator();
while(var3.hasNext()) {
S entity = var3.next();
result.add(this.save(entity));
}
return result;
}
@Transactional
public void flush() {
this.em.flush();
}
/** @deprecated */
@Deprecated
protected Page<T> readPage(TypedQuery<T> query, Pageable pageable, @Nullable Specification<T> spec) {
return this.readPage(query, this.getDomainClass(), pageable, spec);
}
protected <S extends T> Page<S> readPage(TypedQuery<S> query, Class<S> domainClass, Pageable pageable, @Nullable Specification<S> spec) {
if (pageable.isPaged()) {
query.setFirstResult((int)pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
}
return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> {
return executeCountQuery(this.getCountQuery(spec, domainClass));
});
}
protected TypedQuery<T> getQuery(@Nullable Specification<T> spec, Pageable pageable) {
Sort sort = pageable.isPaged() ? pageable.getSort() : Sort.unsorted();
return this.getQuery(spec, this.getDomainClass(), sort);
}
protected <S extends T> TypedQuery<S> getQuery(@Nullable Specification<S> spec, Class<S> domainClass, Pageable pageable) {
Sort sort = pageable.isPaged() ? pageable.getSort() : Sort.unsorted();
return this.getQuery(spec, domainClass, sort);
}
protected TypedQuery<T> getQuery(@Nullable Specification<T> spec, Sort sort) {
return this.getQuery(spec, this.getDomainClass(), sort);
}
protected <S extends T> TypedQuery<S> getQuery(@Nullable Specification<S> spec, Class<S> domainClass, Sort sort) {
CriteriaBuilder builder = this.em.getCriteriaBuilder();
CriteriaQuery<S> query = builder.createQuery(domainClass);
Root<S> root = this.applySpecificationToCriteria(spec, domainClass, query);
query.select(root);
if (sort.isSorted()) {
query.orderBy(QueryUtils.toOrders(sort, root, builder));
}
return this.applyRepositoryMethodMetadata(this.em.createQuery(query));
}
/** @deprecated */
@Deprecated
protected TypedQuery<Long> getCountQuery(@Nullable Specification<T> spec) {
return this.getCountQuery(spec, this.getDomainClass());
}
protected <S extends T> TypedQuery<Long> getCountQuery(@Nullable Specification<S> spec, Class<S> domainClass) {
CriteriaBuilder builder = this.em.getCriteriaBuilder();
CriteriaQuery<Long> query = builder.createQuery(Long.class);
Root<S> root = this.applySpecificationToCriteria(spec, domainClass, query);
if (query.isDistinct()) {
query.select(builder.countDistinct(root));
} else {
query.select(builder.count(root));
}
query.orderBy(Collections.emptyList());
return this.em.createQuery(query);
}
private <S, U extends T> Root<U> applySpecificationToCriteria(@Nullable Specification<U> spec, Class<U> domainClass, CriteriaQuery<S> query) {
Assert.notNull(domainClass, "Domain class must not be null!");
Assert.notNull(query, "CriteriaQuery must not be null!");
Root<U> root = query.from(domainClass);
if (spec == null) {
return root;
} else {
CriteriaBuilder builder = this.em.getCriteriaBuilder();
Predicate predicate = spec.toPredicate(root, query, builder);
if (predicate != null) {
query.where(predicate);
}
return root;
}
}
private <S> TypedQuery<S> applyRepositoryMethodMetadata(TypedQuery<S> query) {
if (this.metadata == null) {
return query;
} else {
LockModeType type = this.metadata.getLockModeType();
TypedQuery<S> toReturn = type == null ? query : query.setLockMode(type);
this.applyQueryHints(toReturn);
return toReturn;
}
}
private void applyQueryHints(Query query) {
Iterator var2 = this.getQueryHints().withFetchGraphs(this.em).iterator();
while(var2.hasNext()) {
Entry<String, Object> hint = (Entry)var2.next();
query.setHint((String)hint.getKey(), hint.getValue());
}
}
private static long executeCountQuery(TypedQuery<Long> query) {
Assert.notNull(query, "TypedQuery must not be null!");
List<Long> totals = query.getResultList();
long total = 0L;
Long element;
for(Iterator var4 = totals.iterator(); var4.hasNext(); total += element == null ? 0L : element) {
element = (Long)var4.next();
}
return total;
}
private static boolean isUnpaged(Pageable pageable) {
return pageable.isUnpaged();
}
private static class ExampleSpecification<T> implements Specification<T> {
private static final long serialVersionUID = 1L;
private final Example<T> example;
ExampleSpecification(Example<T> example) {
Assert.notNull(example, "Example must not be null!");
this.example = example;
}
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return QueryByExamplePredicateBuilder.getPredicate(root, cb, this.example);
}
}
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(new Expression[]{this.parameter});
}
}
}