我的总结 基于 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);