SpringBoot中使用JPA进行复杂查询

一、使用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进行复杂查询

  1. 继承JpaSpecificationExecutor接口

    @Repository
    public interface ResumeRepository extends JpaRepository<Resume, Integer>, JpaSpecificationExecutor<Resume> {
    }
    
  2. 使用

    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/

你可能感兴趣的:(springboot)