SpringBoot开发web项目

导入SpringBoot 先导入空项目
修改依赖的版本:
在这里插入图片描述
重新导入依赖:在这里插入图片描述
引入 mybatis-spring-boot-starter依赖和 mysql连接的依赖:

<!--        mybatis-spring-boot-starter依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
<!--        mysql连接的依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

添加自动生成文件插件:


            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>


在这里插入图片描述
自动生成文件配置文件:generatorConfig.xml(放在resources目录下)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
  <!-- 配置文件,放在resource目录下即可 -->
  <!--数据库驱动个人配置-->
    <!--          本地存放mysql-connector-java-8.0.18.jar的路径-->
  <classPathEntry
          location="C:\Users\luo\.m2\repository\mysql\mysql-connector-java\8.0.18\mysql-connector-java-8.0.18.jar"/>
    <context id="MysqlTables" targetRuntime="MyBatis3">
    <property name="autoDelimitKeywords" value="true"/>
    <!--可以使用``包括字段名,避免字段名与sql保留字冲突报错-->
    <property name="beginningDelimiter" value="`"/>
    <property name="endingDelimiter" value="`"/>
    <!-- optional,旨在创建class时,对注释进行控制 -->
    <commentGenerator>
      <property name="suppressDate" value="true"/>
      <property name="suppressAllComments" value="true"/>
    </commentGenerator>
    <!--数据库链接地址账号密码-->
    <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                    connectionURL="jdbc:mysql://127.0.0.1:3306/bbs2020?serverTimezone=Hongkong&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;userSSL=false"
      userId="root"
      password="123456">
      <property name="nullCatalogMeansCurrent" value="true"/>
    </jdbcConnection>
    <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
    <javaTypeResolver>
      <property name="forceBigDecimals" value="false"/>
    </javaTypeResolver>
    <!--生成Model类存放位置-->
    <javaModelGenerator targetPackage="com.luo.bbs.model.pojo"
      targetProject="src/main/java">
      <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
      <property name="enableSubPackages" value="true"/>
      <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
      <property name="trimStrings" value="true"/>
      <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
      <property name="immutable" value="false"/>
    </javaModelGenerator>
    <!--生成mapper映射文件存放位置-->
    <sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
      <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>
    <!--生成Dao类存放位置-->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.luo.bbs.model.dao"
      targetProject="src/main/java">
      <property name="enableSubPackages" value="true"/>
    </javaClientGenerator>
    <!--生成对应表及类名 domainObjectName是数据表对应的Javabean类名-->
    <table schema="root" tableName="post" domainObjectName="Post"
      enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>
    <table tableName="user" domainObjectName="User" enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>

  </context>
</generatorConfiguration>

在application.properties中书写与数据库相关的配置文件:

server.port=8092

spring.datasource.name=bbs_database
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/bbs2020?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456


配置好这些后就可以写controller和service进行数据库的测试了。

在测试前还需要加入一些配置:
在入口类前面加上:

@MapperScan(basePackages = "com.luo.bbs.model.dao")
@ComponentScan(basePackages = {"com.luo.*"})

@MapperScan
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加,
@ComponentScan 的作用就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中
在这里插入图片描述
在application.properties配置文件中:
#指定mappers文件在哪,从哪里去找
mybatis.mapper-locations=classpath:mappers/*.xml

在这里插入图片描述
这些都配置好后在调用mapper时idea会报红,但是不影响程序的正常运行:
在这里插入图片描述
这是因为idea不能识别这个类,@MapperScan(basePackages = “com.luo.bbs.model.dao”)只是让mybatis识别,idea不能识别,所以需要在每个Mapper接口前面加上@Repository注解
在这里插入图片描述
一切准备就绪后便可尝试跑通数据库连接

引入log4j日志组件
先在spring-boot-starter-web中去除自带的日志组件
,以便排除冲突

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>

        </dependency>

在这里插入图片描述
引入log4j2依赖:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

不需要配置版本,springboot会根据springboot的版本自动配置版本
引入log4j2配置文件:

log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
  <Properties>
  <!--日志储存的地址-->
    <Property name="baseDir" value="D:\log\bbs"/>
  </Properties>

  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
      <ThresholdFilter level="info" onMatch="ACCEPT"
        onMismatch="DENY"/>
      <PatternLayout
        pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
    </Console>

    <!--debug级别日志文件输出-->
    <RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
      filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
      <!-- 过滤器 -->
      <Filters>
        <!-- 限制日志级别在debug及以上在info以下 -->
        <ThresholdFilter level="debug"/>
        <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
      </Filters>
      <!-- 日志格式 -->
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <!-- 策略 -->
      <Policies>
        <!-- 每隔一天转存 -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 文件大小 -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>

    <!-- info级别日志文件输出 -->
    <RollingFile name="info_appender" fileName="${baseDir}/info.log"
      filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
      <!-- 过滤器 -->
      <Filters>
        <!-- 限制日志级别在info及以上在error以下 -->
        <ThresholdFilter level="info"/>
        <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
      </Filters>
      <!-- 日志格式 -->
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <!-- 策略 -->
      <Policies>
        <!-- 每隔一天转存 -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 文件大小 -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>

    <!-- error级别日志文件输出 -->
    <RollingFile name="error_appender" fileName="${baseDir}/error.log"
      filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
      <!-- 过滤器 -->
      <Filters>
        <!-- 限制日志级别在error及以上 -->
        <ThresholdFilter level="error"/>
      </Filters>
      <!-- 日志格式 -->
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <Policies>
        <!-- 每隔一天转存 -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 文件大小 -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="debug">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="debug_appender"/>
      <AppenderRef ref="info_appender"/>
      <AppenderRef ref="error_appender"/>
    </Root>

  </Loggers>
</Configuration>

AOP统一打印请求和返回信息
先引入AOP所需的依赖:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

然后新建一个过滤器:

名为:WebLogAspect.java :

package com.luo.bbs.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * 打印请求和响应信息
 */
