学习进度条
在最近的团队项目中,我负责了用户登录和设备管理模块的开发工作。通过这次实践,我深入学习了Spring Boot框架及相关技术的应用,下面将详细介绍我所用到的技术点和实现方案。
项目技术栈概览
- 后端框架:Spring Boot 3.x
- 持久层:MyBatis + MyBatis Dynamic SQL
- 数据库:MySQL
- 安全认证:JWT (JSON Web Token)
- 数据校验:Jakarta Validation
- Excel处理:Apache POI
- 密码加密:MD5
核心功能实现
1. 统一响应格式设计
项目中设计了Result类作为统一的API响应格式:
public class Result<T> {
private Integer code; // 0失败,1成功
private String message; // 提示错误信息
private T data; // 数据
// 成功静态方法
public static <T> Result<T> success(T data) {
return new Result<>(1, "success", data);
}
// 失败静态方法
public static <T> Result<T> error(String message) {
return new Result<>(0, "操作失败" + message, null);
}
}
这种设计使得前端处理响应更加统一,便于错误处理和数据处理。
2. 用户认证与JWT集成
登录流程实现
@PostMapping("/login")
public Result<String> login(@RequestBody @Validated LoginRequest loginRequest) {
User loginUser = userMapper.findByUsername(loginRequest.getUsername());
if(loginUser == null) {
return Result.error("用户名错误");
}
if(Md5Util.getMD5String(loginRequest.getPassword()).equals(loginUser.getPassword())){
Map<String,Object> claims = new HashMap<>();
claims.put("username",loginUser.getUsername());
claims.put("password",loginUser.getPassword());
String token = JwtUtil.genToken(claims);
return Result.success(token);
}
return Result.error("密码错误");
}
关键技术点:
- 使用
@Validated进行请求参数校验 - 密码采用MD5加密存储和验证
- JWT生成包含用户基本信息的token
- 使用ThreadLocal存储当前用户信息
密码修改功能
@PostMapping("/updatePwd")
public Result updatePwd(@RequestBody Map<String, String> params) {
// 参数校验
String oldPwd = params.get("old_pwd");
String newPwd = params.get("new_pwd");
String rePwd = params.get("re_pwd");
// 获取当前用户
Map<String, Object> map = ThreadLocalUtil.get();
String username = map.get("username").toString();
User loginUser = userMapper.findByUsername(username);
// 验证原密码
if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))) {
return Result.error("原密码填写不正确");
}
// 更新密码
String md5NewPwd = Md5Util.getMD5String(newPwd);
userMapper.updatePwd(md5NewPwd, loginUser.getId());
return Result.success();
}
3. 设备管理核心功能
设备实体类设计
@Entity
@Table(name = "device", uniqueConstraints = {
@UniqueConstraint(columnNames = "device_code", name = "idx_device_code")
})
public class Device {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "device_code", length = 64, nullable = false)
private String deviceCode;
@Column(name = "device_name", length = 128, nullable = false)
private String deviceName;
// 其他字段...
}
使用JPA注解定义实体与表的映射关系,包括唯一约束、字段长度等。
分页查询实现
@GetMapping
public Result<PageBean<Device>> list(Integer pageNum, Integer pageSize,
@RequestParam(required = false) String deviceCode,
@RequestParam(required = false) String deviceType,
@RequestParam(required = false) String deviceName,
@RequestParam(required = false) String status) {
PageBean<Device> pb = deviceMapper.list(pageNum,pageSize,deviceCode,deviceType,deviceName,status);
return Result.success(pb);
}
分页核心类:
public class PageBean<T> {
private Long total; // 总条数
private List<T> items; // 当前页数据集合
}
MyBatis动态SQL实现:
class DeviceSqlProvider {
public String selectByCondition(...) {
return new SQL() {{
SELECT("*");
FROM("device");
if (deviceCode != null && !deviceCode.isEmpty()) {
WHERE("device_code LIKE CONCAT('%', #{deviceCode}, '%')");
}
// 其他条件...
ORDER_BY("id DESC");
}}.toString() + " LIMIT #{offset}, #{pageSize}";
}
}
设备导入导出功能
Excel导入:
@PostMapping("/import")
public Result<String> importDevices(@RequestParam("file") MultipartFile file) {
// 验证文件类型
if (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls")) {
return Result.error("只支持Excel文件(.xlsx, .xls)");
}
// 解析Excel
List<Device> devices = ExcelUtil.importExcel(file.getInputStream(), Device.class);
// 批量插入
int result = deviceMapper.batchInsert(devices);
return Result.success("成功导入" + result + "条数据");
}
模板下载:
@GetMapping("/template")
public ResponseEntity<InputStreamResource> downloadTemplate() throws IOException {
ClassPathResource resource = new ClassPathResource("templates/device_template.xlsx");
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.header("Content-Disposition", "attachment; filename=device_template.xlsx")
.body(new InputStreamResource(resource.getInputStream()));
}
关键技术点总结
- MyBatis动态SQL:使用
@SelectProvider实现复杂条件查询,避免SQL注入风险 - 分页查询优化:计算总数和分页数据分离,提高查询效率
- JWT认证:无状态认证机制,适合分布式系统
- Excel处理:使用Apache POI实现数据的导入导出
- RESTful API设计:规范的URL设计和HTTP状态码使用
- 参数校验:使用
@Validated和@Pattern进行输入验证 - CORS处理:通过
@CrossOrigin解决跨域问题
学习收获
通过这个项目,我深入理解了以下知识点:
- Spring Boot的自动配置原理
- MyBatis的Mapper接口与XML映射的多种写法
- JWT的工作机制及在Spring中的集成
- 分页查询的性能优化技巧
- Excel文件处理的常见问题及解决方案
- REST API设计的最佳实践
后续优化方向
- 引入Redis缓存高频访问的设备数据
- 实现更精细化的权限控制
- 添加操作日志记录功能
- 优化Excel导入的性能,支持大数据量导入
- 增加Swagger API文档支持
这个项目让我对Spring Boot生态有了更深入的理解,特别是在数据持久化和API设计方面积累了宝贵经验。希望这篇总结能对其他开发者有所帮助。
学习进度条
今日所花时间:3小时
今日代码量:约300行
博客量:1篇
了解到的知识点:
- MyBatis动态SQL的高级用法
- JWT在Spring Boot中的完整实现
- Excel导入导出的服务端处理
- 复杂分页查询的优化技巧

浙公网安备 33010602011771号