pom依赖
springboot相关
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- devtools --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!-- 实现自定义的state缓存 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- thymeleaf --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
hutool相关
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-http</artifactId><version>5.1.0</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-crypto</artifactId><version>5.1.0</version><scope>provided</scope></dependency>
JustAuth
<!-- JustAuth1.9.4版本后,如果需要使用支付宝登录,需要单独引用该依赖 --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>3.7.4.ALL</version></dependency><dependency><groupId>me.zhyd.oauth</groupId><artifactId>JustAuth</artifactId><version>1.16.4</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-http</artifactId><version>5.1.0</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.2.2</version><scope>provided</scope></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.10</version><scope>provided</scope></dependency><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.2.2.RELEASE</version><configuration><mainClass>me.zhyd.justauth.JustauthDemoApplication</mainClass><includeSystemScope>true</includeSystemScope></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
server.port=8443spring.thymeleaf.cache=falsespring.devtools.restart.additional-paths=src/main/javaspring.devtools.restart.exclude=static/**,public/**# \u96C6\u6210redis\u5B9E\u73B0\u81EA\u5B9A\u4E49\u7684state\u7F13\u5B58spring.redis.database=0spring.redis.host=localhostspring.redis.port=6379spring.redis.password=123456
redis相关
JustAuth 里的redis类
AuthStateRedisCache.java
RedisConfig.java
若依摘录
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ruoyi</groupId><artifactId>ruoyi</artifactId><version>3.8.1</version><packaging>jar</packaging><name>ruoyi</name><url>http://www.ruoyi.vip</url><description>若依管理系统</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.9</version><relativePath /></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><maven-jar-plugin.version>3.1.1</maven-jar-plugin.version><mybatis.spring.boot.starter.version>2.2.0</mybatis.spring.boot.starter.version><pagehelper.spring.boot.starter.version>1.4.0</pagehelper.spring.boot.starter.version><fastjson.version>1.2.79</fastjson.version><druid.version>1.2.8</druid.version><commons.io.version>2.11.0</commons.io.version><commons.fileupload.version>1.4</commons.fileupload.version><commons.collections.version>3.2.2</commons.collections.version><bitwalker.version>1.21</bitwalker.version><jwt.version>0.9.1</jwt.version><kaptcha.version>2.3.2</kaptcha.version><swagger.version>3.0.0</swagger.version><poi.version>4.1.2</poi.version><oshi.version>5.8.6</oshi.version><jna.version>5.10.0</jna.version><velocity.version>2.3</velocity.version></properties><dependencies><!-- SpringBoot 核心包 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- SpringBoot 测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- SpringBoot 拦截器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- SpringBoot Web容器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- spring-boot-devtools --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> <!-- 表示依赖不会传递 --></dependency><!-- spring security 安全认证 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- redis 缓存操作 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- pool 对象池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!-- Mysql驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- SpringBoot集成mybatis框架 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.spring.boot.starter.version}</version></dependency><!-- pagehelper 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pagehelper.spring.boot.starter.version}</version></dependency><!-- 阿里数据库连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!-- 自定义验证注解 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!-- 常用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><!-- io常用工具类 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons.io.version}</version></dependency><!-- 文件上传工具类 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>${commons.fileupload.version}</version></dependency><!-- 解析客户端操作系统、浏览器等 --><dependency><groupId>eu.bitwalker</groupId><artifactId>UserAgentUtils</artifactId><version>${bitwalker.version}</version></dependency><!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><!-- Spring框架基本的核心工具--><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><!-- Token生成与解析--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.version}</version></dependency><!-- Jaxb --><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId></dependency><!-- Swagger3依赖 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>${swagger.version}</version><exclusions><exclusion><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId></exclusion></exclusions></dependency><!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 --><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>1.6.2</version></dependency><!-- 获取系统信息 --><dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId><version>${oshi.version}</version></dependency><!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>${poi.version}</version></dependency><!-- velocity代码生成使用模板 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>${velocity.version}</version></dependency><!-- collections工具类 --><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>${commons.collections.version}</version></dependency><!-- 定时任务 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><exclusions><exclusion><groupId>com.mchange</groupId><artifactId>c3p0</artifactId></exclusion></exclusions></dependency><!-- 验证码 --><dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>${kaptcha.version}</version><exclusions><exclusion><artifactId>javax.servlet-api</artifactId><groupId>javax.servlet</groupId></exclusion></exclusions></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --></configuration></plugin></plugins></build><repositories><repository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/repository/public</url><releases><enabled>true</enabled></releases></repository></repositories><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/repository/public</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories></project>
# 项目相关配置ruoyi:# 名称name: RuoYi# 版本version: 3.8.1# 版权年份copyrightYear: 2022# 实例演示开关demoEnabled: true# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)profile: D:/ruoyi/uploadPath# 获取ip地址开关addressEnabled: false# 验证码类型 math 数组计算 char 字符验证captchaType: math# 开发环境配置server:# 服务器的HTTP端口,默认为8080port: 8080servlet:# 应用的访问路径context-path: /tomcat:# tomcat的URI编码uri-encoding: UTF-8# 连接数满后的排队数,默认为100accept-count: 1000threads:# tomcat最大线程数,默认为200max: 800# Tomcat启动初始化的线程数,默认值10min-spare: 100# 日志配置logging:level:com.ruoyi: debugorg.springframework: warn# Spring配置spring:# 资源信息messages:# 国际化资源文件路径basename: i18n/messagesprofiles:active: druid# 文件上传servlet:multipart:# 单个文件大小max-file-size: 10MB# 设置总上传的文件大小max-request-size: 20MB# 服务模块devtools:restart:# 热部署开关enabled: true# redis 配置redis:# 地址host: localhost# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password:# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最大空闲连接max-idle: 8# 连接池的最大数据库连接数max-active: 8# #连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms# token配置token:# 令牌自定义标识header: Authorization# 令牌密钥secret: abcdefghijklmnopqrstuvwxyz# 令牌有效期(默认30分钟)expireTime: 30# MyBatis配置mybatis:# 搜索指定包别名typeAliasesPackage: com.ruoyi.project.**.domain# 配置mapper的扫描,找到所有的mapper.xml映射文件mapperLocations: classpath*:mybatis/**/*Mapper.xml# 加载全局的配置文件configLocation: classpath:mybatis/mybatis-config.xml# PageHelper分页插件pagehelper:helperDialect: mysqlsupportMethodsArguments: trueparams: count=countSql# Swagger配置swagger:# 是否开启swaggerenabled: true# 请求前缀pathMapping: /dev-api# 防止XSS攻击xss:# 过滤开关enabled: true# 排除链接(多个用逗号分隔)excludes: /system/notice# 匹配链接urlPatterns: /system/*,/monitor/*,/tool/*# 代码生成gen:# 作者author: ruoyi# 默认生成包路径 system 需改成自己的模块名称 如 system monitor toolpackageName: com.ruoyi.project.system# 自动去除表前缀,默认是trueautoRemovePre: false# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)tablePrefix: sys_
# 数据源配置spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:# 主库数据源master:url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: root# 从库数据源slave:# 从数据源开关/默认关闭enabled: falseurl:username:password:# 初始连接数initialSize: 5# 最小连接池数量minIdle: 10# 最大连接池数量maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsewebStatFilter:enabled: truestatViewServlet:enabled: true# 设置白名单,不填则允许所有访问allow:url-pattern: /druid/*# 控制台管理用户名和密码login-username: ruoyilogin-password: 123456filter:stat:enabled: true# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: true
Application Version: ${ruoyi.version} Spring Boot Version: ${spring-boot.version} //////////////////////////////////////////////////////////////////// // .____ .___ // // | | ___________ __| _/ // // | | / _ \_ __ \/ __ | // // | |__( <_> ) | \/ /_/ | // // |_______ \____/|__| \____ | // // \/ \/ // ////////////////////////////////////////////////////////////////////
单应用
认证授权分析
package com.ruoyi.framework.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.http.HttpMethod;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.security.web.authentication.logout.LogoutFilter;import org.springframework.web.filter.CorsFilter;import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter;import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl;import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;/*** spring security配置** @author ruoyi*/@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter{/*** 自定义用户认证逻辑*/@Autowiredprivate UserDetailsService userDetailsService;/*** 认证失败处理类*/@Autowiredprivate AuthenticationEntryPointImpl unauthorizedHandler;/*** 退出处理类*/@Autowiredprivate LogoutSuccessHandlerImpl logoutSuccessHandler;/*** token认证过滤器*/@Autowiredprivate JwtAuthenticationTokenFilter authenticationTokenFilter;/*** 跨域过滤器*/@Autowiredprivate CorsFilter corsFilter;/*** 解决 无法直接注入 AuthenticationManager** @return* @throws Exception*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception{return super.authenticationManagerBean();}/*** anyRequest | 匹配所有请求路径* access | SpringEl表达式结果为true时可以访问* anonymous | 匿名可以访问* denyAll | 用户不能访问* fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问* hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问* hasRole | 如果有参数,参数表示角色,则其角色可以访问* permitAll | 用户可以任意访问* rememberMe | 允许通过remember-me登录的用户访问* authenticated | 用户登录后可访问*/@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception{httpSecurity// CSRF禁用,因为不使用session.csrf().disable()// 认证失败处理类.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()// 基于token,所以不需要session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 过滤请求.authorizeRequests()// 对于登录login 注册register 验证码captchaImage 允许匿名访问.antMatchers("/login", "/register", "/captchaImage").anonymous().antMatchers(HttpMethod.GET,"/","/*.html","/**/*.html","/**/*.css","/**/*.js","/profile/**").permitAll().antMatchers("/swagger-ui.html").anonymous().antMatchers("/swagger-resources/**").anonymous().antMatchers("/webjars/**").anonymous().antMatchers("/*/api-docs").anonymous().antMatchers("/druid/**").anonymous()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated().and().headers().frameOptions().disable();httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);// 添加JWT filterhttpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);// 添加CORS filterhttpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);}/*** 强散列哈希加密实现*/@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder(){return new BCryptPasswordEncoder();}/*** 身份认证接口*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception{auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());}}
package com.ruoyi.framework.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import org.springframework.web.filter.CorsFilter;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import com.ruoyi.common.constant.Constants;import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;/*** 通用配置** @author ruoyi*/@Configurationpublic class ResourcesConfig implements WebMvcConfigurer{@Autowiredprivate RepeatSubmitInterceptor repeatSubmitInterceptor;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry){/** 本地文件上传路径 */registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");/** swagger配置 */registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");}/*** 自定义拦截规则*/@Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");}/*** 跨域配置*/@Beanpublic CorsFilter corsFilter(){CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);// 设置访问源地址config.addAllowedOriginPattern("*");// 设置访问源请求头config.addAllowedHeader("*");// 设置访问源请求方法config.addAllowedMethod("*");// 有效期 1800秒 // 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了config.setMaxAge(1800L);// 添加映射路径,拦截一切请求UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);// 返回新的CorsFilterreturn new CorsFilter(source);}}
从登录来看
/** SysLoginController* 登录方法** @param loginBody 登录信息* @return 结果*/@PostMapping("/login")public AjaxResult login(@RequestBody LoginBody loginBody){AjaxResult ajax = AjaxResult.success();// 生成令牌String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),loginBody.getUuid());ajax.put(Constants.TOKEN, token);return ajax;}/** SysLoginService* 登录验证** @param username 用户名* @param password 密码* @param code 验证码* @param uuid 唯一标识* @return 结果*/public String login(String username, String password, String code, String uuid){boolean captchaOnOff = configService.selectCaptchaOnOff();// 验证码开关if (captchaOnOff){validateCaptcha(username, code, uuid);}// 用户验证Authentication authentication = null;try{// 该方法会去调用UserDetailsServiceImpl.loadUserByUsernameauthentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));}catch (Exception e){if (e instanceof BadCredentialsException){AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));throw new UserPasswordNotMatchException();}else{AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));throw new ServiceException(e.getMessage());}}AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));LoginUser loginUser = (LoginUser) authentication.getPrincipal();recordLoginInfo(loginUser.getUserId());// 生成tokenreturn tokenService.createToken(loginUser);}
黑马畅购小程序
json 树形结构与 树表互转
json转表
@PostMapping("list/tree")public RShop list(@RequestBody List<CatVO> catvo) {setchildren(catvo);System.out.println("==============");return RShop.ok();}private List<CatVO> setchildren (List<CatVO> all){List<CatVO> collect = all.stream().map((catvo -> {Cat cat = new Cat();BeanUtils.copyProperties(catvo, cat);System.out.println(cat);boolean save = catService.save(cat);System.out.println("========");List<CatVO> children = catvo.getChildren();setchildren(children);return catvo;})).collect(Collectors.toList());return collect;}其他版本的递归方式/* @PostMapping("list/tree")public RShop list(@RequestBody List<CatVO> catvo) {List<CatVO> collect = catvo.stream().map((m) -> {Cat cat = new Cat();BeanUtils.copyProperties(m,cat);boolean save = catService.save(cat);System.out.println(save);System.out.println("========");List<CatVO> children = m.getChildren();setchildren(children);return m;}).collect(Collectors.toList());//List<Cat> catlist = catService.listWithTree();return RShop.ok();}*/
从表中查询三级分类
//CatController@ApiOperation("获取分类数据")@GetMapping("categories")public RShop getCategories(){List<Cat> entities = catService.listWithTree();return RShop.ok().message(entities);}//entity 添加了children@TableField(exist=false)private List<Cat> children;//CatServiceImplpackage com.shop.wxshop.service.impl;import com.shop.wxshop.entity.Cat;import com.shop.wxshop.entity.CatVO;import com.shop.wxshop.mapper.CatMapper;import com.shop.wxshop.service.CatService;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import org.springframework.stereotype.Service;import java.util.List;import java.util.stream.Collectors;/*** <p>* 服务实现类* </p>** @author xiaoyuan* @since 2022-03-16*/@Servicepublic class CatServiceImpl extends ServiceImpl<CatMapper, Cat> implements CatService {@Overridepublic List<Cat> listWithTree() {// 1.查出所有分类List<Cat> cats = baseMapper.selectList(null);// 2.组装父子的树形结构// 2.1 找到所有的一级分类List<Cat> level1Menus = cats.stream().filter(c ->c.getCat_pid() == 0).map((menu)->{menu.setChildren(getChildren(menu,cats));return menu;}).collect(Collectors.toList());return level1Menus;}//递归查找所有菜单的子菜单private List<Cat> getChildren(Cat root,List<Cat> all){List<Cat> children = all.stream().filter(c -> {return c.getCat_pid().equals(root.getCat_id());}).map(c -> {// 1.找到子菜单c.setChildren(getChildren(c,all));return c;}).collect(Collectors.toList());return children;}}
mybatisplus 查询指定列
// 分页方式@Testpublic void test4() {Page<Map<String,Object>> page = new Page<>(1, 20);QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();goodsQueryWrapper.like("goods_name","手机").select("goods_id","goods_name");Page<Map<String, Object>> pageParam = goodsService.pageMaps(page, goodsQueryWrapper);List<Map<String, Object>> records = pageParam.getRecords();records.forEach(System.out::println);}//stream流方式@GetMapping("goods/qsearch")public RShop getByGoodsName(@RequestParam(name = "query",required = true) String query){QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();goodsQueryWrapper.like("goods_name","手机").select("goods_id","goods_name");List<Goods> list = goodsService.list(goodsQueryWrapper);List<GoodsVO> goodsVOlist = list.stream().map(item -> {GoodsVO goodsVO = new GoodsVO();BeanUtils.copyProperties(item,goodsVO);return goodsVO;}).collect(Collectors.toList());goodsVOlist.forEach(System.out::println);return RShop.ok().message(goodsVOlist);}
