1.可以不写@Query,可以直接通过DAO里面定义的方法名字。
还有findTop4ByOrderByIsReadDesc
2.修改,删除语句一定要加上
@Modifying
@Transactional(这个的原因好像是说,jpa的修改删除操作其实分为两步,一步是改实体对象,另一步是改持久化对象。所以就算你逻辑上只有一个删除或者修改的操作,也要加上这个事务的注解)
3.遇到需要连表查询的,比如说用左关联
就需要重写Specification这个类里头的toPredicate这个方法。
下面这个例子,是一对多的关系,NoticeManageDo是一,NoticeUserNewDo是多,一这边实体类需要加上
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER) @JoinColumn(name="notice_Id") Set<NoticeUserNewDo> noticeUserNewDos;
以下,蓝色是重点。
Pageable pageable = new PageRequest(noticeManageQo.getPageNo()-1, noticeManageQo.getPageSize()); Page<NoticeManageDo> page = noticeManageDao.findAll(new Specification<NoticeManageDo>() { @Override public Predicate toPredicate(Root<NoticeManageDo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //一对多,会有重复,所以要去重 criteriaQuery.distinct(true); return getPredicate(userId,noticeManageQo,root,criteriaBuilder); } },pageable);
private Predicate getPredicate(Long userId,NoticeManageQo noticeManageQo, Root<NoticeManageDo> root, CriteriaBuilder criteriaBuilder) { List<Predicate> list = new ArrayList<>(); Join<NoticeUserNewDo, NoticeManageDo> join = root.join("noticeUserNewDos", JoinType.LEFT); if (noticeManageQo.getReceiveUserId().size()>0) { CriteriaBuilder.In<Object> in = criteriaBuilder.in(join.get("userId")); in.value(noticeManageQo.getReceiveUserId()); list.add(in); } if(noticeManageQo.getOrgNo().size() > 0){ CriteriaBuilder.In<Object> in = criteriaBuilder.in(join.get("orgId")); in.value(noticeManageQo.getOrgNo()); list.add(in); } if(noticeManageQo.getPubUserId() != null){ list.add(criteriaBuilder.equal(root.get("createdById"),noticeManageQo.getPubUserId())); } list.add(criteriaBuilder.equal(root.get("enabledFlag"),"1")); Predicate[] p = new Predicate[list.size()]; return criteriaBuilder.and(list.toArray(p)); }
4.关于参数是实体类对象
参数是实体对象的时候要用:#{#noticeManageInsertQo.title}这样取值,并且你的参数里头如果有非实体对象,也要:#{#userId}这样取,千万不要:userId这样取。因为不可以混合jpa方式和SPel ,我一开始就是两者混用了,然后一直报错,
no parameter binding found for name XXXXXXX!
.,后来好不容易找到这个
https://stackoverflow.com/questions/36004952/no-parameter-binding-found-for-name-spring-data-jpa
问题才得以解决。
@Modifying
@Query("update com.haizhi.crm.biz.notice.model.NoticeManageDo n set " +
"n.title = :#{#noticeManageInsertQo.title} ,n.content = :#{#noticeManageInsertQo.content},n.reply = :#{#noticeManageInsertQo.reply},n.status = :#{#noticeManageInsertQo.status}, " +
"n.receiveUserId = :#{#noticeManageInsertQo.receiveUserId}, n.orgNo = :#{#noticeManageInsertQo.orgNo} " +
",n.updateById =:#{#userId},n.updatedDt =:#{#updatedDt}" +
" where n.id = :#{#noticeManageInsertQo.id}")
void updateNoticeById(@Param("userId") String userId,@Param("updatedDt") Date updatedDt,@Param("noticeManageInsertQo") NoticeManageInsertQo noticeManageInsertQo);
5.如果你的@Query里面要写原生的sql,要记得加上nativeQuery = true