项目管理功能,目前还剩下条件查询还没实现。
经过这么多章,可以看出用得套路都是差不多的。就像条件查询这个功能,我需要在后端实现一个条件查询的接口,供前端调用。
前端需要在组件里实现对应的方法与后端进行交互,最后页面查询按钮上绑定对应的方法。
一、后端
由于JPA也是支持动态查询的,所以优先还是使用现成的。
1.dao层
在dao层里需要做个修改,让ProjectDAO
再多继承一个类:
JpaSpecificationExecutor
。
package com.mock.platform.dao; import com.mock.platform.pojo.Project; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; public interface ProjectDAO extends JpaRepository<Project, Integer>, JpaSpecificationExecutor { }
可以看一下JpaSpecificationExecutor
类,提供了5个方法,不过每个方法都有一个Specification<T> var1
,这里是关键哦。
2.service层
这里是修改的重点,谁叫它是干活的呢。
public Page<Project> searchProject(Project project, int number, int size) { Sort sort = Sort.by(Sort.Direction.DESC, "id"); Pageable pageable = PageRequest.of(number - 1, size , sort); Specification<Project> query = new Specification<Project>() { @Override public Predicate toPredicate(Root<Project> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { List<Predicate> predicates = new ArrayList<>(); if (project.getId() != null) { predicates.add(criteriaBuilder.equal(root.get("id"), project.getId())); } if (StringUtils.isNotEmpty(project.getProjectName())) { predicates.add(criteriaBuilder.like(root.get("projectName"), "%" + project.getProjectName() + "%")); } return criteriaBuilder.and(predicates.toArray(new Predicate[0])); } }; return projectDAO.findAll(query, pageable); }
这里就用了上述5个方法的第3个,因为查询后的结果也需要分页。
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
代码里实现的是可以通过项目名称或者项目id来查询,以项目名称为例:
predicates.add(criteriaBuilder.like(root.get("projectName"), "%" + project.getProjectName() + "%"));
"projectName"
对应project
实体里的projectName
属性。root.get("projectName")
获取属性对应的数据库表字段。project.getProjectName()
获取当前传入的查询条件值。like
就是模糊匹配了,配合%xxx%
使用。criteriaBuilder
会构建出对应的sql
语句 。
当然这只是一个简单查询,and
或者or
就不展开了,后面用到的时候再说。
3.controller
这里就很简单了,因为活儿都派给service
了。
@GetMapping("/searchProject") public Object searchProject(Project project, int number, int size) throws Exception { return Result.success(projectService.searchProject(project, number, size)); }
测试通过。
二、前端
前端这次只需要改动project.vue
就好了,增加对应的查询方法。
对了,在此之前,还要增加对应的api 。
//src/api/project.js export function searchProject(projectName, number, size) { return request({ url: '/my_platform/project/searchProject', method: 'get', params: { 'projectName': projectName, 'number': number, 'size': size } }) }
vue组件里methods
里增加对应的方法.
当projectName
是空的时候,如果点击了查询
按钮,就重新请求下列表页。
当projectName
不为空,那就可以调用搜索项目的方法 searchProject()
。
handleProjectSearch() { //条件查询 if (this.listQueryInfo.projectName === undefined || this.listQueryInfo.projectName === '') { this.projectGet() } else { searchProject(this.listQueryInfo.projectName, this.pageInfo.number, this.pageInfo.size).then(response => { this.list = response.data.content this.pageInfo.size = response.data.size this.pageInfo.number = response.data.number + 1 this.pageInfo.totalElements = response.data.totalElements this.pageInfo.totalPages = response.data.totalPages this.pageInfo.numberOfElements = response.data.numberOfElements this.listLoading = false }) } }
页面元素部分,就是改动查询条件输入框和查询按钮部分。
<div class="filter-container"> <el-input placeholder="项目名称" style="width: 200px;" class="filter-item" v-model="listQueryInfo.projectName" @keyup.enter.native="handleProjectSearch(listQueryInfo.projectName)" clearable/> <el-button class="filter-item" type="primary" icon="el-icon-search" style="margin-left:10px;" @click="handleProjectSearch(listQueryInfo.projectName)"> 查询 </el-button> <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="projectCreate(createInfo)"> 新建 </el-button> </div>
@keyup.enter.native
属性可以敲回车键查询 ,clearable
则是增加一个清空输入的按钮。
全部弄完了,测试一下模糊查询。
通过。
后面的功能实现基本都是这样的套路了,应该不会像这样前后端铺开写了,有知识点或者思路想法之类的会记录。