SpringBoot + Vue 实现查询

发布于 2025-10-24 12:50:11 浏览 20 次

SpringBoot + Vue 实现 “查询” 功能的核心是:前端发起查询请求(可携带条件),后端接收请求后从数据库查询数据,再将结果返回给前端展示。查询功能根据场景可分为单条数据查询(如根据 ID 查询详情)和多条数据查询(如列表分页查询、条件筛选),以下详细说明实现流程。
一、核心流程拆解
前端发起查询请求
单条查询:通过唯一标识(如 ID)触发请求(例如点击 “查看详情” 按钮)。
列表查询:页面加载时默认查询,或用户输入筛选条件(如姓名、日期范围)后提交查询。
后端接收并处理请求
SpringBoot 接收请求参数(如 ID、分页参数、筛选条件),调用 Service 层组装查询条件,再通过 Dao 层执行 SQL 查询(如 SELECT 语句)。
返回数据给前端
后端将查询结果(单条对象或分页列表)封装成统一格式,通过 HTTP 响应返回给前端。
前端展示数据
Vue 接收数据后,渲染到页面(如详情页展示单条数据,表格展示列表数据)。
二、前后端关键代码示例

  1. 单条数据查询(根据 ID 查询详情)

适用于查看某条记录的详细信息(如用户详情、订单详情)。
前端(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>
  1. 多条数据查询(分页 + 条件筛选)

适用于列表展示(如用户列表、订单列表),支持分页(避免数据量过大)和条件筛选(如按姓名模糊查询、按年龄范围查询)。
前端(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 逻辑。查询评价页面如下
image.png

0 条评论

发布
问题