All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.kasinf.framework.rest.repository.BaseRepositoryImpl Maven / Gradle / Ivy
package com.kasinf.framework.rest.repository;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import com.kasinf.framework.rest.eneity.AbstractEntity;
import com.kasinf.framework.rest.repository.callback.SearchCallback;
import com.kasinf.framework.rest.eneity.type.LogicDeletable;
import com.kasinf.framework.rest.support.Searchable;
import lombok.Setter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.util.Assert;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.io.Serializable;
import java.util.*;
/**
* 基础存储库实现
*
* @author lkhsh
*/
@Setter
public class BaseRepositoryImpl extends SimpleJpaRepository implements BaseRepository {
private static final String LOGIC_DELETE_ALL_QUERY_STRING = "update %s x set x.isDelete=true where x in ?1";
private static final String DELETE_ALL_QUERY_STRING = "delete from %s x where x in ?1";
private static final String FIND_QUERY_STRING = "select x from %s x where 1=1 ";
private static final String COUNT_QUERY_STRING = "select count(x) from %s x where 1=1 ";
protected final EntityManager em;
protected final Class entityClass;
protected final JpaEntityInformation entityInformation;
protected final String entityName;
protected final String idName;
private String findAllQL;
private String countAllQL;
private SearchCallback searchCallback = SearchCallback.DEFAULT;
public BaseRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.em = entityManager;
this.entityInformation = entityInformation;
this.entityClass = entityInformation.getJavaType();
this.entityName = entityInformation.getEntityName();
this.idName = entityInformation.getIdAttributeNames().iterator().next();
findAllQL = String.format(FIND_QUERY_STRING, entityName);
countAllQL = String.format(COUNT_QUERY_STRING, entityName);
}
/////////////////////////////////////////////////
////////覆盖默认spring data jpa的实现////////////
/////////////////////////////////////////////////
/**
* 删除对应实体,需要考虑是否是逻辑删除
*
* @param t 要删除的实体
*/
@Override
@Transactional(rollbackOn = Exception.class)
public void delete(T t) {
Assert.notNull(t, "Entity must not be null!");
if (t instanceof LogicDeletable) {
((LogicDeletable) t).markDeleted();
save(t);
} else {
super.delete(t);
}
}
/**
* 通过ID删除对象,添加逻辑删除的考虑
*
* @param id 对象ID
*/
@Override
@Transactional(rollbackOn = Exception.class)
public void deleteById(ID id) {
T t = super.getOne(id);
delete(t);
}
/**
* 删除指定对象列表,考虑对逻辑删除实体的操作
*
* @param entities 对象列表
*/
@Override
@Transactional(rollbackOn = Exception.class)
public void deleteInBatch(Iterable entities) {
Iterator iter = entities.iterator();
if (iter.hasNext()) {
Set models = new HashSet<>();
iter.forEachRemaining(models::add);
String ql = LogicDeletable.class.isAssignableFrom(this.entityClass) ?
String.format(LOGIC_DELETE_ALL_QUERY_STRING, entityName) :
String.format(DELETE_ALL_QUERY_STRING, entityName);
Query query = em.createQuery(ql);
setParameters(query, models);
query.executeUpdate();
}
}
/**
* 删除全部,考虑逻辑删除,若要清空逻辑对象表的数据,需要在接口覆盖此方法
*/
@Override
@Transactional(rollbackOn = Exception.class)
public void deleteAll() {
String ql = LogicDeletable.class.isAssignableFrom(this.entityClass) ?
String.format(LOGIC_DELETE_ALL_QUERY_STRING.replace("where x in ?1", ""), entityName) :
String.format(DELETE_ALL_QUERY_STRING.replace("where x in ?1", ""), entityName);
Query query = em.createQuery(ql);
query.executeUpdate();
}
@Override
public boolean existsById(ID id) {
return findById(id).isPresent();
}
/////////////////////////////////////////////////
///////////////////自定义实现////////////////////
/////////////////////////////////////////////////
@Override
public T findOne(ID id) {
Optional t = findById(id);
return t.orElse(null);
}
/**
* 通过指定的ID数组删除对象,考虑对逻辑删除的处理
*
* @param ids 要删除的id数组
*/
@Override
@Transactional(rollbackOn = Exception.class)
public void deleteInBatch(ID[] ids) {
if (ArrayUtil.isNotEmpty(ids)) {
Set models = new HashSet<>(ids.length);
for (ID id : ids) {
T model;
try {
model = entityClass.newInstance();
} catch (Exception e) {
throw new RuntimeException("batch delete " + entityClass + " exception", e);
}
try {
ReflectUtil.setFieldValue(model, idName, id);
} catch (Exception e) {
throw new RuntimeException("batch delete " + entityClass + " exception, can not set id", e);
}
models.add(model);
}
deleteInBatch(models);
}
}
@Override
public Page findAll(Searchable searchable) {
List list = this.findAll(findAllQL, searchable, searchCallback);
long total = searchable.hasPageable() ? count(searchable) : list.size();
return new PageImpl(list, searchable.getPage(), total);
}
@Override
public List findList(Searchable searchable) {
return this.findAll(findAllQL, searchable, searchCallback);
}
@Override
public long count(Searchable searchable) {
return this.count(countAllQL, searchable, searchCallback);
}
/**
* 按条件统计
*
* @param ql 基本查询语句
* @param searchable 查询条件、分页、排序
* @param searchCallback 查询回调,自定义设置查询条件和赋值
*/
private long count(final String ql, final Searchable searchable, final SearchCallback searchCallback) {
searchable.changeDataCondition();
assertConverted(searchable);
StringBuilder s = new StringBuilder(ql);
searchCallback.prepareQl(s, searchable);
Query query = em.createQuery(s.toString());
searchCallback.setValues(query, searchable);
return (Long) query.getSingleResult();
}
/**
* @param ql 基本查询语句
* @param searchable 查询条件、分页、排序
* @param searchCallback 查询回调,自定义设置查询条件和赋值
*/
private List findAll(final String ql, final Searchable searchable, final SearchCallback searchCallback) {
searchable.changeDataCondition();
assertConverted(searchable);
StringBuilder s = new StringBuilder(ql);
searchCallback.prepareQl(s, searchable);
searchCallback.prepareOrder(s, searchable);
Query query = em.createQuery(s.toString());
searchCallback.setValues(query, searchable);
searchCallback.setPageable(query, searchable);
return query.getResultList();
}
private void assertConverted(Searchable searchable) {
if (!searchable.isConverted()) {
searchable.convert(this.entityClass);
}
}
/**
* 按顺序设置Query参数
*
* @param query:查询
* @param params:参数
*/
private void setParameters(Query query, Object... params) {
if (params != null) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i + 1, params[i]);
}
}
}
}