配套视频地址:https://www.bilibili.com/video/BV1dG4y1T7yp/
后端
1. 项目初始化
- 创建springboot项目:2.7.8
- pom依赖
<!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency><!-- freemarker --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
- yml
server:port:9999spring:datasource:username: root password:123456url: jdbc:mysql:///xdblogging:level:com.lantu: debug
- 测试
2. Mybatis-plus代码生成
- 编写代码生成器
publicstaticvoidmain(String[] args){String url ="jdbc:mysql:///xdb";String username ="root";String password ="123456";String author ="laocai";String outputDir ="D:\\tmp\\spring\\x-admin\\src\\main\\java";String basePackage ="com.lantu";String moduleName ="sys";String mapperLocation ="D:\\tmp\\spring\\x-admin\\src\\main\\resources\\mapper\\"+ moduleName;String tableName ="x_user,x_menu,x_role,x_role_menu,x_user_role";String tablePrefix ="x_";FastAutoGenerator.create(url, username, password).globalConfig(builder ->{ builder.author(author)// 设置作者.enableSwagger()// 开启 swagger 模式//.fileOverride() // 覆盖已生成文件.outputDir(outputDir);// 指定输出目录}).packageConfig(builder ->{ builder.parent(basePackage)// 设置父包名.moduleName(moduleName)// 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, mapperLocation));// 设置mapperXml生成路径}).strategyConfig(builder ->{ builder.addInclude(tableName)// 设置需要生成的表名.addTablePrefix(tablePrefix);// 设置过滤表前缀}).templateEngine(newFreemarkerTemplateEngine())// 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}
- 启动类加注解
@MapperScan("com.lantu.*.mapper")
- 测试
3. 公共响应类
@Data@NoArgsConstructor@AllArgsConstructorpublicclassResult<T>{privateInteger code;privateString message;privateT data;publicstatic<T>Result<T>success(){returnnewResult<>(20000,"success",null);}publicstatic<T>Result<T>success(T data){returnnewResult<>(20000,"success",data);}publicstatic<T>Result<T>success(T data,String message){returnnewResult<>(20000,message,data);}publicstatic<T>Result<T>success(String message){returnnewResult<>(20000,message,null);}publicstatic<T>Result<T>fail(){returnnewResult<>(20001,"fail",null);}publicstatic<T>Result<T>fail(Integer code){returnnewResult<>(code,"fail",null);}publicstatic<T>Result<T>fail(Integer code,String message){returnnewResult<>(code,message,null);}publicstatic<T>Result<T>fail(String message){returnnewResult<>(20001,message,null);}}
4. 登录相关接口
4.1 登录
接口属性值url/user/loginmethodpost请求参数username
password返回参数
controller
@PostMapping("/login")publicResult<Map<String,Object>>login(@RequestBodyUser user){Map<String,Object> data = userService.login(user);if(data !=null){returnResult.success(data);}returnResult.fail(20002,"用户名或密码错误");}
service
publicMap<String,Object>login(User user){LambdaQueryWrapper<User> wrapper =newLambdaQueryWrapper();
wrapper.eq(User::getUsername,user.getUsername());
wrapper.eq(User::getPassword,user.getPassword());User loginUser =this.getOne(wrapper);if(loginUser !=null){Map<String,Object> data =newHashMap<>();String key ="user::"+UUID.randomUUID();
data.put("token", key);// 待优化,最终方案jwt
loginUser.setPassword(null);
redisTemplate.opsForValue().set(key,loginUser,30,TimeUnit.MINUTES);return data;}returnnull;}
整合redis
- pom
<!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
- yml
spring:redis:host: localhost port:6379
- 配置类
@ConfigurationpublicclassMyRedisConfig{@ResourceprivateRedisConnectionFactory factory;@BeanpublicRedisTemplateredisTemplate(){RedisTemplate<String,Object> redisTemplate =newRedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(newStringRedisSerializer());Jackson2JsonRedisSerializer<Object> serializer =newJackson2JsonRedisSerializer<>(Object.class); redisTemplate.setValueSerializer(serializer);ObjectMapper om =newObjectMapper(); om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY); om.setDateFormat(newSimpleDateFormat("yyyy-MM-dd HH:mm:ss")); om.setTimeZone(TimeZone.getDefault()); om.configure(MapperFeature.USE_ANNOTATIONS,false); om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.PROPERTY); om.setSerializationInclusion(JsonInclude.Include.NON_NULL); serializer.setObjectMapper(om);return redisTemplate;}}
4.2 获取用户信息
接口属性值url/user/info?token=xxxmethodget请求参数token返回参数
controller
@GetMapping("/info")publicResult<?>getUserInfo(@Param("token")String token){Map<String,Object> data = userService.getUserInfo(token);if(data !=null){returnResult.success(data);}returnResult.fail(20003,"用户信息获取失败");}
service
publicMap<String,Object>getUserInfo(String token){// 从redis查询tokenObject obj = redisTemplate.opsForValue().get(token);// 反序列化User user =JSON.parseObject(JSON.toJSONString(obj),User.class);if(user !=null){Map<String,Object> data =newHashMap<>();
data.put("name",user.getUsername());
data.put("avatar",user.getAvatar());List<String> roleList =this.getBaseMapper().getRoleNamesByUserId(user.getId());
data.put("roles", roleList);return data;}returnnull;}
mapper.xml
<selectid="getRoleNamesByUserId"parameterType="Integer"resultType="String">
SELECT
b.role_name
FROM x_user_role a,x_role b
WHERE a.`user_id` = #{userId}
AND a.`role_id` = b.`role_id`
</select>
4.3 注销
接口属性值url/user/logoutmethodpost请求参数返回参数[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DwV5GD4c-1675952251553)(C:\Users\dacai\AppData\Roaming\Typora\typora-user-images\image-20230203171855151.png)]
controller
@PostMapping("/logout")publicResult<?>logout(@RequestHeader("X-Token")String token){
userService.logout(token);returnResult.success("注销成功");}
service
publicvoidlogout(String token){
redisTemplate.delete(token);}
6. 跨域处理
@ConfigurationpublicclassCorsConfig{@BeanpublicCorsFiltercorsFilter(){//1.添加CORS配置信息CorsConfiguration config =newCorsConfiguration();//1) 允许的域,不要写*,否则cookie就无法使用了
config.addAllowedOrigin("http://localhost:8888");//这里填写请求的前端服务器//2) 是否发送Cookie信息
config.setAllowCredentials(true);//3) 允许的请求方式
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");// 4)允许的头信息
config.addAllowedHeader("*");//2.添加映射路径,我们拦截一切请求UrlBasedCorsConfigurationSource configSource =newUrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);//3.返回新的CorsFilter.returnnewCorsFilter(configSource);}}
7. 用户管理接口
接口说明查询用户列表分页查询新增用户根据id查询用户修改用户删除用户逻辑删除
7.1 查询用户列表
- controller
@GetMapping("/list")publicResult<?>getUserListPage(@RequestParam(value ="username", required =false)String username,@RequestParam(value ="phone", required =false)String phone,@RequestParam("pageNo")Long pageNo,@RequestParam("pageSize")Long pageSize){LambdaQueryWrapper<User> wrapper =newLambdaQueryWrapper(); wrapper.eq(username !=null,User::getUsername, username); wrapper.eq(phone !=null,User::getPhone, phone);Page<User> page =newPage<>(pageNo, pageSize); userService.page(page, wrapper);Map<String,Object> data =newHashMap<>(); data.put("total", page.getTotal()); data.put("rows", page.getRecords());returnResult.success(data);}
- 分页拦截器
@ConfigurationpublicclassMpConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptor interceptor =newMybatisPlusInterceptor(); interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));return interceptor;}}
7.2 新增用户
密码加密处理,用BCryptPasswordEncoder,涉及登录逻辑改动
7.3 修改用户
此处不提供密码更新,大家自行扩展,可以去实现前端右上角菜单的个人信息功能
7.4 删除用户
利用MyBatisPlus做逻辑删除处理
mybatis-plus:global-config:db-config:logic-delete-field: delete
logic-delete-value:1logic-not-delete-value:0
版权归原作者 大菜007 所有, 如有侵权,请联系我们删除。