1.更新用户基本信息
controller类:
javascript
@PutMapping("/update")
//@RequestBody 把前端传递的json字符串转换成User对象
public Result update(@RequestBody @Validated User user){
//获取当前登录用户id");
userService.update(user);
return Result.success();
}
ServiceImpl:
javascript
@Override
public void update(User user) {
user.setUpdateTime(LocalDateTime.now());
userMapper.update(user);
}
@RequestBody 是 Spring 框架中用于接收 HTTP 请求体(Request Body) 的注解,通常用于处理 POST、PUT 等请求方式,将请求体中的 JSON/XML 数据反序列化为 Java 对象。
参数校验:
如果要对实体参数进行校验
1.在实体类中添加注解:
javascript
package com.itheima.pojo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@NotNull //让springmvc在接收请求参数的时候,对id这个属性进行非空校验
private Integer id;//主键ID
private String username;//用户名
@JsonIgnore//让springmvc把当前对象转换成json字符串的时候,忽略password,最终的json字符串中就没有password这个属性
private String password;//密码
@NotEmpty
@Pattern(regexp = "^\\S{1,10}$")
private String nickname;//昵称
@NotEmpty
@Email
private String email;//邮箱
private String userPic;//用户头像地址
private LocalDateTime createTime;//创建时间
private LocalDateTime updateTime;//更新时间
}

2在controller类中实体类参数前面添加@Validated
javascript
@PutMapping("/update")
//@RequestBody 把前端传递的json字符串转换成User对象更新
public Result update(@RequestBody @Validated User user){
//获取当前登录用户id");
userService.update(user);
return Result.success();
}
2.更新用户头像
此时用patch的请求方式;
PATCH:适用于只需要更新资源的部分字段的场景。比如,用户只想修改自己的邮箱地址,而不希望修改其他信息,此时使用 PATCH 方法就非常合适。
Controller类:
javascript
@PatchMapping("updateAvatar")
public Result updateAvatar(@RequestParam @URL String avatarUrl){
userService.updateAvatar(avatarUrl);
return Result.success();
}
@RequestParam 是 Spring MVC/Spring Boot 里用来接收 URL 查询参数 或 表单字段 的核心注解。
一句话:它把 ?key=value 里的 value 注入到方法参数中。
ServiceImpl:
javascript
@Override
public void updateAvatar(String avatarUrl) {
//获取当前登录用户的id
Map<String,Object> map= ThreadLocalUtil.get();
Integer id = (Integer) map.get("id");
userMapper.updateAvatar(avatarUrl,id);
}
更新时间
如果是实体类对象那么就可以在ServiceImpl里面编写如下代码:
javascript
user.setUpdateTime(LocalDateTime.now());
因为可以通过修改user里面的updateTime来更新创建时间:
如果不是那么就可以直接在mapper里面的sql语句中直接调用now()
javascript
update_time = now()
参数校验:@URL来检验是否为url

3.更新密码的操作:
controller:
javascript
@PatchMapping("/updatePwd")
public Result updatePwd(@RequestBody Map<String,String> params){
//1.校验参数
String oldPwd = params.get("old_pwd");
String newPwd = params.get("new_pwd");
String rePwd = params.get("re_pwd");
if(!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)){
return Result.error("缺少必要参数");
}
//原密码是否正确
//调用UserService根据用户名得到原密码在和oldPwd进行比对
Map<String,Object> map = ThreadLocalUtil.get();
String username = (String) map.get("username");
User loginUser = userService.findByUsername(username);
if(!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))) {
return Result.error("原密码错误");
}
//newPwd和rePwd是否一致
if(!rePwd.equals(newPwd)){
return Result.error("两次密码不一致");
}
//2.调用service完成 密码更新
userService.updatePwd(newPwd);
return Result.success();
}
javascript
@Override
public void updatePwd(String newPwd) {
Map<String,Object> map= ThreadLocalUtil.get();
Integer id = (Integer) map.get("id");
userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);
}
- 让密码加密的操作:
- Md5Util.getMD5String(newPwd)
新增文章分类
javascript
@PostMapping
public Result add(@RequestBody @Validated(Category.Add.class) Category category){
categoryService.add(category);
return Result.success();
}
javascript
@Override
public void add(Category category) {
//补充属性
category.setCreateTime(LocalDateTime.now());
category.setUpdateTime(LocalDateTime.now());
Map<String, Object> map = ThreadLocalUtil.get();
Integer userId = (Integer) map.get("id");
category.setCreateUser(userId);
categoryMapper.add(category);
}

文章分类列表:
javascript
@GetMapping
public Result<List<Category>> list(){
List<Category> cs= categoryService.list();
return Result.success(cs);
}
javascript
@Override
public List<Category> list() {
Map<String,Object> map = ThreadLocalUtil.get();
Integer userid = (Integer) map.get("id");
return categoryMapper.list(userid);
}
指定日期的格式:

