Conditional paging query of SpringDataJPA

One, pom dependence

<!--     SpringBootweb-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        SpringBoot测试类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!--SpringDataJPA-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- Mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
         <!--       thymeleaf模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

Entity class

@Data
@Entity(name = "fastdfsfile")
public class Fastdfsfile {
    
    
    @Id
    private Integer id;
    private String url;
    private String name;
}

JPARepository

public interface FastdfsRespsitory extends JpaRepository<Fastdfsfile,Integer>, JpaSpecificationExecutor<Fastdfsfile> {
    
    
}

2. Conditional query

service code

 /**
     * JPA  条件搜索
     * @param filename
     * @return
     */
    public List<Fastdfsfile> search(String filename) {
    
    
        Specification<Fastdfsfile> Specification = new Specification<Fastdfsfile>() {
    
    
            /**
             * @param root  根对象 : 要把条件封装进哪个对象  目的是将条件封装对象
             * @param criteriaQuery 封装查询的关键字:group by,order by等,其实无用!
             * @param criteriaBuilder 封装条件对象的   目的是封装条件对象
             * @return  如果直接返回null,表示不需要任何条件
             */
            @Override
            public Predicate toPredicate(Root<Fastdfsfile> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    
    
                /**
                 * like()  模糊查询
                 * equal() 直接查询
                 * ------------------------
                 * root.get("labelname").as(String.class)
                 * 从封装的条件对象中获得要查询的字段,该字段是String类型
                 * 参数2 : 具体查询的条件
                 * 即整体的结果就相当于是
                 *  where labelname like "%张三%"
                 *  ------------------------
                 * 如果还有需要查询的条件就再来一个criteriaBuilder.like(...);
                 * 但是该criteriaBuilder.like()返回值是Predicate对象,正是toPredicate的返回值
                 * 如果多个criteriaBuilderlike()就会返回多个Predicate对象,那该如何返回?
                 * -------------------------
                 * criteriaBuilder提供了and(Predicate... p)方法,该方法返回值是Predicate对象
                 * and()方法的参数是Predicate类型的数组,即有多少查询条件就可以使用criteriaBuilder得当多少
                 * Predicate对象,然后放入Predicate类型的数组,再放入and()返回.
                 * 但是不确定有多少查询条件啊?即不确定该Predicate类型的数组的长度啊?
                 * -------------------------
                 * 使用集合存储.集合存储所有criteriaBuilder得当的Predicate对象,然后获得集合长度,利用该长度
                 * 创建数组,然后将该集合中的值传入数组,然后将数组放入and(),最终返回
                 * -------------------------
                 * and() 就好比 where name like "%张三%" and age = 1
                 */
                List<Predicate> list = new ArrayList<>();
                root.get("name").as(String.class);
                if(filename != null && !"".equals(filename)) {
    
    
                    Predicate predicate = criteriaBuilder.like(root.get("name").as(String.class), "%" + filename + "%");
                    list.add(predicate);
                }
                Predicate[] predicates = list.toArray(new Predicate[list.size()]);
                return criteriaBuilder.and(predicates);
            }
        };
        List<Fastdfsfile> all = fastdfsRespsitory.findAll(Specification);
        return all;
    }

test

@SpringBootTest
@RunWith(SpringRunner.class)
public class JPATest {
    
    
    @Autowired
    FastdfsRespsitory respsitory;
    @Autowired
    FileService service;
    @Test
    public void test(){
    
    
        List<Fastdfsfile> list = service.search("周杰伦");
        list.forEach(System.out::println);
    }
}

Result
Insert picture description here
note: Interaction with Thymeleaf
Insert picture description here
Insert picture description here
Insert picture description here

Three, condition paging query

service code

/**
     * JPA 条件+分页 查询
     * @param searchname
     * @param pageNum
     * @param pegeSize
     * @return
     *
     */
    public Page searchAndPage(String searchname, int pageNum, int pegeSize) {
    
    
        // Pageable是接口,PageRequest是其子类
        // jpa的第一页要设置为 0
        Pageable pageable = PageRequest.of(pageNum-1,pegeSize);
        Specification<Fastdfsfile> specification = new Specification<Fastdfsfile>() {
    
    
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
    
    
                List<Predicate> list = new ArrayList<>();
                root.get("name").as(String.class);
                if(searchname != null && !"".equals(searchname)) {
    
    
                    Predicate predicate = criteriaBuilder.like(root.get("name").as(String.class), "%" + searchname + "%");
                    list.add(predicate);
                }
                Predicate[] predicates = list.toArray(new Predicate[list.size()]);
                return criteriaBuilder.and(predicates);
            }
        };
        Page<Fastdfsfile> page = fastdfsRespsitory.findAll(specification, pageable);
        return page;
    }

