前几天在一个大神的博客中看到有人留言 谈到SpringBoot JPA在复杂的SQL拼接查询时显得力不从心! 不如MyBatis方便
个人感觉有些片面, JPA用好了 开发起来真实感觉太舒服了, 就是学习成本稍微高那么一点点 网上能够给出的好的方案也不是很多
在这里 我就写个例子 提供大家参考
首先是Entity 这是代码片段 其实没啥可以研究的
@Entity
@Table(name = "t_stock_log")
public class StockLog {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private Long userId=0l;//用户Id
@Column(nullable = false)
private String username="";//用户账号
@Column(nullable = false)
private String name="";//用户姓名
@Column(nullable = false)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate = new Date();//发生日期
@Column(nullable = false)
private Integer type=0;//0为减少 1为增加
@Column(nullable = false)
private String des="";//描述
@Column(nullable = false)
private Float num=0f;//变化数量
@Column(nullable = false)
private Float num2=0f;//剩余数量
@Column(nullable = false)
private Integer version=0;
@Column(nullable = false)
private Boolean del=false;
}
让我们的对数据库的操作 简单说明一下 我们的Repository 在这里 继承 JpaSpecificationExecutor<T> 这个接口
可以使用Specification 来进行条件拼接
public interface StockLogRepository extends JpaRepository<StockLog, Long>,JpaSpecificationExecutor<StockLog> {
Page<StockLog> findAll(Specification<StockLog> specification,Pageable pageable);
}
下面在Service 中 拼接我们的查询条件 关键点就在这里
public Page<StockLog> getLogs2(String username, Integer type, Pageable pageable) {
return dao.findAll(new Specification<StockLog>() {
@Override
public Predicate toPredicate(Root<StockLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<>();
list.add(cb.equal(root.get("del").as(Boolean.class), false));
//条件1 用户
if(!StringUtils.isEmpty(username)){
list.add(cb.equal(root.get("username").as(String.class),username));
}
//条件2 类型
if(type!=null){
list.add(cb.equal(root.get("type").as(Integer.class),type));
}
query.where(cb.and(list.toArray(new Predicate[list.size()])));
return query.getRestriction();
}
},pageable);
}
完全面向对象 实现复杂的查询 3层架构 想要更多的条件 只要在list中 add 就可以了 方便 实用 容错率低
有更牛的方法 还须大家发出来一起研究!