SpringBoot + Vue 实现 “查询” 功能的核心是:前端发起查询请求(可携带条件),后端接收请求后从数据库查询数据,再将结果返回给前端展示。查询功能根据场景可分为单条数据查询(如根据 ID 查询详情)和多条数据查询(如列表分页查询、条件筛选),以下详细说明实现流程。
一、核心流程拆解
前端发起查询请求
单条查询:通过唯一标识(如 ID)触发请求(例如点击 “查看详情” 按钮)。
列表查询:页面加载时默认查询,或用户输入筛选条件(如姓名、日期范围)后提交查询。
后端接收并处理请求
SpringBoot 接收请求参数(如 ID、分页参数、筛选条件),调用 Service 层组装查询条件,再通过 Dao 层执行 SQL 查询(如 SELECT 语句)。
返回数据给前端
后端将查询结果(单条对象或分页列表)封装成统一格式,通过 HTTP 响应返回给前端。
前端展示数据
Vue 接收数据后,渲染到页面(如详情页展示单条数据,表格展示列表数据)。
二、前后端关键代码示例
适用于查看某条记录的详细信息(如用户详情、订单详情)。
前端(Vue)代码
vue
<template>
<div class="user-detail">
<h3>用户详情</h3>
<p>ID:{{ user.id }}</p>
<p>姓名:{{ user.name }}</p>
<p>年龄:{{ user.age }}</p>
<p>邮箱:{{ user.email }}</p>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
user: {} // 存储查询到的用户详情
}
},
created() {
// 从路由参数中获取用户ID(如URL为 /user/detail/123,则id=123)
const userId = this.$route.params.id
this.fetchUserDetail(userId)
},
methods: {
fetchUserDetail(id) {
// 发送GET请求查询单条数据
axios.get(`/api/user/detail/${id}`)
.then(response => {
if (response.data.success) {
this.user = response.data.data // 赋值给user,用于页面渲染
} else {
alert('查询失败:' + response.data.msg)
}
})
.catch(error => {
console.error('请求出错:', error)
})
}
}
}
</script>后端(SpringBoot)代码
Controller 层:接收 ID 参数,调用 Service 查询
java
运行
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
// 根据ID查询用户详情
@GetMapping("/detail/{id}")
public Result getUserDetail(@PathVariable Long id) {
User user = userService.getById(id);
if (user == null) {
return Result.error("用户不存在");
}
return Result.success(user);
}
}
Service 层:调用 Dao 层查询
java
运行
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getById(Long id) {
return userMapper.selectById(id); // 调用MyBatis查询
}
}Dao 层(MyBatis):
java
运行
@Mapper
public interface UserMapper {
// 根据ID查询
User selectById(Long id);
}
xml
<!-- UserMapper.xml -->
<select id="selectById" parameterType="Long" resultType="com.example.entity.User">
SELECT id, name, age, email FROM user WHERE id = #{id}
</select>适用于列表展示(如用户列表、订单列表),支持分页(避免数据量过大)和条件筛选(如按姓名模糊查询、按年龄范围查询)。
前端(Vue)代码
vue
<template>
<div class="user-list">
<!-- 筛选条件表单 -->
<div class="search-form">
<input v-model="searchParams.name" placeholder="请输入姓名" />
<input v-model="searchParams.minAge" type="number" placeholder="最小年龄" />
<input v-model="searchParams.maxAge" type="number" placeholder="最大年龄" />
<button @click="fetchUserList">查询</button>
</div>
<!-- 数据表格 -->
<table>
<thead>
<tr><th>ID</th><th>姓名</th><th>年龄</th><th>邮箱</th></tr>
</thead>
<tbody>
<tr v-for="user in userList" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
<td>{{ user.email }}</td>
</tr>
</tbody>
</table>
<!-- 分页控件 -->
<div class="pagination">
<button @click="changePage(currentPage - 1)" :disabled="currentPage === 1">上一页</button>
<span>第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
<button @click="changePage(currentPage + 1)" :disabled="currentPage === totalPages">下一页</button>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
searchParams: { // 筛选条件
name: '',
minAge: null,
maxAge: null
},
userList: [], // 存储查询到的用户列表
currentPage: 1, // 当前页码
pageSize: 10, // 每页条数
total: 0, // 总记录数
totalPages: 0 // 总页数
}
},
created() {
this.fetchUserList() // 页面加载时默认查询第一页
},
methods: {
fetchUserList() {
// 构造查询参数:包含分页信息和筛选条件
const params = {
pageNum: this.currentPage,
pageSize: this.pageSize,
name: this.searchParams.name,
minAge: this.searchParams.minAge,
maxAge: this.searchParams.maxAge
}
// 发送GET请求(参数通过URL拼接)
axios.get('/api/user/list', { params })
.then(response => {
if (response.data.success) {
const data = response.data.data
this.userList = data.records // 列表数据
this.total = data.total // 总记录数
this.totalPages = Math.ceil(this.total / this.pageSize) // 计算总页数
}
})
},
changePage(page) {
if (page < 1) return
this.currentPage = page
this.fetchUserList() // 切换页码后重新查询
}
}
}
</script>后端(SpringBoot)代码
分页查询参数封装:定义 DTO 接收前端分页和筛选条件
java
运行
// UserQueryDTO.java
public class UserQueryDTO {
private Integer pageNum = 1; // 默认第一页
private Integer pageSize = 10; // 默认每页10条
private String name; // 姓名(模糊查询)
private Integer minAge; // 最小年龄
private Integer maxAge; // 最大年龄
// 省略getter、setter
}
Controller 层:接收查询参数,返回分页结果
java
运行
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
// 分页查询用户列表(带条件筛选)
@GetMapping("/list")
public Result getUserList(UserQueryDTO queryDTO) {
// 调用Service查询,返回MyBatis-Plus的IPage对象
IPage<User> page = userService.listPage(queryDTO);
return Result.success(page);
}
}Service 层:组装查询条件,执行分页查询(以 MyBatis-Plus 为例,简化分页逻辑)
java
运行
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public IPage<User> listPage(UserQueryDTO queryDTO) {
// 构建分页对象(当前页、每页条数)
IPage<User> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
// 构建查询条件(使用MyBatis-Plus的QueryWrapper)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 姓名模糊查询(如输入“张”,查询所有姓张的用户)
if (StringUtils.hasText(queryDTO.getName())) {
queryWrapper.like("name", queryDTO.getName());
}
// 年龄范围查询(如minAge=18,maxAge=30,查询18-30岁的用户)
if (queryDTO.getMinAge() != null) {
queryWrapper.ge("age", queryDTO.getMinAge());
}
if (queryDTO.getMaxAge() != null) {
queryWrapper.le("age", queryDTO.getMaxAge());
}
// 执行分页查询
return userMapper.selectPage(page, queryWrapper);
}
}Dao 层:直接使用 MyBatis-Plus 的 BaseMapper(无需手动写 SQL)
java
运行
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 继承BaseMapper后,无需手动实现selectPage方法
}三、关键注意事项
分页插件配置若使用 MyBatis-Plus 实现分页,需在 SpringBoot 中配置分页插件,否则分页不生效:
java
运行
@Configuration
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}条件查询的灵活性实际开发中,筛选条件可能更复杂(如日期范围、多字段组合查询),可通过动态 SQL 动态拼接条件(MyBatis 的<if>标签)或 MyBatis-Plus 的 QueryWrapper 实现灵活拼接。
性能优化
避免查询不必要的字段(如只查列表展示所需的字段,而非全表字段)。
对频繁查询的字段建立索引(如name、age),提升查询速度。
大数据量场景下,可考虑分页查询 + 异步加载,避免页面卡顿。
空值处理前端筛选条件可能为空(如用户未输入姓名),后端需判断参数是否为空,避免因空值导致查询异常(如like null会查询不到数据)。
通过以上实现,SpringBoot + Vue 可灵活支持单条查询和分页条件查询,核心是前端正确传递参数、后端准确组装查询条件并返回数据,最终由前端渲染展示。如需更复杂的查询场景(如联表查询),可在此基础上扩展 Dao 层的 SQL 逻辑。查询评价页面如下