@Aspect
@Component
public class WebLogAspect {
    //导入log类,用于记录日志
    private final Logger log = LoggerFactory.getLogger(WebLogAspect.class);


    /**
     * 指定拦截点的方法
     */
    //配置拦截的点,拦截controller层以及controller层以下的所有内容
    @Pointcut("execution(public  * com.luo.bbs.controller.*.*(..))")
    public void webLog() {

    }

    /**
     * 拦截点之前 JoinPoint是提供请求参数的,记录的是关于类的信息,方法信息
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
//收到请求,记录请求内容
        //拿到当前的请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

//对日志的记录
        log.info("URL:" + request.getRequestURI().toString());
        log.info("HTTP_METHOD:" + request.getMethod());
        log.info("IP:" + request.getRemoteAddr());
        //类的一些方法
        //joinPoint.getSignature().getDeclaringTypeName()获取类名
        //joinPoint.getSignature().getName() 获取方法名
        log.info("CLASS_METHOD" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
//打印参数
        log.info("ARGS:" + Arrays.toString(joinPoint.getArgs()));


    }


    /**
     * 拦截点之后的方法
     * res是webLog将要返回的内容
     * @param res
     */
    @AfterReturning(returning = "res",pointcut = "webLog()")
    public void doAfterReturning(Object res) throws JsonProcessingException {
        //new ObjectMapper().writeValueAsString(res) 把res转换为json格式
        log.info("RESPONSE:"+new ObjectMapper().writeValueAsString(res));

    }



}

编写统一返回对象;
ApiRestResponse.java中:

package com.luo.bbs.common;


import com.luo.bbs.exception.ExceptionEnum;

/***
 * 描述:   通用返回对象
 */
public class ApiRestResponse<T> {

    private Integer status;

    private String msg;

    private T data;

    private static final int OK_COOE = 10000;

    private static final String OK_MSG = "SUCCESS";

    public ApiRestResponse(Integer status, String msg, T data) {

        this.status = status;
        this.msg = msg;
        this.data = data;
    }


    public ApiRestResponse(Integer status, String msg) {
        this.status = status;
        this.msg = msg;
    }

    public ApiRestResponse() {
        
        this(OK_COOE, OK_MSG);
    }

    //成功且不返回参数时
    public static <T> ApiRestResponse<T> success() {
        
        return new ApiRestResponse<>();
    }
//成功且需要返回参数时
    public static <T> ApiRestResponse<T> success(T result) {
        ApiRestResponse<T> response = new ApiRestResponse<>();
        response.setData(result);
        return response;
    }

//错误时(错误码和错误信息需要自己输)
    public static <T> ApiRestResponse<T> error(Integer code,String msg) {

        return new ApiRestResponse<>(code, msg);
    }

//错误时,错误码和错误信息在枚举中定义
    public static <T> ApiRestResponse<T> error(ExceptionEnum ex) {
        return new ApiRestResponse<>(ex.getCode(), ex.getMsg());
    }


    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public static int getOkCooe() {
        return OK_COOE;
    }

    public static String getOkMsg() {
        return OK_MSG;
    }

