个人技术总结——Spring Boot RESTful
| 这个作业属于哪个课程 | FZU_SE_teacherW_4 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
| 这个作业的目标 | 个人技术总结 |
| 其他参考文献 | <<构建之法>> |
目录
- 1.技术概述
- 2.技术详述
- 3.遇到的问题与解决方案
- 4.总结
- 5.参考文献
1.技术概述
- 技术用途:
Spring Boot提供了RESTful API,其具有的快速开发能力,能够轻松实现前后端的交互,使得开发人员可以快速搭建基于Spring的Web应用。
2.技术详述
- 首先在Repository层定义接口。
@Repository
public interface ExerciseRecordRepository extends JpaRepository<ExerciseRecord, String> {
// 获取指定用户最新的运动记录
Optional<ExerciseRecord> findTopByUserIdOrderByExerciseIdDesc(String userId);
// 获取指定用户的所有记录,按开始时间降序排列
List<ExerciseRecord> findByUserIdOrderByStartTimeDesc(String userId);
// 查询指定时间段内的运动记录
List<ExerciseRecord> findByUserIdAndStartTimeBetween(String userId, Date startDate, Date today);
}
- 之后在Controller层提供映射接口。
@RestController
@RequestMapping("/api/exercise-records")
public class ExerciseRecordController {
@Autowired
private ExerciseRecordRepository exerciseRecordRepository;
// 获取用户的所有运动记录
@GetMapping
public List<ExerciseRecord> getAllExerciseRecords(@RequestParam String userId) {
return exerciseRecordRepository.findByUserIdOrderByStartTimeDesc(userId);
}
// 获取指定用户最新的运动记录
@GetMapping("/latest")
public ResponseEntity<ExerciseRecord> getLatestExerciseRecord(@RequestParam String userId) {
Optional<ExerciseRecord> latestRecord = exerciseRecordRepository.findTopByUserIdOrderByExerciseIdDesc(userId);
return latestRecord.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.noContent().build());
}
// 获取一段时间内的消耗热量,按运动种类分类
@SuppressWarnings("deprecation")
@GetMapping("/total-calories")
public ResponseEntity<?> getTotalCalories(@RequestParam String userId, @RequestParam String period) {
// period:"today","week","month","year"
Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
Date startDate;
switch (period) {
case "week":
startDate = getStartOfWeek(today);
break;
case "month":
startDate = getStartOfMonth(today);
break;
case "year":
startDate = getStartOfYear(today);
break;
case "today":
default:
startDate = getStartOfDay(today);
break;
}
List<ExerciseRecord> records = exerciseRecordRepository.findByUserIdAndStartTimeBetween(userId, startDate,
today);
// 计算一段时间内运动消耗的热量...代码较长省略...
}
- 在前端View层调用接口,通过HTTP/AJAX请求接口获取数据并进行渲染。
function fetchCaloriesData(period) {
fetch(`/api/exercise-records/total-calories?userId=${userId}&period=${period}`)
.then(response => response.json())
.then(data => {
// 构造图表所需的数据
const labels = Object.keys(data);
const values = Object.values(data);
// 绘制图表
drawChartCalories(labels, values);
})
.catch(error => console.error("获取数据失败:", error));
}
// 查看历史运动记录
function viewHistory() {
if (isViewHistory === false) {
fetch(`/api/exercise-records?userId=${userId}`)
.then(response => response.json())
.then(data => {
let tableHTML = `<table>
<tr>
<th>运动类型</th>
<th>运动时长/分钟</th>
<th>运动距离/公里</th>
<th>消耗卡路里/千卡</th>
<th>开始时间</th>
<th>结束时间</th>
</tr>`;
data.forEach(record => {
tableHTML += `<tr>
<td>${record.type}</td>
<td>${formatDuration(record.duration)}</td>
<td>${record.distance}</td>
<td>${record.calories}</td>
<td>${new Date(record.startTime).toLocaleString()}</td>
<td>${record.endTime ? new Date(record.endTime).toLocaleString() : '进行中'}</td>
</tr>`;
});
tableHTML += '</table>';
document.getElementById('history').innerHTML = tableHTML;
document.getElementById('history').style.display = 'block'; // 显示历史记录
});
isViewHistory = true;
document.getElementById('viewHistoryButton').textContent = '隐藏历史记录';
}
else {
document.getElementById('history').style.display = 'none'; // 隐藏历史记录
isViewHistory = false;
document.getElementById('viewHistoryButton').textContent = '查看历史记录';
}
}
}
3.遇到的问题与解决方案
- 问题1:数据查询效率低
在 getAllExerciseRecords 和 getLatestExerciseRecord 接口中,直接查询数据库中的全部记录或最新记录,随着数据量的增加,查询时间变长,性能下降。 - 解决方案:
在数据库中为查询字段(如 userId 和 startTime)建立索引,提高查询效率。
使用分页技术,在查询用户所有记录时,限制返回的记录数量,并允许前端通过分页请求获取数据:
@GetMapping
public Page<ExerciseRecord> getAllExerciseRecords(
@RequestParam String userId,
@RequestParam int page,
@RequestParam int size
) {
Pageable pageable = PageRequest.of(page, size, Sort.by("startTime").descending());
return exerciseRecordRepository.findByUserId(userId, pageable);
}
- 问题2:前端数据展示性能问题
前端在展示历史记录时,直接加载所有数据可能导致页面卡顿或崩溃。 - 解决方案:
分页加载: 修改前端调用接口时传递分页参数。
后端返回分页结果,前端实现“加载更多”功能。
fetch(`/api/exercise-records?userId=${userId}&page=${currentPage}&size=${pageSize}`)
4.总结
Spring Boot 提供了自动化配置和快速开发能力,配合 JpaRepository 实现复杂查询逻辑,简化了代码
接口设计。
合理设计 RESTful API 的路径和数据格式,不仅让接口更清晰,还提高了前后端协作的效率。
5.参考文献
相关推荐
Personal-Tech-Blog:使用Java Spring Boot框架+ MySQL数据库+语义UI前端UI框架构建自己的个人技术博客
个人技术博客 使用Java Spring Boot框架+ MySQL数据库+语义UI前端UI框架来构建您自己的个人技术博客。 可以通过访问该网站演示
基于Spring Boot的JavaWeb个人博客系统大作业完整实现
简介:本项目是一个基于Spring Boot框架开发的Java Web个人博客系统,结合MySQL数据库与主流Web技术,构建了一个功能完整、易于扩展的博客平台。系统支持用户注册登录、博客文章的增删改查、评论管理、搜索分页、权限控制等核心功能,采用MVC架构模式,集成JPA或MyBatis进行数据持久化,并通过Thymeleaf等模板引擎实现前后端交互。项目还引入Redis缓存、Spring Security安全认证、日志管理和异常处理机制,全面提升性能与安全性。
基于spring boot的个人博客网站项目+ppt
采用前后台分离 后端:Spring Boot + Mybatis + thymeleaf模板 数据库:MySQL+Redis 前端UI:Semantic UI框架
基于spring boot+mybatis的个人博客(前端+后台管理系统).zip
基于spring boot+mybatis的个人博客(前端+后台管理系统)
个人博客系统设计,基于spring的个人博客系统设计
完整的个人博客设计源程序。



