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 { protected final int defaultPage = 1; protected final int defaultSize = 15; protected Class tClass; protected Class 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) params[0]; repoClass = (Class) 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().findOne(id); } public List search(String filters) throws ParseException { URLQueryParser queryParser = createQueryParser("", filters, ""); CriteriaQuery query = queryParser.makeCriteriaQuery(); return entityManager .createQuery(query) .getResultList(); } public List search(String filters, String sorts) throws ParseException { URLQueryParser queryParser = createQueryParser("", filters, sorts); CriteriaQuery query = queryParser.makeCriteriaQuery(); return entityManager .createQuery(query) .getResultList(); } public List 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 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 findByField(String field, Object value){ return findByFields( new String[]{field}, new Object[]{value} ); } public List findByFields(String[] fields, Object[] values){ CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery query = criteriaBuilder.createQuery(getEntityClass()); Root root = query.from(getEntityClass()); List 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 getEntityClass() { return tClass; } public URLQueryParser createQueryParser(String fields, String filters, String orders) { URLQueryParser queryParser = new URLQueryParser(fields, filters, orders) .setEntityManager(entityManager) .setEntityClass(getEntityClass()); return queryParser; } public URLQueryParser createQueryParser(String filters) { URLQueryParser queryParser = new URLQueryParser(filters) .setEntityManager(entityManager) .setEntityClass(getEntityClass()); return queryParser; } public Sort parseSorts(String sorter){ if (!StringUtils.isEmpty(sorter)) { String[] orderArray = sorter.split(","); List 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 new Sort(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 * @return */ public T convertToModel(Object source, Class target) { if (source == null) { return null; } T _target = BeanUtils.instantiate(target); BeanUtils.copyProperties(source, _target); return _target; } /** * 将实体集合转换为模型集合。 * @param sources * @param targets * @param target * @param * @return */ public List convertToModels(Collection sources, List targets, Class 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 = new Sort(Sort.Direction.DESC,sorts.substring(1,sorts.length()).split(",")); }else if(sorts.contains("+")){ sort = new Sort(Sort.Direction.ASC,sorts.substring(1,sorts.length()).split(",")); }else{ sort = new Sort(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 = new PageRequest(page,size,createSort(sorts)); }else{ pageRequest = new PageRequest(page,size); } return pageRequest; } }