Hibernate JPA 各種自定義SQL及返回總結
阿新 • • 發佈:2020-08-10
我的總結 基於 spring-data-jpa-2.1.15RELEASE.jar
JPA代替mybatis的dao
import com.dahuatech.bigfish.project.assignment.entity.AssignmentDO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
import java.util.Optional;
public interface AssignmentRepository extends JpaRepository<AssignmentDO,Long>, JpaSpecificationExecutor<AssignmentDO> { List<AssignmentDO> findAllByIdIn(List<Long> ids); Optional<List<AssignmentDO>> findAllByIsDel(Integer isDel); Optional<AssignmentDO> findByAssignmentNOAndIsDel(String assignmentNO,Integer isDel); }
這個介面基本可以滿足單個表查詢。非常方便好用。當然只對於單表
介面的方法就是sql條件。
接下來是單表複雜查詢sql:語法和mybatis差不多
import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @PersistenceContext private EntityManager entityManager; // 自定義sql StringBuffer querySql = new StringBuffer("select * from assignment"); querySql.append(" where appoint_people_code = :userCode and is_del = 0"); querySql.append(" and real_complete_time >= :").append(conditionDTO.getFieldName()); // 因為我的引數在list中,所以需要遍歷。不需要遍歷的話,直接填入引數名稱就好 querySql.append(" and team_work_people_code like concat('%',:").append(conditionDTO.getFieldName()).append(",'%')"); 這是 like 語句 querySql.append(" and team_work_people_code like concat('%',:userCode,'%')"); // 正常這樣寫就可以 querySql.append(" and assignment_no in (:assignmentNO) "); // in語句 // 生成Query Query query = entityManager.createNativeQuery(querySql.toString(),AssignmentDO.class); // 這種寫法,返回的類,只能是@entity註解的類(sql中查詢的表對應的類)。不能自定義返回自己需要的類 // 設定引數 query.setParameter("userCode",userDetailDTO.getUserCode()); // 對應 拼接的sql中的 引數名稱 query.setParameter("assignmentNO",填入list集合); // 對應 拼接的sql中的 引數名稱 // 查詢結果 List<assignmentDO> list = query.getResultList();
返回自定義的類,方法一:NativeQueryImpl+自定義sql
select m.agree_amt as totalAmount,es.estimate AS totalEstimateAmount,count(*) as total from my_project m JOIN (select item_code,item_cost_id,is_del,estimate from estimate where id in (select max(id) id from estimate WHERE item_cost_id = 52 and is_del = 0 GROUP BY item_code)) es on (m.opty_num=es.item_code and es.item_cost_id = 52) where m.is_del = 0 and es.is_del = 0 // 這是我的查詢sql // 想加什麼引數跟上面一下新增就可以了 // 返回的類 import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; @Data public class BaobiaoVO implements Serializable { private BigDecimal totalAmount; private BigInteger total; private BigDecimal totalEstimateAmount; } // 重點注意的地方 // 生成Query import org.hibernate.query.internal.NativeQueryImpl; import org.hibernate.transform.Transformers; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @PersistenceContext EntityManager em; // 第一個重點注意 NativeQueryImpl query = em.createNativeQuery(querySql.toString()).unwrap(NativeQueryImpl.class); query.setResultTransformer(Transformers.aliasToBean(BaobiaoVO.class)); // 第二個重點注意 @Transactional(readOnly = true) // 這個註解一定要加在呼叫自定義方法的最外層的方法上面。 // 查詢結果 List<BaobiaoVO> list = query.getResultList();
自定義返回類,方法二:@Query註解+自定義類
@Param 是其中一種傳參方式
需要注意的是:在這種方式中,@Query註解的屬性中沒有設定 nativeQuery = true
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; public interface MyProjectRepository extends JpaRepository<MyProject, Long>, JpaSpecificationExecutor<MyProject> { @Query(value = "SELECT new com.dahuatech.bigfish.project.myproject.entity.vo.MyProjectRO(m.id,m.optyNum,m.optyName,m.optyId,m.oneAgree,m.twoAgree,m.province,m.city) " + "from MyProject m where m.optyStatus in ('有效','中標') and m.optyLevel in ('公司級','部門級','區域級') and isDel = :isDel") List<MyProjectRO> queryMyProject(@Param("isDel") Integer isDel); } // 自定義的類--想要實現以上的sql正常返回。自定義類中要新增有參建構函式,然後在sql中直接new 就可以 import lombok.Data; import java.io.Serializable; @Data public class MyProjectRO implements Serializable { Long id; String optyNum; String optyName; String optyId; String oneAgree; String twoAgree; String province; String city; public MyProjectRO (){} public MyProjectRO (Long id,String optyNum,String optyName,String optyId,String oneAgree,String twoAgree,String province,String city) { this.id = id; this.optyNum = optyNum; this.optyName = optyName; this.optyId = optyId; this.oneAgree = oneAgree; this.twoAgree = twoAgree; this.province = province; this.city = city; } }
自定義返回類,方法三:@Query註解 返回 List
注意: ?1 也是其中一種傳參方式,1 表示第一個引數。
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import com.alibaba.fastjson.JSONObject; public interface MyProjectRepository extends JpaRepository<MyProject, Long>, JpaSpecificationExecutor<MyProject> { @Query(value = "SELECT m.id,m.opty_num,m.opty_name,m.opty_id,m.one_agree,m.two_agree,m.province,m.city " + "from my_project m where m.opty_status in ('有效','中標') and m.opty_level in ('公司級','部門級','區域級') and is_del = ?1",nativeQuery = true) List<Map<String,Object>> queryMyProject(Integer isDel); } // 自定義的類 import lombok.Data; import java.io.Serializable; @Data public class MyProjectRO implements Serializable { Long id; String optyNum; String optyName; String optyId; String oneAgree; String twoAgree; String province; String city; } // 查詢結果 List<Map<String, Object>> list = myProjectRepository.queryMyProject(); // 轉物件 List<MyProjectRO> list = JSONObject.parseArray(JSONObject.toJSONString(list), MyProjectRO.class);