关于spring-data-jpa的使用

前提

  • 1、需要实体类与数据库中的指定表绑定,并绑定指定列,如下
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_label")   //绑定数据库中的那张表,如果有多个主键,就在对应上面加上该注解
@Entity    //将改实体类注入容器中
public class Label implements Serializable {
  
   @Id              // 主键必须要有的,与数据库中的主键绑定
   private String id;
 
   @Column(name = "labelName")   //如果改字段与数据库中的列名不一样,自己可以指定
   private String labelname;
  • 2、写一个接口继承JpaRepository<Label,String>
public interface LabelDao extends JpaRepository<Label,String>, JpaSpecificationExecutor<Label> {

}
参数 说明
第一个参数 绑定的实体类
第二个参数 ,该实体类主键的类型

该接口可以实现基本的增删该查,但是如果还需要条件查询,则还需要继承另一个接口
JpaSpecificationExecutor<Label;>
其关系结构如下

1、简单的增删改查

使用刚刚的接口即可

labelDao.save(Label label)  //增,改
label.deleteById(String id) //删
label.findById(String id) //查

2、条件查询

如果只是一个条件,完成后就可以直接返回,如果是多个则需要使用组合,下面是3个条件

/**
     * 构建查询条件
     * @param label 查询的条件label对象
     * @return
     */
    public Specification<Label> createSpecification(Label label){
        return new Specification<Label>() {
            /**
             *
             * @param root 获取匹配的对象条件
             * @param cq   order by , group by 等。一般用不到,一般我们直接写sql语句
             * @param cb  链接参数对象
             * @return
             */
            @Override
            public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<>();

                if(!StringUtils.isEmpty(label.getLabelname())){
                    Predicate predicate = cb.like(root.get("labelname").as(String.class), "%" + label.getLabelname() + "%");
                    predicateList.add(predicate);
                }

                if(!StringUtils.isEmpty(label.getState())){
                    Predicate predicate = cb.equal(root.get("state").as(String.class), label.getState());
                    predicateList.add(predicate);
                }

                if(!StringUtils.isEmpty(label.getRecommend())){
                    Predicate predicate = cb.equal(root.get("recommend").as(String.class),label.getRecommend() );
                    predicateList.add(predicate);
                }
//                Predicate[] array = (Predicate[]) predicateList.toArray();
//                直接使用会出现如下错误
//                [Ljava.lang.Object; cannot be cast to [Ljavax.persistence.criteria.Predicate;

                Predicate[] array = new Predicate[predicateList.size()];
                predicateList.toArray(array);
                return cb.and(array);
            }
        };
    }

    /**
     * 根据条件查询所有的标签
     * @param label 条件,即label实体类
     * @return
     */
    public List<Label> findSearch(Label label){
        Specification<Label> specification = createSpecification(label);
        //select * from tb_label where labelname like "%条件%" and state=条件 and recommed = 条件
        return labelDao.findAll(specification);
    }

3、分页条件查询

分页查询只是在find方法参数里面加了一个另一个参数,如下即可(页码内部是从0开始的,如果从前端发过来是1,则需要 -1 来完成操作

/**
     * 根据条件查询标签信息,并分页
     * @param label  查询的条件
     * @param page   查询多少页,从第1页开始
     * @param size   每页查询多少条
     * @return    page<Label>
     */
    public Page<Label> findSearchPage(Label label,int page,int size){
        //因为代码内部是从0开始的页数
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        Specification<Label> specification = createSpecification(label);
        //返回的是 Page<T>
        return labelDao.findAll(specification, pageRequest);
    }

后面可以通过

 Page<Label> pageList = labelService.findSearchPage(label, page, size);
 pageList.getTotalElements() //总的数据量
 pageList.getContent() //获取该次分页查询的数据

4、通过命名规则来完成查询

在之前的空的接口中,根据命名规则写一个方法

#查询状态为2并以创建日期降序排序,查询前4条记录

List<Label> findTop4ByStateOrderByCreatetimeDesc(String state);
-----------------------------------------------------
其内部就会根据你的命名规则去查询

接下来service层就可以去调用了

5、通过写sql语句来完成查询

前面的方法都只能单表查询,如果多表的话,只能自己写sql语句去执行了!
如果只是查询用一个query即可,但是如果需要修改数据就再加一个注解== @Modifying==

/**
     * 根据标签id 查询该标签下的 最新问答列表,并分页
     * @param labelId  标签id
     * @param pageable  分页数据
     * @return
     */
     // @Modifying
    @Query(value = "SELECT * FROM tb_pl pl ,tb_problem pro WHERE pl.problemid = pro.id AND pl.labelid = ? ORDER BY pro.createtime DESC",
            nativeQuery = true)
    Page<Problem> findNewProblemList(String labelId, Pageable pageable);

总结一下,如果需要分页需要将pageable对象传入(pagerequest是它的子类),其返回值是page ,分页的数据和总条数都在该对象中!需要去拿即可!(参考前面3)

猜你喜欢

转载自blog.csdn.net/qq_38263083/article/details/86570945