1. 程式人生 > >spring-data-jpa動態拼接sql語句實現動態的多表條件查詢

spring-data-jpa動態拼接sql語句實現動態的多表條件查詢

**

spring-data-jpa 動態拼接sql語句

** spring-data-jpa對於簡單的資料操作確實使用起來比較方便,但是對於一些比較複雜的動態的多表條件查詢就不是那麼簡單了,對於需要些sql語句並且需要動態的新增條件的時候就得使用jpa的EntityManager來完成了.
以下為以返回EasyUI分頁資料為例,

public interface VideoDao extends JpaRepository<Video, Long>, JpaSpecificationExecutor<Video>{
	public Page<VideoExtend> findVideoList(VideoParam vp,Pageable pageable);
}
**//此介面繼承JpaRepository和JpaSpecificationExecutor**

**//這個實現類和上面的介面在同一級目錄下,並且同一命名規則.無需用implements與上面的介面產生正式的實現關係,但是還是要規範的實現上面的介面的方法.**
package cn.folkcam.rablive.cp.dao;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import com.taobao.api.internal.toplink.embedded.websocket.util.StringUtil;

import cn.folkcam.rablive.cp.entity.CommonSearchParameter;
import cn.folkcam.rablive.cp.entity.TradeDaily;
import cn.folkcam.rablive.cp.entity.Video;
import cn.folkcam.rablive.cp.entity.VideoExtend;
import cn.folkcam.rablive.cp.entity.VideoParam;

/**
 * videoDao的實現類
 */
public class VideoDaoImpl {

	@PersistenceContext
	private EntityManager entityManager;
	
	/**
	 * @param parameter
	 * @param pageable
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Page<VideoExtend> findVideoList(VideoParam parameter,Pageable pageable) {
		StringBuilder dataSql = new StringBuilder("SELECT v.fee_stat,v.action_id,v.video_icon_audit,"
				+ "v.video_url,v.video_wide,v.video_high,v.privilege_list,v.video_lable,"
				+ "v.praise_cnt,v.play_cnt,v.comment_cnt,v.resend_cnt,v.gift_cnt,v.reward_cnt,"
				+ "v.play_cnt,v.position_name,v.longitude,v.latitude,v.cos_lat,v.update_time,"
				+ "v.video_id,v.video_customer_id,v.video_title,v.aliyun_video_id,v.create_time,"
				+ "v.video_status,a.remark,v.video_icon,v.report_cnt,v.fee_stat,"
				+ "v.video_lable,c.sex "
				+ " FROM t_video v join t_customer c on v.video_customer_id = c.customer_id "
				+ "left join t_action a on v.action_id = a.action_id ");
			StringBuilder countSql = new StringBuilder("SELECT count(1) FROM t_video v ");
//				+ "left join t_action a on v.video_id = a.video_id ");
		
		//拼接where條件
		StringBuilder whereSql = new StringBuilder(" WHERE 1 = 1");
		if (StringUtils.isNotEmpty(parameter.getCustomerId())) {
			whereSql.append(" AND v.video_customer_id = :customerId");
		}
		
		if (StringUtils.isNotEmpty(parameter.getStatus())) {
			whereSql.append(" AND v.video_status = :status");
		}

		if (parameter.getEndTime() != null && parameter.getStartTime() != null) {
			whereSql.append(" AND v.create_time >= :startTime AND v.create_time <= :endTime");
		}

		if (StringUtils.isNotEmpty(parameter.getVideoTitle())) {
			whereSql.append(" AND v.video_title like concat('%',:videoTitle,'%')");
		}													

		if(parameter.getSex()!= null&&parameter.getSex()!=-1){
			countSql.append(" join t_customer c on v.video_customer_id = c.customer_id ");
			whereSql.append(" AND c.sex = :sex");
		}
		//組裝sql語句
		dataSql.append(whereSql).append(" order by v.create_time desc");
		countSql.append(whereSql);
		
		//建立本地sql查詢例項
		Query dataQuery = entityManager.createNativeQuery(dataSql.toString(), VideoExtend.class);
		Query countQuery = entityManager.createNativeQuery(countSql.toString());
		
		//設定引數
		if (StringUtils.isNotEmpty(parameter.getCustomerId())) {
			dataQuery.setParameter("customerId", parameter.getCustomerId());
			countQuery.setParameter("customerId", parameter.getCustomerId());
		}
		if (parameter.getEndTime() != null && parameter.getStartTime() != null) {
			dataQuery.setParameter("startTime", parameter.getStartTime(), TemporalType.TIMESTAMP);
			dataQuery.setParameter("endTime", parameter.getEndTime(), TemporalType.TIMESTAMP);
			countQuery.setParameter("startTime", parameter.getStartTime(), TemporalType.TIMESTAMP);
			countQuery.setParameter("endTime", parameter.getEndTime(), TemporalType.TIMESTAMP);
		}
		if (StringUtils.isNotEmpty(parameter.getStatus())) {
			dataQuery.setParameter("status", parameter.getStatus());
			countQuery.setParameter("status", parameter.getStatus());
		}
		if (StringUtils.isNotEmpty(parameter.getVideoTitle())) {
			dataQuery.setParameter("videoTitle", parameter.getVideoTitle());
			countQuery.setParameter("videoTitle", parameter.getVideoTitle());
		}
		if(parameter.getSex()!= null&&parameter.getSex()!=-1){
			dataQuery.setParameter("sex",parameter.getSex());
			countQuery.setParameter("sex",parameter.getSex());
		}
		//設定分頁
		dataQuery.setFirstResult(pageable.getOffset());
		dataQuery.setMaxResults(pageable.getPageSize());
		BigInteger count = (BigInteger) countQuery.getSingleResult();
		Long total = count.longValue();
		List<VideoExtend> content2 = total > pageable.getOffset() ? dataQuery.getResultList() : Collections.<VideoExtend> emptyList();
		return new PageImpl<>(content2, pageable, total);
	}	
}

簡單的寫寫,歡迎補充糾正