1. 程式人生 > 實用技巧 >Hibernate JPA 各種自定義SQL及返回總結

Hibernate JPA 各種自定義SQL及返回總結

我的總結 基於 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);