一、使用EntityManager進行復雜查詢
自己寫SQL語句的方式。
import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.Query; import org.hibernate.SQLQuery; import org.hibernate.transform.Transformers; import org.hibernate.type.IntegerType; import org.hibernate.type.StringType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @Component public class EchartsCustomImpl { @Autowired private EntityManager entityManager; /** 查詢省份訪問量數據 **/ private final static String SELECT_CHINA_MAP_SQL = "" + "select " + " taa.num as num, map.province_name as provinceName " + "from ( " + " select " + " sum(pv_count+visitor_count) as num, province_id " + " from area " + " where " + " create_time BETWEEN :startTime and :endTime " + " group by province_id " + ") as taa left join province as map on taa.province_id=map.province_id "; public Map<String, Integer> selectChinaMapData(String startTime, String endTime) { Query query = entityManager.createNativeQuery(SELECT_CHINA_MAP_SQL) .setParameter("startTime", startTime) .setParameter("endTime", endTime); query.unwrap(SQLQuery.class) .addScalar("num", IntegerType.INSTANCE) .addScalar("provinceName", StringType.INSTANCE) .setResultTransformer(Transformers.aliasToBean(ChinaMapDto.class)); List<ChinaMapDto> chinaMapDtoList = query.getResultList(); Map<String, Integer> map = new HashMap<>(); if(!CollectionUtils.isEmpty(chinaMapDtoList)) { for (ChinaMapDto chinaMapDto : chinaMapDtoList) { map.put(chinaMapDto.getProvinceName(), chinaMapDto.getNum()); } } return map; } }
二、使用JpaSpecificationExecutor進行復雜查詢
繼承JpaSpecificationExecutor接口
@Repository public interface ResumeRepository extends JpaRepository<Resume, Integer>, JpaSpecificationExecutor<Resume> { }
使用
import java.util.ArrayList; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.jpa.domain.Specification; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; import com.intecwh.hp.domain.entity.Resume; import com.intecwh.hp.domain.repository.base.ResumeRepository; @RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTest { @Autowired private ResumeRepository resumeRepository; @Test public void testJpaSpecificationExecutor() { String empName = "zhangsan"; String school = "清華大學"; String specName = "計算機"; Specification<Resume> specification = new Specification<Resume>() { @Override public Predicate toPredicate(Root<Resume> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<Predicate>(); if(!StringUtils.isEmpty(empName)) { list.add(cb.like(root.get("empName").as(String.class), "%"+empName+"%")); } if(!StringUtils.isEmpty(school)) { list.add(cb.like(root.get("school").as(String.class), school)); } if(!StringUtils.isEmpty(specName)) { list.add(cb.like(root.get("specName").as(String.class), specName)); } Predicate[] p = new Predicate[list.size()]; return cb.or(list.toArray(p)); } }; List<Resume> resumes = resumeRepository.findAll(specification); System.out.println(resumes); } }
參考文章:http://blog.didispace.com/spring-boot-data-jpa-specification/