|
@ -0,0 +1,362 @@
|
|
|
package com.yihu.mysql.query;
|
|
|
|
|
|
import com.yihu.utils.context.SpringContextUtils;
|
|
|
import org.hibernate.Query;
|
|
|
import org.hibernate.Session;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.domain.PageRequest;
|
|
|
import org.springframework.data.domain.Pageable;
|
|
|
import org.springframework.data.domain.Sort;
|
|
|
import org.springframework.data.jpa.repository.JpaRepository;
|
|
|
import org.springframework.data.repository.CrudRepository;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
import org.springframework.transaction.annotation.Propagation;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
import javax.persistence.EntityManager;
|
|
|
import javax.persistence.PersistenceContext;
|
|
|
import javax.persistence.criteria.CriteriaBuilder;
|
|
|
import javax.persistence.criteria.CriteriaQuery;
|
|
|
import javax.persistence.criteria.Predicate;
|
|
|
import javax.persistence.criteria.Root;
|
|
|
import javax.persistence.metamodel.EntityType;
|
|
|
import java.io.Serializable;
|
|
|
import java.lang.reflect.ParameterizedType;
|
|
|
import java.lang.reflect.Type;
|
|
|
import java.text.ParseException;
|
|
|
import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* Service基础类。此类基于Spring Data JPA进行封装(Spring Data JPA又是基于JPA封装,EHR平台使用Hibernate作为JPA实现者)。
|
|
|
* 需要注意的是,部分功能会跳过JPA接口而直接使用Hibernate接口,比如访问Hibernate的Session接口,因为它把JPA的EntityManager功能强大。
|
|
|
*
|
|
|
* @author lincl
|
|
|
* @author Sand
|
|
|
* @version 1.0
|
|
|
* @created 2016.2.3。
|
|
|
*/
|
|
|
@Transactional(propagation = Propagation.SUPPORTS)
|
|
|
public abstract class BaseJpaService<T, R extends CrudRepository> {
|
|
|
|
|
|
protected final int defaultPage = 1;
|
|
|
protected final int defaultSize = 15;
|
|
|
|
|
|
protected Class<T> tClass;
|
|
|
protected Class<R> repoClass;
|
|
|
|
|
|
@PersistenceContext
|
|
|
protected EntityManager entityManager;
|
|
|
@Autowired
|
|
|
protected JdbcTemplate jdbcTemplate;
|
|
|
|
|
|
public BaseJpaService() {
|
|
|
Type genType = getClass().getGenericSuperclass();
|
|
|
if (genType instanceof ParameterizedType) {
|
|
|
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
|
|
|
if (params.length == 2) {
|
|
|
tClass = (Class<T>) params[0];
|
|
|
repoClass = (Class<R>) params[1];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public T save (T entity) {
|
|
|
return (T) getRepository().save(entity);
|
|
|
}
|
|
|
|
|
|
public void batchInsert (List list) {
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
|
entityManager.persist(list.get(i));
|
|
|
if (i % 30 == 0) {
|
|
|
entityManager.flush();
|
|
|
entityManager.clear();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void delete(Serializable id) {
|
|
|
getRepository().delete(id);
|
|
|
}
|
|
|
|
|
|
public void delete(T entity) {
|
|
|
getRepository().delete(entity);
|
|
|
}
|
|
|
|
|
|
public void delete(Iterable ids) {
|
|
|
getRepository().delete(ids);
|
|
|
}
|
|
|
|
|
|
public int delete(Object[] ids){
|
|
|
if (Integer.class.getName().equals(getEntityIdType())) {
|
|
|
Integer [] _ids = new Integer[ids.length];
|
|
|
for (int i = 0; i < ids.length; i ++) {
|
|
|
_ids[i] = new Integer(ids[i].toString());
|
|
|
}
|
|
|
ids = _ids;
|
|
|
}
|
|
|
String hql = "DELETE FROM " + getEntityClass().getName() + " WHERE " + getEntityIdFiled() + " in(:ids)";
|
|
|
Query query = currentSession().createQuery(hql);
|
|
|
query.setParameterList("ids", ids);
|
|
|
return query.executeUpdate();
|
|
|
}
|
|
|
|
|
|
public T retrieve(Serializable id) {
|
|
|
return (T) getRepository().findById(id);
|
|
|
}
|
|
|
|
|
|
public List<T> search(String filters) throws ParseException {
|
|
|
URLQueryParser queryParser = createQueryParser("", filters, "");
|
|
|
CriteriaQuery query = queryParser.makeCriteriaQuery();
|
|
|
|
|
|
return entityManager
|
|
|
.createQuery(query)
|
|
|
.getResultList();
|
|
|
}
|
|
|
|
|
|
public List<T> search(String filters, String sorts) throws ParseException {
|
|
|
URLQueryParser queryParser = createQueryParser("", filters, sorts);
|
|
|
CriteriaQuery query = queryParser.makeCriteriaQuery();
|
|
|
|
|
|
return entityManager
|
|
|
.createQuery(query)
|
|
|
.getResultList();
|
|
|
}
|
|
|
|
|
|
public List<T> search(String fields, String filters, String sorts) throws ParseException {
|
|
|
URLQueryParser queryParser = createQueryParser(fields, filters, sorts);
|
|
|
CriteriaQuery query = queryParser.makeCriteriaQuery();
|
|
|
return entityManager
|
|
|
.createQuery(query)
|
|
|
.getResultList();
|
|
|
}
|
|
|
|
|
|
public List<T> search(String fields, String filters, String sorts, Integer page, Integer size) throws ParseException {
|
|
|
URLQueryParser queryParser = createQueryParser(fields, filters, sorts);
|
|
|
CriteriaQuery query = queryParser.makeCriteriaQuery();
|
|
|
if (page == null || page <= 0) {
|
|
|
page = defaultPage;
|
|
|
}
|
|
|
if (size == null || size <= 0 || size > 10000) {
|
|
|
size = defaultSize;
|
|
|
}
|
|
|
return entityManager
|
|
|
.createQuery(query)
|
|
|
.setFirstResult((page - 1) * size)
|
|
|
.setMaxResults(size)
|
|
|
.getResultList();
|
|
|
}
|
|
|
|
|
|
public List<T> findByField(String field, Object value){
|
|
|
|
|
|
return findByFields(
|
|
|
new String[]{field},
|
|
|
new Object[]{value}
|
|
|
);
|
|
|
}
|
|
|
|
|
|
public List<T> findByFields(String[] fields, Object[] values){
|
|
|
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
|
|
CriteriaQuery query = criteriaBuilder.createQuery(getEntityClass());
|
|
|
Root<T> root = query.from(getEntityClass());
|
|
|
List<Predicate> ls = new ArrayList<>();
|
|
|
for(int i=0; i< fields.length; i++){
|
|
|
if (values[i].getClass().isArray()) {
|
|
|
ls.add(criteriaBuilder.in(root.get(fields[i]).in((Object[]) values[i])));
|
|
|
} else {
|
|
|
ls.add(criteriaBuilder.equal(root.get(fields[i]), values[i]));
|
|
|
}
|
|
|
}
|
|
|
query.where(ls.toArray(new Predicate[ls.size()]));
|
|
|
return entityManager
|
|
|
.createQuery(query)
|
|
|
.getResultList() ;
|
|
|
}
|
|
|
|
|
|
public long getCount(String filters) throws ParseException {
|
|
|
URLQueryParser queryParser = createQueryParser(filters);
|
|
|
CriteriaQuery query = queryParser.makeCriteriaCountQuery();
|
|
|
|
|
|
return (long) entityManager.createQuery(query).getSingleResult();
|
|
|
}
|
|
|
|
|
|
public Class<T> getEntityClass() {
|
|
|
return tClass;
|
|
|
}
|
|
|
|
|
|
public <T> URLQueryParser createQueryParser(String fields, String filters, String orders) {
|
|
|
URLQueryParser queryParser = new URLQueryParser<T>(fields, filters, orders)
|
|
|
.setEntityManager(entityManager)
|
|
|
.setEntityClass(getEntityClass());
|
|
|
|
|
|
return queryParser;
|
|
|
}
|
|
|
|
|
|
public <T> URLQueryParser createQueryParser(String filters) {
|
|
|
URLQueryParser queryParser = new URLQueryParser<T>(filters)
|
|
|
.setEntityManager(entityManager)
|
|
|
.setEntityClass(getEntityClass());
|
|
|
|
|
|
return queryParser;
|
|
|
}
|
|
|
|
|
|
public Sort parseSorts(String sorter){
|
|
|
if (!StringUtils.isEmpty(sorter)) {
|
|
|
String[] orderArray = sorter.split(",");
|
|
|
|
|
|
List<Sort.Order> orderList = new ArrayList<>(orderArray.length);
|
|
|
Arrays.stream(orderArray).forEach(
|
|
|
elem -> orderList.add(
|
|
|
elem.startsWith("+") ? new Sort.Order(Sort.Direction.ASC, elem.substring(1)):
|
|
|
new Sort.Order(Sort.Direction.DESC, elem.substring(1))));
|
|
|
return Sort.by(orderList);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
public JpaRepository getJpaRepository(){
|
|
|
return (JpaRepository) SpringContextUtils.getService(repoClass);
|
|
|
}
|
|
|
|
|
|
public R getRepository() {
|
|
|
return SpringContextUtils.getService(repoClass);
|
|
|
}
|
|
|
|
|
|
public Session currentSession() {
|
|
|
return entityManager.unwrap(Session.class);
|
|
|
}
|
|
|
|
|
|
public String getEntityName(){
|
|
|
return getEntityClass().getName();
|
|
|
}
|
|
|
|
|
|
public String getEntityIdFiled(){
|
|
|
EntityType entityType = entityManager.getMetamodel().entity(getEntityClass());
|
|
|
javax.persistence.metamodel.Type type = entityType.getIdType();
|
|
|
return entityType.getId(type.getJavaType()).getName();
|
|
|
}
|
|
|
|
|
|
public String getEntityIdType(){
|
|
|
EntityType entityType = entityManager.getMetamodel().entity(getEntityClass());
|
|
|
javax.persistence.metamodel.Type type = entityType.getIdType();
|
|
|
return type.getJavaType().getName();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将实体转换为模型。
|
|
|
*
|
|
|
* @param source
|
|
|
* @param target
|
|
|
* @param <T>
|
|
|
* @return
|
|
|
*/
|
|
|
public <T> T convertToModel(Object source, Class<T> target) {
|
|
|
if (source == null) {
|
|
|
return null;
|
|
|
}
|
|
|
T _target = BeanUtils.instantiate(target);
|
|
|
BeanUtils.copyProperties(source, _target);
|
|
|
return _target;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将实体集合转换为模型集合。
|
|
|
* @param sources
|
|
|
* @param targets
|
|
|
* @param target
|
|
|
* @param <T>
|
|
|
* @return
|
|
|
*/
|
|
|
public <T> List<T> convertToModels(Collection sources, List<T> targets, Class<T> target){
|
|
|
if (null == sources) {
|
|
|
return null;
|
|
|
}
|
|
|
sources.forEach(item -> {
|
|
|
T _target = BeanUtils.instantiate(target);
|
|
|
BeanUtils.copyProperties(item, _target);
|
|
|
targets.add(_target);
|
|
|
});
|
|
|
return targets;
|
|
|
}
|
|
|
|
|
|
public String getCode() {
|
|
|
return UUID.randomUUID().toString().replaceAll("-", "");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取指定长度的随机数字字符串
|
|
|
* @param length
|
|
|
* @return
|
|
|
*/
|
|
|
public String randomInt(int length) {
|
|
|
String str = "0123456789";
|
|
|
StringBuffer buffer = new StringBuffer();
|
|
|
Random random = new Random();
|
|
|
for(int i = 0; i < length; ++i) {
|
|
|
int pos = random.nextInt(str.length());
|
|
|
buffer.append(str.charAt(pos));
|
|
|
}
|
|
|
return buffer.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取指定长度的随机字符串
|
|
|
* @param length
|
|
|
* @return
|
|
|
*/
|
|
|
public String randomString(int length) {
|
|
|
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
|
StringBuffer buffer = new StringBuffer();
|
|
|
Random random = new Random();
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
int pos = random.nextInt(str.length());
|
|
|
buffer.append(str.charAt(pos));
|
|
|
}
|
|
|
return buffer.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 排序条件 第一个字符为 + 表示升序,第一个字符为 - 表示减序,不包含 + 或者 - 默认升序
|
|
|
* @param sorts
|
|
|
* @return
|
|
|
*/
|
|
|
public Sort createSort(String sorts){
|
|
|
Sort sort = null;
|
|
|
if (!org.springframework.util.StringUtils.isEmpty(sorts)) {
|
|
|
// 默认升序
|
|
|
if(sorts.contains("-")){
|
|
|
sort = Sort.by(Sort.Direction.DESC,sorts.substring(1,sorts.length()).split(","));
|
|
|
}else if(sorts.contains("+")){
|
|
|
sort = Sort.by(Sort.Direction.ASC,sorts.substring(1,sorts.length()).split(","));
|
|
|
}else{
|
|
|
sort = Sort.by(Sort.Direction.ASC,sorts.split(","));
|
|
|
}
|
|
|
}
|
|
|
return sort;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 创建分页对象
|
|
|
* @param page
|
|
|
* @param size
|
|
|
* @param sorts
|
|
|
* @return
|
|
|
*/
|
|
|
public Pageable createPage(Integer page, Integer size, String sorts){
|
|
|
PageRequest pageRequest = null;
|
|
|
if(null == page || page <= 0){
|
|
|
page = defaultPage;
|
|
|
}
|
|
|
if(null == size || size <= 0){
|
|
|
size = defaultSize;
|
|
|
}
|
|
|
if(!org.apache.commons.lang3.StringUtils.isEmpty(sorts)){
|
|
|
pageRequest = PageRequest.of(page,size,createSort(sorts));
|
|
|
}else{
|
|
|
pageRequest = PageRequest.of(page,size);
|
|
|
}
|
|
|
|
|
|
return pageRequest;
|
|
|
}
|
|
|
}
|