项目管理功能,目前还剩下条件查询还没实现。
经过这么多章,可以看出用得套路都是差不多的。就像条件查询这个功能,我需要在后端实现一个条件查询的接口,供前端调用。
前端需要在组件里实现对应的方法与后端进行交互,最后页面查询按钮上绑定对应的方法。
一、后端
由于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
则是增加一个清空输入的按钮。
全部弄完了,测试一下模糊查询。
通过。
后面的功能实现基本都是这样的套路了,应该不会像这样前后端铺开写了,有知识点或者思路想法之类的会记录。