    @Override
    public String toString() {
        return "ApiRestResponse{" +
                "status=" + status +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

并新建一个枚举类,用户存放错误码和错误信息
ExceptionEnum.java:

package com.luo.bbs.exception;

/**
 * 异常枚举
 */
public enum ExceptionEnum {

    NEED_USER_NAME(1001, "用户名不能为空");

   Integer code;
   String msg;

    ExceptionEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }


    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

处理统一异常:(主要为自定义异常)
BbsException.java:

package com.luo.bbs.exception;

/**
 * 统一异常
 */
public class BbsException extends RuntimeException {


    private final Integer code;
    private final String message;

    public BbsException(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public BbsException(ExceptionEnum exceptionEnum) {
        this(exceptionEnum.getCode(), exceptionEnum.getMsg());
    }

    public Integer getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

统一处理系统的异常:

package com.luo.bbs.exception;

import com.luo.bbs.common.ApiRestResponse;
import com.luo.bbs.filter.WebLogAspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

/**
 * 描述: 处理统一异常的Handler
 */
//@ControllerAdvice作用:拦截异常
@ControllerAdvice
public class GlobalExceptionHandler {
    private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    //处理系统异常
    @ExceptionHandler(Exception.class)
@ResponseBody
    public Object handleException(Exception e) {
        log.error("Default Exception:",e);
        return ApiRestResponse.error(ExceptionEnum.SYSTEM_ERROR);
    }


    //处理业务异常(编写程序时抛出的异常)
    @ExceptionHandler(BbsException.class)
    @ResponseBody
    public Object handleBbsException(BbsException e) {
        log.error("BbsException:",e);
        return ApiRestResponse.error(e.getCode(), e.getMessage());
    }


    //以下两个可能不会用到


    //处理传递参数异常时返回的错误信息
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiRestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException",e);
        return handleBindingResult(e.getBindingResult());

    }

    private ApiRestResponse handleBindingResult(BindingResult result) {
//把异常处理为对外暴露的提示
        List<String> list = new ArrayList<>();
        if (result.hasErrors()) {

            List<ObjectError> allErrors = result.getAllErrors();
            for (int i = 0; i < allErrors.size(); i++) {
                ObjectError objectError = allErrors.get(i);
                String message = objectError.getDefaultMessage();
                list.add(message);
            }

        }
        if (list.size()==0) {
            return ApiRestResponse.error(ExceptionEnum.REQUEST_PARAM_ERROR);
        }
        return ApiRestResponse.error(ExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());





    }
}

过滤器的开发:(拦截需要登录之后才能操作的URL)
过滤器:UserFilter.java

package com.luo.bbs.filter;

import com.luo.bbs.common.ApiRestResponse;
import com.luo.bbs.common.Constant;
import com.luo.bbs.exception.ExceptionEnum;
import com.luo.bbs.model.pojo.User;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 用户校验过滤器
 */
public class UserFilter implements Filter {
    public static User currentUser;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpSession session = request.getSession();
        currentUser= (User) session.getAttribute(Constant.NOW_USER);
       
        if (currentUser == null) {
            PrintWriter out = new HttpServletResponseWrapper(
                    (HttpServletResponse) servletResponse).getWriter();
            out.write("{\n"
                    + "    \"status\": 10004,\n"
                    + "    \"msg\": \" NEED_LOGIN\",\n"
                    + "    \"data\": null\n"
                    + "}");



            out.flush();
            out.close();
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}


过滤器配置文件:

package com.luo.bbs.config;

import com.luo.bbs.filter.UserFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * User过滤器的配置
 */
@Configuration
public class UserFilterConfig {


    @Bean
    public UserFilter userFilter() {
        return new UserFilter();
    }

@Bean(name = "userFilterConf")
    public FilterRegistrationBean userFilterConfig() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(userFilter());
        filterRegistrationBean.addUrlPatterns("/update/*");
        filterRegistrationBean.addUrlPatterns("/delete/*");
        filterRegistrationBean.setName("userFilterConf");
        return filterRegistrationBean;
    }
}

自动生成API文档:
先引入依赖:

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        

然后在main函数中加上注解:@EnableSwagger2,代表开启了Swagger能力在这里插入图片描述
然后再添加swagger的配置文件:SpringFoxConfig.java :

package com.luo.bbs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
public class SpringFoxConfig {

    //访问http://localhost:8092/swagger-ui.html可以看到API文档
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("BBS系统")
                .description("")
                .termsOfServiceUrl("")
                .build();
    }
}

再配置MvcConfig: WebMvcConfig.java :(配置地址映射)

package com.luo.bbs.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置地址映射
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations(
                "classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations(
                "classpath:/META-INF/resources/webjars/");
    }
}

参数校验@Valid
在这里插入图片描述
在请求参数前加上@Valid注解:
在这里插入图片描述

然后再到对应的实体类中添加验证规范以及错误时的提示信息:
在这里插入图片描述
再到之前处理统一异常的Handler中 GlobalExceptionHandler.java中


    //处理传递参数异常时返回的错误信息
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiRestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException",e);
        return handleBindingResult(e.getBindingResult());

    }




private ApiRestResponse handleBindingResult(BindingResult result) {
//把异常处理为对外暴露的提示
        List<String> list = new ArrayList<>();
        if (result.hasErrors()) {

            List<ObjectError> allErrors = result.getAllErrors();
            for (int i = 0; i < allErrors.size(); i++) {
                ObjectError objectError = allErrors.get(i);
                String message = objectError.getDefaultMessage();
                list.add(message);
            }

        }
        if (list.size()==0) {
            return ApiRestResponse.error(ExceptionEnum.REQUEST_PARAM_ERROR);
        }
        return ApiRestResponse.error(ExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());

    }

分页对象:

SQL语句:

   <select id="selectListForAdmin" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from imooc_mall_product
        order by update_time desc
    </select>

Mapper:
在这里插入图片描述
实现分页:

  public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {

        PageHelper.startPage(pageNum, pageSize);
        List<Product> products = productMapper.selectListForAdmin();

        PageInfo pageInfo = new PageInfo(products);
        return pageInfo;
    }

复制类:(将相同类型相同字段的属性复制)

BeanUtils.copyProperties(addPostReq, post);

将addPostReq复制到post

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值