Spring jpa是Spring家族的一套基于jpa规范标准的查询框架,其实它的内部的是借参考于Hibarnate实现的,只是它更加轻量级。Spring jpa对于单表的增删改查是很方便的,对于多表查询的话也可以使用它的一个注解:@Query实现。@Query可以像Hibrnate那样写hql,也可以写原生sql。担是如果你的查询结果是多个表查询出来的结果,而且你的数据库中的表都是单表的话,用原生sql是查询出来对应不上的,应该用它的hql。@Query可以写增删改查sql语句,担如果是增删改操作还要加上@Modifying注解。
下面进入正题,使用EntityManager实现Spring jpa多表查询与动态sql,不多说,直接上代码:
首先在你的service中引EntityManager :
@PersistenceContext
private final EntityManager entityManager;
这是传参用到的:
/**
* 给sql参数设置值
* @param query 查询
* @param params 参数
*/
private void setParameters(Query query, Map<String,Object> params){
for(Map.Entry<String,Object> entry:params.entrySet()){
query.setParameter(entry.getKey(),entry.getValue());
}
}
接下来开始sql:
@Override
//@Cacheable
public Map<String, Object> queryAllByPageAndParams(CourseStatisticReqParams reqParams, Pageable pageable) {
String groupBySql=" group by buc.course_id order by buc.create_date desc";
StringBuilder countSelectSql = new StringBuilder();
countSelectSql.append("select count(t.id) from (select buc.id id from bae_user_course buc left join bae_course c on buc.course_id=c.id \n" +
"where 1=1 ");
StringBuilder selectSql = new StringBuilder();
//user_id改成user_phone
//selectSql.append("select c.course_name,c.course_type,buc.course_id,count(buc.user_id) buy_num,sum(buc.learn_ratio) learn_ratio from bae_user_course buc left join bae_course c on buc.course_id=c.id where 1=1 ");
selectSql.append("select c.course_name,c.course_type,buc.course_id,count(buc.user_phone) buy_num,sum(buc.learn_ratio) learn_ratio from bae_user_course buc left join bae_course c on buc.course_id=c.id where 1=1 ");
Map<String,Object> params = new HashMap<>();
StringBuilder whereSql = new StringBuilder();
if(ObjectUtil.isNotEmpty(reqParams)){
if(null !=reqParams.getCourseName() && !"".equals(reqParams.getCourseName())){
whereSql.append(" and c.course_name like concat('%',:course_name,'%')");
params.put("course_name",reqParams.getCourseName());
}
if(null !=reqParams.getStartDate() && !"".equals(reqParams.getStartDate())){
if(null !=reqParams.getEndDate() && !"".equals(reqParams.getEndDate())){
whereSql.append(" and c.create_date >=:start_date and c.create_date <=:end_date");
params.put("start_date", DateUtil.toTimestamp(reqParams.getStartDate()));
params.put("end_date",DateUtil.toTimestamp(reqParams.getEndDate()));
}
}
}
String groupBySqlCount=" group by buc.course_id) t";
String countSql = new StringBuilder().append(countSelectSql).append(whereSql).append(groupBySqlCount).toString();
Query countQuery = this.entityManager.createNativeQuery(countSql);
this.setParameters(countQuery,params);
BigInteger count = (BigInteger) countQuery.getSingleResult();
String querySql = new StringBuilder().append(selectSql).append(whereSql).append(groupBySql).toString();
Query query = this.entityManager.createNativeQuery(querySql);
query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
this.setParameters(query,params);
query.setFirstResult(pageable.getPageNumber());
query.setMaxResults(pageable.getPageSize());
List<Object[]> content =query.getResultList();
List<CourseStatisticResParams> list=new ArrayList<CourseStatisticResParams>(content.size());
for (Object obj : content) {
Map row = (Map) obj;
CourseStatisticResParams res=new CourseStatisticResParams();
res.setCourseName(row.get("course_name")==null?null:row.get("course_name").toString());
res.setBuyNum(row.get("buyNum")==null?null:Integer.parseInt(row.get("buyNum").toString()));
res.setCourseId(row.get("course_id")==null?null:Long.parseLong(row.get("course_id").toString()));
res.setBuyNum(row.get("buy_num")==null?null:Integer.parseInt(row.get("buy_num").toString()));
res.setCourseType(row.get("course_type")==null?null:Integer.parseInt(row.get("course_type").toString()));
//未学 在学 学完 考完 人数
if(null !=res.getCourseId() && !"".equals(res.getCourseId())){
//未学
Map<String,Object> no_learn_params = new HashMap<>();
String no_learn_sql="select count(buc.id) from bae_user_course buc where 1=1 and(buc.learn_ratio is null or buc.learn_ratio=0) and buc.course_id=:course_id";
no_learn_params.put("course_id",res.getCourseId());
Query no_learn_countquery = this.entityManager.createNativeQuery(no_learn_sql);
this.setParameters(no_learn_countquery,no_learn_params);
BigInteger no_learn_count = (BigInteger)no_learn_countquery.getSingleResult();
res.setNoLearnNum(no_learn_count==null?0:no_learn_count.intValue());
//在学
Map<String,Object> learning_params = new HashMap<>();
String learning_sql="select count(buc.id) from bae_user_course buc where 1=1 and buc.learn_ratio >0 and buc.learn_ratio<100 and buc.learn_status=0 and buc.course_id=:course_id";
learning_params.put("course_id",res.getCourseId());
Query learning_countquery = this.entityManager.createNativeQuery(learning_sql);
this.setParameters(learning_countquery,learning_params);
BigInteger learning_count = (BigInteger)learning_countquery.getSingleResult();
res.setLearningNum(learning_count==null?0:learning_count.intValue());
//学完
Map<String,Object> learned_params = new HashMap<>();
String learned_sql="select count(buc.id) from bae_user_course buc where 1=1 and buc.course_id=:course_id and buc.learn_status=1";
learned_params.put("course_id",res.getCourseId());
Query learned_countquery = this.entityManager.createNativeQuery(learned_sql);
this.setParameters(learned_countquery,learned_params);
BigInteger learned_count = (BigInteger)learned_countquery.getSingleResult();
res.setLearnedNum(learned_count==null?0:learned_count.intValue());
//考完
Map<String,Object> examed_params = new HashMap<>();
String examed_sql="select count(buc.id) from bae_user_course buc where 1=1 and buc.course_id=:course_id and buc.learn_status=1 and buc.exam_status=1";
examed_params.put("course_id",res.getCourseId());
Query examed_countquery = this.entityManager.createNativeQuery(examed_sql);
this.setParameters(examed_countquery,examed_params);
BigInteger examed_count = (BigInteger)examed_countquery.getSingleResult();
res.setExamedNum(examed_count==null?0:examed_count.intValue());
}
list.add(res);
}
Page<CourseStatisticResParams> courseStatisticPage = new PageImpl<CourseStatisticResParams>(list, pageable, Long.valueOf(count.toString()));
return PageUtil.toPage(courseStatisticPage);
}
其中Query countQuery = this.entityManager.createNativeQuery(countSql);是表示使用原生sql的意思,如果你想用像hql那样,可以用它的createQuery这个方法,然后sql语句改成像hql那样查询即可。