获取文章分类详情:
javascript
@GetMapping("/detail")
public Result detail(Integer id){
Category c = categoryService.findById(id);
return Result.success(c);
}
javascript
@Override
public Category findById(Integer id) {
Category c = categoryMapper.findById(id);
return c;
}
更新文章分类:
javascript
@PutMapping
public Result update(@RequestBody @Validated(Category.Update.class) Category category){
categoryService.update(category);
return Result.success();
}
javascript
@Override
public void update(Category category) {
category.setUpdateTime(LocalDateTime.now());
categoryMapper.update(category);
}
*分组校验:
1定义分组:
javascript
public interface Add extends Default {
}
public interface Update extends Default{
}
2.
javascript
public class Category {
@NotNull(groups = Update.class)
private Integer id;//主键ID
@NotEmpty
private String categoryName;//分类名称
@NotEmpty
private String categoryAlias;//分类别名
private Integer createUser;//创建人ID
@JsonFormat(pattern = "yyyy-HH-dd HH:mm:ss")
private LocalDateTime createTime;//创建时间
@JsonFormat(pattern = "yyyy-HH-dd HH:mm:ss")
private LocalDateTime updateTime;//更新时间
//如果说某个某个校验项没有指定分组,默认属于Default分组
//相当于就是如果继承了Default 那么就应该遵循所有的限制 除非有个限制被指定为某一组
//分组之间可以继承,A extend B 那么A分组就拥有B分组的校验项
public interface Add extends Default {
}
public interface Update extends Default{
}
新增文章
javascript
@PostMapping
public Result add(@RequestBody @Validated Article article){
articleService.add(article);
return Result.success();
}
javascript
@Override
public void add(Article article) {
//补充属性
article.setCreateTime(LocalDateTime.now());
article.setUpdateTime(LocalDateTime.now());
Map<String,Object> map = ThreadLocalUtil.get();
Integer userId = (Integer) map.get("id");
article.setCreateUser(userId);
articleMapper.add(article);
}
参数校验:

javascript
public class Article {
@NotNull
private Integer id;//主键ID
@NotEmpty
@Pattern(regexp = "^\\S{1,10}$")
private String title;//文章标题
@NotEmpty
private String content;//文章内容
@NotEmpty
@URL
private String coverImg;//封面图像
@State
private String state;//发布状态 已发布|草稿
@NotNull
private Integer categoryId;//文章分类id
private Integer createUser;//创建人ID
private LocalDateTime createTime;//创建时间
private LocalDateTime updateTime;//更新时间
}
自定义校验:

1.创建anno包 创建自定义State接口
javascript
@Documented//元注解
@Target({ElementType.FIELD})//元注解 State注解适用的地方 Field属性,
@Retention(RetentionPolicy.RUNTIME)//元注解 会保留到哪个阶段 runtime:运行阶段
@Constraint(validatedBy = {StateValidation.class})//指定提供校验规则的类
public @interface State {
//提供校验失败后的提示信息
String message() default "state参数值只能是已发布或草稿";
//指定分组
Class<?>[] groups() default {};
//负载 获取到State注解的附加信息
Class<? extends Payload>[] payload() default {};
}
2.创建validation包 StateValidation类
javascript
package com.itheima.validation;
import com.itheima.anno.State;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
//ConstraintValidator<给哪个注解提供校验规则,校验的数据类型>
public class StateValidation implements ConstraintValidator<State,String> {
/**
*
* @param s 将来要检验的数据
* @param constraintValidatorContext
* @return 结果如果是true 校验通过
* 结果如果是false 校验失败
*/
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
//提供校验规则
if(s == null){
return false;
}
if(s.equals("已发布") || s.equals("草稿")){
return true;
}
return false;
}
}
3.在要校验的地方写上注解
javascript
@State
private String state;//发布状态 已发布|草稿
文章列表查询(条件分页)
1.先在pojo导入写好的PageBean类:
javascript
package com.itheima.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
//分页返回结果对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{
private Long total;//总条数
private List<T> items;//当前页数据集合
}
javascript
@GetMapping
public Result<PageBean<Article>> list(
Integer pageNum,
Integer pageSize,
@RequestParam(required = false)Integer categoryId,
@RequestParam(required = false)String state
){
PageBean<Article> pb=articleService.list(pageNum,pageSize,categoryId,state);
return Result.success(pb);
}
PageHelper依赖:
javascript
<!-- PageHelper分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
javascript
@Override
public PageBean<Article> list (Integer pageNum, Integer pageSize, Integer categoryId, String state) {
//1.创建PageBean对象
PageBean<Article> pb = new PageBean<>();
//2.开启分页查询 借助于PageHelper
PageHelper.startPage(pageNum,pageSize);
//3.调用mapper查询文章列表
Map<String,Object> map = ThreadLocalUtil.get();
Integer userId = (Integer) map.get("id");
List<Article> as = articleMapper.list(userId,categoryId,state);
//Page中提供了方法,可以获取PageHelper分页查询后,得到的总记录条数和当前页数据
Page<Article> p = (Page<Article>) as;
//把数据填充到PageBean中
pb.setTotal(p.getTotal());
pb.setItems(p.getResult());
return pb;
}
通过映射配置文件编写动态sql

mapper namespace里面编写的是ArticleMapper的位置
select id里面写的是方法名字 resultType写的是多条数据对应的数据类型
javascript
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.ArticleMapper">
<!--动态sql-->
<select id = "list" resultType="com.itheima.pojo.Article">
select * from article
<where>
<if test = "categoryId!=null" >
category_id =#{categoryId}
</if>
<if test = "state!=null" >
and state =#{state}
</if>
and create_user= #{userId}
</where>
</select>
</mapper>
文件上传
javascript
package com.itheima.controller;
import com.itheima.pojo.Result;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class FileUploadController {
@PostMapping("/upload")
public Result<String> upload(MultipartFile file) throws IOException {
//把文件的内容存储到本地磁盘
String originalFilename = file.getOriginalFilename();
//保证文件名唯一 防止文件覆盖
String filename = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
file.transferTo(new File("C:\\Users\\蛋堡\\Desktop\\file\\"+filename));
return Result.success("url访问地址");
}
}