Page code :

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>FastDFS文件服务器</title>
<!--    <link rel="stylesheet" href="../static/css/login.css">-->
<!--    <link rel="stylesheet" type="text/css" th:href="@{static/css/font-awesome.css}">-->
    <link rel="stylesheet" href="../static/dist/css/bootstrap.css">
    <link rel="stylesheet" href="../static/dist/css/bootstrap.min.css">
    <link rel="stylesheet" th:href="@{../static/dist/js/bootstrap.min.js}">
</head>
<body>
<div class="jumbotron">
    <h1>文件管理</h1>
    <p>文件大小在10M以下,文件越大,速度越慢,请谅解...</p>
<!--    <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>-->
</div>
<!--<form th:action="@{/fastdfs/upload}" enctype="multipart/form-data" method="post" class="form-inline">-->
<!--    <input type="file" name="file" multiple="multiple">-->
<!--    <input type="submit" value="上传">-->
<!--</form>-->

<form class="navbar-form navbar-left" role="search" th:action="@{/fastdfs/upload}" enctype="multipart/form-data" method="post">
    <div class="form-group">
        <input type="file" class="form-control"  name="file" >
    </div>
    <button type="submit" class="btn btn-default">Upload</button>
</form>
<form class="navbar-form navbar-left" role="search" th:action="@{/fastdfs/searchAndPage}" method="get">
    <div class="form-group">
        <input type="text" class="form-control" placeholder="文件名" name="searchname" th:value="${searchname}">
    </div>
    <button type="submit" class="btn btn-default">Search</button>
    <a th:href="@{/fastdfs/searchAndPage}"><button type="button" class="btn btn-default">Clear</button></a>
</form>
<br><br>
<table class="table">
    <tr>
        <td>ID</td>
        <td>文件名</td>
        <td>URL</td>
        <td>操作</td>
    </tr>
    <tr th:each="fastdfsfile : ${fastdfsfiles}">
        <td th:text="${fastdfsfile.id}"> </td>
        <td th:text="${fastdfsfile.name}"> </td>
        <td th:text="${fastdfsfile.url}"> </td>
        <td><a th:href="@{/fastdfs/look(furl=${fastdfsfile.url})}"><span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span></a> &nbsp;
            <a th:href="@{/fastdfs/download(fid=${fastdfsfile.url})}"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></a>&nbsp;
            <a th:href="@{/fastdfs/delete(fid=${fastdfsfile.id},furl=${fastdfsfile.url})}"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a></td>
    </tr>
</table>
<nav aria-label="Page navigation" class="text-center">
    <ul class="pagination pagination-lg">
        <li  aria-label="Previous">
            <a th:href="'/fastdfs/searchAndPage?searchname='+${searchname}+'&pageNum=' + ${pageNo -1}"  th:class="${pageNo}-1 le 0 ? 'btn btn-default btn-lg disabled':'' ">
                <span class="glyphicon glyphicon-chevron-left"></span>
            </a>
        </li>
        <li th:each=" pageNum:${#numbers.sequence(1,totalPages)}" >
            <a th:href="'/fastdfs/searchAndPage?searchname='+${searchname}+'&pageNum=' + ${pageNum}" th:text="${pageNum}" th:if="${pageNum} ne ${pageNo}"></a>
            <a th:href="'/fastdfs/searchAndPage?searchname='+${searchname}+'&pageNum=' + ${pageNum}" th:text="${pageNum}" th:if="${pageNum} eq ${pageNo}" th:style="'font-weight:bold;background: #84C1FF;'"></a>
        </li>
        <li aria-label="Next" >
            <a th:href="@{/fastdfs/searchAndPage(searchname=${searchname},pageNum=${pageNo} + 1)}"  th:class="${pageNo}+1 gt ${totalPages} ? 'btn btn-default btn-lg disabled':'' ">
                <span class="glyphicon glyphicon-chevron-right"></span>
            </a>
        </li>
    </ul>
</nav>
<p th:text="当前页 + ${pageNo}"><p th:text="总页数 + ${totalPages}"><p th:text="总条数 + ${totalElements}">
</body>
</html>

test:
Insert picture description here

BUG1

When using Thymeleaf pages for pagination, the previous page and the next page.
Insert picture description here
Insert picture description here
Solution:
Put +1 outside the curly brackets to add
Insert picture description here

Guess you like

Origin blog.csdn.net/DreamsArchitects/article/details/109237497