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) // 这个注解一定要加在调用自定义方法的最外层的方法上面。

// 第三个注意点:sql查询返回的字段要和类字段一样
// 查询结果 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);

 

Predicate in 的用法

 1         Specification<MeetingDO> specification = new Specification<MeetingDO>() {
 2             @Override
 3             public Predicate toPredicate(Root<MeetingDO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
 4                 Predicate predicate = PredicateUtil.handleQueryCondition(criteriaBuilder, root, queryDTO);
 5                 // in 项目编号
 6                 Path<String> path = root.get("optyNum");
 7                 CriteriaBuilder.In<String> in = criteriaBuilder.in(path);
 8                 if (!finalList.isEmpty()) {
 9                     for (String s : finalList) {
10                         in.value(s);
11                     }
12                     predicate = criteriaBuilder.and(predicate, criteriaBuilder.in(in));
13                 }22                 return predicate;
23             }
24         };
25         Page<MeetingDO> all = repository.findAll(specification, pageable);
// like+in+ (or) 的用法
         Predicate workSheetName = cb.like(root.get("workSheetName"), "%" + searchKey + "%"); Predicate workSheetNum = cb.like(root.get("workSheetNum"), "%" + searchKey + "%"); List<WaterHouse> byHouseNameLike = waterHouseRepository.findByHouseNameLike("%" + searchKey + "%"); if(CollectionUtils.isNotEmpty(byHouseNameLike)){ Set<Long> houseIdSet = byHouseNameLike.stream().map(WaterHouse::getId).collect(Collectors.toSet()); CriteriaBuilder.In<Object> objectIn = cb.in(root.get("houseId")); houseIdSet.forEach(x->{ objectIn.value(x); }); predicates.add(cb.and(cb.or(workSheetName,workSheetNum,objectIn))); }else{ predicates.add(cb.and(cb.or(workSheetName,workSheetNum))); }

 

 //   criteriaBuilder.like 

// 与会人员搜索
                if (finalIsUserCode) {
                    predicate = criteriaBuilder.and(predicate, criteriaBuilder.like(root.get("joinPerson"), "%"+finalUserCode+"%"));
                }

 自定义拼写sql 返回map集合 map转对象 并分页

 1     public Page findData(EconomicReportDTO economicReportDTO, UserDetailDTO userDetailDTO) {
 2         String querySql = getQuerySql(economicReportDTO, userDetailDTO);
 3         Query query = entityManager.createNativeQuery(querySql);
 4         query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
 5         List<Map<String, Object>> tempList = query.getResultList();
 6         // 总结果集
 7         List<EconomicReportRO> roList = JSONObject.parseArray(JSONObject.toJSONString(tempList), EconomicReportRO.class);
 8         // 设置分页
 9         query.setFirstResult((economicReportDTO.getPageNum()-1) * economicReportDTO.getPageSize());
10         query.setMaxResults(economicReportDTO.getPageSize());
11         // 获取分页查询结果集
12         List<Map<String, Object>> tempListPage = query.getResultList();
13         List<EconomicReportRO> roListPage = JSONObject.parseArray(JSONObject.toJSONString(tempListPage), EconomicReportRO.class);
14         List<EconomicReportVO> voList = new ArrayList<>();
15         // 财经数据整合
16         if (!roListPage.isEmpty()) {
17             getEconomicData(roListPage,voList);
18         }
19         // 返回分页
20         Pageable pageable = PageRequest.of(economicReportDTO.getPageNum()-1,
21                 economicReportDTO.getPageSize());
22         Page<EconomicReportRO> page = new PageImpl(voList,pageable,roList.size());
23         return page;
24     }

 @QUERY注解分页  @转自 https://www.cnblogs.com/adg-6/p/11812041.html

@Query(nativeQuery = true,
value = "select id, company_id,address_name,address_detail,phone_num, regist_date,update_date,delete_flag,update_id FROM delivery_address WHERE delete_flag='0' AND IF ( ?1!=1, company_id = ?1, 1=1) AND IF ( ?2 is null,1=1,address_name LIKE CONCAT('%',?2,'%'))",
countQuery = "select count(id) FROM delivery_address WHERE delete_flag='0' AND IF ( ?1!=1, company_id = ?1, 1=1) AND IF ( ?2 is null,1=1,address_name LIKE CONCAT('%',?2,'%'))")
public Page<DeliveryAddress> findAllByCompanyId(Integer companyId,String addressName,Pageable pageable);

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM