All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.dengchen2020.jpa.base.BaseJpaRepositoryImpl Maven / Gradle / Ivy

There is a newer version: 0.0.28
Show newest version
package io.github.dengchen2020.jpa.base;

import com.querydsl.core.QueryResults;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.EntityPath;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPADeleteClause;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.querydsl.jpa.impl.JPAUpdateClause;
import io.github.dengchen2020.core.querydsl.QueryDslEntityPathResolver;
import io.github.dengchen2020.core.support.model.PageParam;
import io.github.dengchen2020.core.support.model.SimplePage;
import jakarta.persistence.EntityManager;
import org.hibernate.jpa.AvailableHints;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.lang.NonNull;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collections;
import java.util.stream.Stream;

/**
 * BaseJpaRepository的实现
 *
 * @author dengchen
 * @since 2024/1/19
 */
@Transactional(propagation = Propagation.SUPPORTS)
public class BaseJpaRepositoryImpl extends SimpleJpaRepository {

    String QUERY_TIMEOUT = "10000";

    private final EntityManager entityManager;

    private  final JPAQueryFactory queryFactory;

    private final JpaEntityInformation entity;

    public BaseJpaRepositoryImpl(JpaEntityInformation entityInformation, final EntityManager em, final JPAQueryFactory queryFactory) {
        super(entityInformation, em);
        this.entityManager = em;
        this.queryFactory = queryFactory;
        this.entity = entityInformation;
    }

    private EntityPathBase entityPath(Class domainClass){
        return (EntityPathBase) QueryDslEntityPathResolver.INSTANCE.createPath(domainClass);
    }

    public EntityManager entityManager() {
        return entityManager;
    }

    public JPAQueryFactory queryFactory() {
        return queryFactory;
    }

    /**
     * 新增或修改
     *
     * @param entity must not be {@literal null}.
     * @param  S
     * @return S
     */
    @NonNull
    @Override
    public  S save(@NonNull final S entity) {
        try {
            return super.save(entity);
        } catch (Exception e) {
            throw new RuntimeException("数据保存失败,值:" + entity, e);
        }
    }

    @Override
    public void deleteAll() {
        throw new UnsupportedOperationException("不支持无条件的全量删除且该方法效率低下");
    }

    @Override
    public void deleteAllInBatch() {
        throw new UnsupportedOperationException("不支持无条件的全量删除,防止误操作,请自行实现");
    }

    public JPAQuery select(Expression expr) {
        return queryFactory.select(expr).setHint(AvailableHints.HINT_SPEC_QUERY_TIMEOUT, QUERY_TIMEOUT);
    }

    public JPAQuery selectDistinct(Expression expr) {
        return select(expr).distinct();
    }

    public JPAQuery selectDistinct(Expression... exprs) {
        return queryFactory.select(exprs).setHint(AvailableHints.HINT_SPEC_QUERY_TIMEOUT, QUERY_TIMEOUT).distinct();
    }

    public JPAQuery selectOne() {
        return queryFactory.select(Expressions.ONE);
    }

    public JPAQuery selectZero() {
        return queryFactory.select(Expressions.ZERO);
    }

    /**
     * 单表数据查询
     * @param from querydsl查询Q类对象
     * @return JPAQuery
     */
    public JPAQuery selectFrom(EntityPath from) {
        return select(from).from(from).setHint(AvailableHints.HINT_SPEC_QUERY_TIMEOUT, QUERY_TIMEOUT);
    }

    /**
     * 更新构造
     *
     * @param path  要更新数据的表名
     * @param where 更新条件
     * @return JPAUpdateClause
     */
    public JPAUpdateClause update(EntityPath path, Predicate[] where) {
        if (where == null || where.length == 0) throw new RuntimeException("更新必须有条件");
        return queryFactory.update(path).where(where);
    }

    /**
     * 更新构造
     *
     * @param path  要更新数据的表名
     * @param where 更新条件
     * @return JPAUpdateClause
     */
    public JPAUpdateClause update(EntityPath path, Predicate where) {
        return update(path, new Predicate[]{where});
    }

    /**
     * 删除构造
     *
     * @param path  要删除数据的表名
     * @param where 删除条件
     * @return JPADeleteClause
     */
    public JPADeleteClause delete(EntityPath path, Predicate[] where) {
        if (where == null || where.length == 0) throw new RuntimeException("删除必须有条件");
        return queryFactory.delete(path).where(where);
    }

    /**
     * 删除构造
     *
     * @param path  要删除数据的表名
     * @param where 删除条件
     * @return JPADeleteClause
     */
    public JPADeleteClause delete(EntityPath path, Predicate where) {
        return delete(path, new Predicate[]{where});
    }

    /**
     * 统一查询,支持分页
     * @param param 查询参数
     * @return JPAQuery
     */
    public JPAQuery findAllQuery(PageParam param){
        return selectFrom(entityPath(entity.getJavaType()));
    }

    /**
     * Querydsl分页查询
     * @param query JPAQuery
     * @param param 分页参数
     * @param o 排序方式
     * @return SimplePage
     */
    public  SimplePage pageList(JPAQuery query, PageParam param, OrderSpecifier... o){
        if (param.getSize() != null && param.getSize() == 0) return new SimplePage<>(query.fetchCount(), Collections.emptyList());
        if (o != null && o.length > 0) query = query.orderBy(o);
        if (!param.isSelectCount()) {
            return new SimplePage<>(null, query.limit(param.getSize())
                    .offset(param.getOffset())
                    .fetch());
        }
        QueryResults result = query.limit(param.getSize())
                .offset(param.getOffset())
                .fetchResults();
        return new SimplePage<>(result.getTotal(), result.getResults());
    }

    /**
     * Querydsl分页条件查询
     *
     * @param param 分页参数
     * @param o     排序方式
     * @return 分页后的数据
     */
    public SimplePage findAll(Predicate predicate, PageParam param, OrderSpecifier... o){
        return pageList(selectFrom(entityPath(entity.getJavaType())).where(predicate), param, o);
    }

    /**
     * 返回流读取器
     * @param query JPAQuery
     * @param param 查询参数
     * @param o 排序方式
     * @return Stream
     */
    public  Stream streamList(JPAQuery query, PageParam param, OrderSpecifier... o){
        if (o != null && o.length > 0) query = query.orderBy(o);
        if(param == null) return query.stream();
        return query.limit(param.getSize())
                .offset(param.getOffset())
                .stream();
    }

    /**
     * 返回流读取器
     * @param predicate 条件
     * @param param 查询参数
     * @param o 排序方式
     * @return Stream
     */
    public Stream findStream(Predicate predicate, PageParam param, OrderSpecifier... o){
        return streamList(selectFrom(entityPath(entity.getJavaType())).where(predicate), param, o);
    }

    /**
     * 返回流读取器
     * @param param 查询参数
     * @param o 排序方式
     * @return Stream
     */
    public Stream findStream(PageParam param, OrderSpecifier... o){
        return streamList(selectFrom(entityPath(entity.getJavaType())), param, o);
    }

    /**
     * 返回流读取器
     * @param o 排序方式
     * @return Stream
     */
    public Stream findStream(OrderSpecifier... o){
        return streamList(selectFrom(entityPath(entity.getJavaType())), null, o);
    }

}