SpringBoot入门(解决JDK8不存在问题)

1、什么是SpringBoot

        SpringBoot是一个用于创建独立的、基于Spring的Java应用程序框架。它通过约定优于配置的方式来简化Spring应用程序的开发过程,使开发者能够更快速地搭建和部署应用程序。Spring Boot 提供了自动化配置,减少了手动配置的工作量,并集成了大量常用的第三方库,从而简化了开发者的工作。Spring Boot 应用程序可以打包为独立的JAR包,并通过内嵌的Servlet容器(如Tomcat、Jetty)来运行,无需外部的Web服务器。(开箱即用

总结来说,Spring Boot 是Spring框架的一个扩展,旨在简化和加速Spring应用程序的开发、配置、部署过程。

        优点:

  1. 简化配置: Spring Boot 使用约定优于配置的理念,大大简化了Spring应用程序的配置过程,减少了开发者的工作量。

  2. 快速启动: Spring Boot 应用程序可以打包为独立的JAR包,并且集成了嵌入式的Servlet容器,如Tomcat或Jetty,因此可以快速启动和运行,无需外部的Web服务器。

  3. 自动化配置: Spring Boot 提供了大量的自动化配置选项,可以根据项目的依赖和环境自动配置Spring应用程序,使得开发者可以更专注于业务逻辑而不是配置细节。

  4. 集成大量开箱即用的组件: Spring Boot 预集成了大量常用的第三方库和框架(如Spring Data、Spring Security等),开发者可以直接引入依赖并开始使用,提高了开发效率。

  5. 微服务支持: Spring Boot 很好地支持微服务架构,可以通过Spring Cloud等相关项目来轻松构建和管理微服务。

  6. 与Spring生态系统的无缝集成: Spring Boot 是Spring框架的一部分,与Spring的生态系统紧密集成,可以充分利用Spring框架的各种功能和扩展。

2、SpringBoot开发示例(解决JDK8不存在的问题)

        2.1、SpringBoot工程创建

基于2019版IDEA创建SpringBoot项目工程(注:JDK8搭建SpringBoot项目的是可能存在如下问题)

        1、Java8不存在问题

解决方案:

        

将下载好的压缩包进行解压即可,随后用IDEA打开即可用

这样项目就搭建好了

查看统一模块管理,按住ctrl+鼠标左键点击跳转即可,进入文件查看内部文件管理

   <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

        2.2、创建SpringBoot配置文件

        application.yml或者.properties的后缀都可以,他们可以进行相互的转换

文件所在目录如下

                        

文件内容如下(基于.properties类型)

#配置服务器端口;默认8080
server.port=8088 
#配置项目访问根路径;默认/
server.servlet.context-path=/SpringBoot
#其他相关配置
......... 

启动类查看

        所在目录

                          

也可以直接创建于包的根路径下则无需加注解@ComponentScan("扫描的包路径")

代码如下

        

package com.zking.springboot01.start;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.zking.springboot01")
@MapperScan({"com.zking.springboot01.mapper"})
public class Springboot01Application {

    public static void main(String[] args) {
        SpringApplication.run(Springboot01Application.class, args);
    }

}

2.3、工程案例演示

创建一个controller包,下面创建HelloController类

@RestController
public class HelloController {
​
    @GetMapping("/hello")
    public Object Hello(){
        Map<String,Object> map = new HashMap<>();
        map.put("code","200");
        map.put("msg","欢迎进入!");
        return map;
    }
}

运行项目访问对应路径即可

3、SpringBoot常用注解

注解注解说明
@SpringBootApplication这是 Spring Boot 最最最核心的注解,用在 Spring Boot 主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。其实这个注解就是 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 这三个注解的组合,也可以用这三个注解来代替 @SpringBootApplication 注解
@Configuration基于JavaConfig的配置形式,相当于xml配置文件中的bean配置,任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id
@ComponentScan功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。(注:所以SpringBoot的启动类最好是放在root package下,因为默认不指定basePackages。)
@EnableAutoConfiguration借助@Import的支持,收集和注册特定场景相关的bean定义。允许 Spring Boot 自动配置注解,开启这个注解之后,Spring Boot 就能根据当前类路径>下的包或者类来配置 Spring Bean
@SpringBootConfiguration这个注解就是 @Configuration 注解的变体,只是用来修饰是 Spring Boot 配置而已,或者可利于 Spring Boot 后续的扩展
@Conditional这是 Spring 4.0 添加的新注解,用来标识一个 Spring Bean 或者 Configuration 配置文>件,当满足指定的条件才开启配置
@ConditionalOnBean组合 @Conditional 注解,当容器中有指定的 Bean 才开启配置
@ConditionalOnMissingBean组合 @Conditional 注解,和 @ConditionalOnBean 注解相反,当容器中没有指定的 Bean 才开启配置
@ConditionalOnClass组合 @Conditional 注解,当容器中有指定的 Class 才开启配置
@ConditionalOnMissingClass组合 @Conditional 注解,和 @ConditionalOnMissingClass 注解相反,当容器中没有指定的 Class 才开启配置
@ConditionalOnWebApplication组合 @Conditional 注解,当前项目类型是 WEB 项目才开启配置
@ConditionalOnNotWebApplication组合 @Conditional 注解,和 @ConditionalOnWebApplication 注解相反,当前项目类型不是 WEB 项目才开启配置
@ConditionalOnProperty组合 @Conditional 注解,当指定的属性有指定的值时才开启配置
@ConditionalOnExpression组合 @Conditional 注解,当 SpEL 表达式为 true 时才开启配置
@ConditionalOnJava组合 @Conditional 注解,当运行的 Java JVM 在指定的版本范围时才开启配置
@ConditionalOnResource组合 @Conditional 注解,当类路径下有指定的资源才开启配置
@ConditionalOnJndi组合 @Conditional 注解,当指定的 JNDI 存在时才开启配置
@ConditionalOnCloudPlatform组合 @Conditional 注解,当指定的云平台激活时才开启配置
@ConditionalOnSingleCandidate组合 @Conditional 注解,当指定的 class 在容器中只有一个 Bean,或者同时有多个但为首选时才开启配置
@ConfigurationProperties用来加载额外的配置(如 .properties 文件),可用在 @Configuration 注解类,或者 @Bean 注解方法上面
@EnableConfigurationProperties一般要配合 @ConfigurationProperties 注解使用,用来开启对 @ConfigurationProperties 注解配置 Bean 的支持
@AutoConfigureAfter用在自动配置类上面,表示该自动配置类需要在另外指定的自动配置类配置完之后。如 Mybatis 的自动配置类,需要在数据源自动配置类之后,@AutoConfigureAfter(DataSourceAutoConfiguration.class) public class MybatisAutoConfiguration
@AutoConfigureBefore这个和 @AutoConfigureAfter 注解使用相反,表示该自动配置类需要在另外指定的自动配置类配置之前
@Import这是 Spring 3.0 添加的新注解,用来导入一个或者多个 @Configuration 注解修饰的类,这在 Spring Boot 里面应用很多
@ImportResource这是 Spring 3.0 添加的新注解,用来导入一个或者多个 Spring 配置文件,这对 Spring Boot 兼容老项目非常有用,因为有些配置无法通过 Java Config 的形式来配置就只能用这个注解来导入

4、统一异常处理

        注:异常类型:1、强制异常;2、非强制异常统一异常处理主要处理非强制异常

        4.1、定义异常枚举类

代码如下:

public enum ErrorType {
    SUCCESS(200, "ok"),
    NO_AUTH(401, "未登录"),
    NO_PERMISSION(403, "没有权限"),
    OTHER_ERROR(500, "后台异常"),
    NOT_FOUND_MAPPING(404, "请求资源不存在");

    private Integer errorCode;

    private String errorMsg;

    ErrorType(Integer code, String errorMsg) {
        this.errorCode = code;
        this.errorMsg = errorMsg;
    }

    public Integer getErrorCode() {
        return this.errorCode;
    }

    public String getErrorMsg() {
        return this.errorMsg;
    }

}

为什么要使用枚举,何为类型检查?

  1. 类型安全性:

    • 枚举类常量: 枚举类常量是枚举类型的一部分,因此它们具有严格的类型安全性。编译器会确保你只能使用该枚举类中定义的常量,这样可以避免使用不相关的常量或值。

    • 实现类或实体类常量: 如果使用实现类或实体类中的常量,通常是通过类的静态常量或静态 final 字段来实现的。这些常量不会有与枚举常量相同的类型检查,因为它们只是普通的类成员。编译器不会强制确保只使用预定义的常量,因此可能会导致使用不正确的常量值的风险。

  2. 可读性和维护性:

    • 枚举类常量: 枚举类常量明确地列在枚举类的定义中,使得代码更具可读性。添加或修改枚举常量时,IDE和编译器会提供支持,因此更易于维护和更新。

    • 实现类或实体类常量: 这些常量可能会散布在类的不同部分或者在整个代码库中,可读性和维护性较差。如果有多个类定义了相似的常量,则可能会导致命名冲突或混淆。

  3. 编程实践:

    • 通常情况下,枚举类常量更适合表示一组相关的常量选项,例如颜色、状态、选项等。这样的使用方式可以提高代码的结构化和清晰度。

    • 实现类或实体类常量通常用于表示不可变的全局值,如数学常数或应用程序的配置参数。

差异:

        实现类或实体类中定义的常量存在被修改的风险。因为这些常量通常是通过静态 final 字段或者常量定义的方式实现的,它们虽然在程序中被视为常量,

但实际上可以被重新赋值或修改。这种修改可能是有意为之,但也可能是意外的,尤其是在大型项目中,可能有多个开发者操作同一个类或实体类的常量。

        枚举类中定义的常量是真正意义上的不可修改的常量。枚举常量在定义时就被确定,并且无法在运行时被修改。这种设计保证了枚举常量的稳定性和不可变性,

使得它们更适合表达固定不变的选项集合,如星期几、月份、状态等。

        因此,为了避免常量被意外修改或破坏,特别是在涉及到多人开发或大型项目中,推荐使用枚举类来定义常量。这样可以确保常量的稳定性和一致性,减少程序中出现的潜在错误。

4.2、定义统一消息返回格式

        

public class ReturnData extends HashMap<String,Object> {

    public ReturnData(int code, String msg) {
        this.put("code",code);
        this.put("msg", msg);
    }

    public ReturnData(int code,String msg, Object data) {
        this.put("code",code);
        this.put("msg",msg);
        this.put("data",data);
    }

    public ReturnData() {
        this.put("code", 1);
        this.put("msg", "success");
    }

    public ReturnData(Object data) {
        this.put("code", 1);
        this.put("msg", "success");
        this.put("data",data);
    }

    public ReturnData(ErrorType error) {
        this.put("code", error.getErrorCode().intValue());
        this.put("msg", error.getErrorMsg().toString());
    }
}

4.3、自定义异常

public class MyExcepton extends RuntimeException {

    private ErrorType error;

    public MyExcepton() {
        super();
    }

    public MyExcepton(String msg) {
        super(msg);
    }

    public MyExcepton (ErrorType error) {
        super(error.getErrorMsg().toString());
        this.error = error;
    }

    public ErrorType getError() {
        return error;
    }

}

4.4、统一异常处理配置类

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ReturnData exceptionHandler(Exception e) {
        System.out.println(e.getCause());
        return new ReturnData(500, "服务异常");
    }

    @ExceptionHandler(MyExcepton.class)
    public ReturnData myExceptionHandler(MyExcepton e) {
        return new ReturnData(e.getError());
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity noHanderFound(NoHandlerFoundException e) {

        ReturnData error =  new ReturnData(ErrorType.NOT_FOUND_MAPPING.getErrorCode().intValue(),
                ErrorType.NOT_FOUND_MAPPING.getErrorMsg());

        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }

}

4.5、静态资源配置

@Configuration
public class ResourceConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //可以访问localhost:8088/static/images/image.jpg
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }
}

4.6、配置application.properties文件

#开启异常捕获
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resources.add-mappings=false

5、SpringBoot整合其他项目

        5.1、整合JDBC

在pom.xml中添加如下坐标:

  <!-- 数据库管理池 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- mysql连接对象 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>

在application.yml或.properties文件中配置

#在application.properties文件中加入如下配置
#数据库连接对象
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#数据库
spring.datasource.url=jdbc:mysql://localhost:3306/vue?useUnicode=true&characterEncoding=utf8
#数据库账号
spring.datasource.username=root
#数据库密码
spring.datasource.password=1234
#数据库使用类型
spring.datasource.type=com.zaxxer.hikari.HikariDataSource

5.2、配置Druid数据库连接池

        

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

在pom.xml中加入如下依赖坐标

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.15</version>
</dependency>

随后在application.propreties文件中添加如下配置(.yml文件可以进行转换)

server.port=8088
server.servlet.context-path=/SpringBoot
#数据库配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.password=1234
#连接类型需要换成Druid连接类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/vue?useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
#数据库连接池Druid配置
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.druid.filter.stat.merge-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=5000、、、
​
spring.datasource.druid.initial-size=5
#最大连接数
spring.datasource.druid.max-active=20
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#连接超时时间
spring.datasource.druid.max-wait=60000
spring.datasource.druid.min-evictable-idle-time-millis=30000
#最小连接数
spring.datasource.druid.min-idle=5
 # 是否缓存preparedStatement,也就是PSCache  官方建议MySQL下建议关闭   个人建议如果想用SQL防火墙 建议打开
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.login-password=admin
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
spring.datasource.druid.web-stat-filter.session-stat-enable=true
spring.datasource.druid.web-stat-filter.session-stat-max-count=100
spring.datasource.druid.web-stat-filter.url-pattern=/*

5.3、整合Mybatis

        

在pom.xml文件中添加如下代码

<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.3.2</version>
</dependency>

MyBatis-Spring-Boot-Starter依赖将会提供如下:

  • 自动检测现有的DataSource。

  • 将创建并注册SqlSessionFactory的实例,该实例使用SqlSessionFactoryBean将该DataSource作为输入参数进行传递。

  • 将创建并注册从SqlSessionFactory中获取的SqlSessionTemplate的实例。

  • 自动扫描您的mappers,将它们链接到SqlSessionTemplate并将其注册到Spring上下文,以便将它们注入到您的bean中。

就是说,使用了该Starter之后,只需要定义一个DataSource即可(application.properties或application.yml中可配置),它会自动创建。

请修改application.yml或application.properties文件,添加以下配置:

#mybatis配置
mybatis:
  #配置SQL映射文件路径
  mapper-locations: classpath:mapper/*.xml
  #配置别名
  type-aliases-package: com.zking.项目名.model

在启动类上添加注解@MapperScan

@SpringBootApplication
@ComponentScan("com.zking.springboot01")
@MapperScan({"com.zking.springboot01.mapper"})
public class Springboot01Application {
​
    public static void main(String[] args) {
        SpringApplication.run(Springboot01Application.class, args);
    }
​
}

在pom.xml中添加插件

  <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <dependencies>
                    <!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.44</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

内容如下:

创建数据库相关连接的配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/zy?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=1234
jdbc.initialSize=10
jdbc.maxTotal=100
jdbc.maxIdle=50
jdbc.minIdle=10
jdbc.maxWaitMillis=-1

在resource目录下创建文件generatorConfig.xml

<?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>
    <!-- 引入配置文件 -->
    <properties resource="jdbc.properties"/>
​
    <!--指定数据库jdbc驱动jar包的位置-->
    <classPathEntry location="E:\tools\repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/>
​
    <!-- 一个数据库一个context -->
    <context id="infoGuardian">
        <!-- 注释 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/><!-- 是否取消注释 -->
            <property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 -->
        </commentGenerator>
​
        <!-- jdbc连接 -->
        <jdbcConnection driverClass="${jdbc.driver}"
                        connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
​
        <!-- 类型转换 -->
        <javaTypeResolver>
            <!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
​
        <!-- 01 指定javaBean生成的位置 -->
        <!-- targetPackage:指定生成的model生成所在的包名 -->
        <!-- targetProject:指定在该项目下所在的路径  -->
        <javaModelGenerator targetPackage="com.zking.springboot01.model"
                            targetProject="src/main/java">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否对model添加构造函数 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否针对string类型的字段在set的时候进行trim调用 -->
            <property name="trimStrings" value="false"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>
​
        <!-- 02 指定sql映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.zking.springboot01.mapper"
                         targetProject="src/main/resources">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
​
        <!-- 03 生成XxxMapper接口 -->
        <!-- type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 -->
        <!-- type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 -->
        <!-- type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
        <javaClientGenerator targetPackage="com.zking.springboot01.mapper"
                             targetProject="src/main/java" type="XMLMAPPER">
            <!-- 是否在当前路径下新加一层schema,false路径com.oop.eksp.user.model, true:com.oop.eksp.user.model.[schemaName] -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
​
        <!-- 配置表信息 -->
        <!-- schema即为数据库名 -->
        <!-- tableName为对应的数据库表 -->
        <!-- domainObjectName是要生成的实体类 -->
        <!-- enable*ByExample是否生成 example类 -->
        <table schema="" tableName="t_book" domainObjectName="Book"
               enableCountByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" enableUpdateByExample="false">
            <!-- 忽略列,不生成bean 字段 -->
            <!-- <ignoreColumn column="FRED" /> -->
            <!-- 指定列的java数据类型 -->
            <!-- <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> -->
        </table>
    </context>
</generatorConfiguration>

5.4、整合Log日志

在application.yml文件中添加如下代码:

#log日志配置
logging:
  level:
     #指定项目目录输入日志信息
     com.zking.项目名.mapper: debug

5.5、整合PageHelper

配置pom.xml,导入依赖:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

请修改application.yml或application.properties文件,添加以下配置:

#pagehelper分页插件配置
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql

创建PageBean类:

package com.zking.pagination.entity;
​
import java.io.Serializable;
import java.util.Map;
​
import javax.servlet.http.HttpServletRequest;
​
public class PageBean implements Serializable {
​
    private static final long serialVersionUID = 2422581023658455731L;
​
    //页码
    private int page=1;
    //每页显示记录数
    private int rows=10;
    //总记录数
    private int total=0;
    //是否分页
    private boolean isPagination=true;
    //上一次的请求路径
    private String url;
    //获取所有的请求参数
    private Map<String,String[]> map;
    
    public PageBean() {
        super();
    }
    
    //设置请求参数
    public void setRequest(HttpServletRequest req) {
        String page=req.getParameter("page");
        String rows=req.getParameter("rows");
        String pagination=req.getParameter("pagination");
        this.setPage(page);
        this.setRows(rows);
        this.setPagination(pagination);
        this.url=req.getContextPath()+req.getServletPath();
        this.map=req.getParameterMap();
    }
    public String getUrl() {
        return url;
    }
​
    public void setUrl(String url) {
        this.url = url;
    }
​
    public Map<String, String[]> getMap() {
        return map;
    }
​
    public void setMap(Map<String, String[]> map) {
        this.map = map;
    }
​
    public int getPage() {
        return page;
    }
​
    public void setPage(int page) {
        this.page = page;
    }
    
    public void setPage(String page) {
        if(null!=page&&!"".equals(page.trim()))
            this.page = Integer.parseInt(page);
    }
​
    public int getRows() {
        return rows;
    }
​
    public void setRows(int rows) {
        this.rows = rows;
    }
    
    public void setRows(String rows) {
        if(null!=rows&&!"".equals(rows.trim()))
            this.rows = Integer.parseInt(rows);
    }
​
    public int getTotal() {
        return total;
    }
​
    public void setTotal(int total) {
        this.total = total;
    }
    
    public void setTotal(String total) {
        this.total = Integer.parseInt(total);
    }
​
    public boolean isPagination() {
        return isPagination;
    }
    
    public void setPagination(boolean isPagination) {
        this.isPagination = isPagination;
    }
    
    public void setPagination(String isPagination) {
        if(null!=isPagination&&!"".equals(isPagination.trim()))
            this.isPagination = Boolean.parseBoolean(isPagination);
    }
    
    /**
     * 获取分页起始标记位置
     * @return
     */
    public int getStartIndex() {
        //(当前页码-1)*显示记录数
        return (this.getPage()-1)*this.rows;
    }
    
    /**
     * 末页
     * @return
     */
    public int getMaxPage() {
        int totalpage=this.total/this.rows;
        if(this.total%this.rows!=0)
            totalpage++;
        return totalpage;
    }
    
    /**
     * 下一页
     * @return
     */
    public int getNextPage() {
        int nextPage=this.page+1;
        if(this.page>=this.getMaxPage())
            nextPage=this.getMaxPage();
        return nextPage;
    }
    
    /**
     * 上一页
     * @return
     */
    public int getPreivousPage() {
        int previousPage=this.page-1;
        if(previousPage<1)
            previousPage=1;
        return previousPage;
    }
​
    @Override
    public String toString() {
        return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", isPagination=" + isPagination
                + "]";
    }
}
​

配置切面代码如下:

package com.zking.springboot01.util;
​
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
@Component
@Aspect
public class PageAspect {
​
    /**
     * 切面=通知+切入点
     * 通知:公共行为,横切关注点,拦截到JoinPoint后所执行的行为
     * 切入点:多个连接点的集合
     * 理解:只有满足匹配条件的目标对象才将通知应用到目标上
     *
     * * *..*Service.*Pager(..)
     * *代表返回值不限
     * *..代表包名不限
     * *Service代表以Service结尾的接口或者类
     * .*Pager代表以Pager方法名结尾的方法
     * (..)代表参数不限
     * @param joinPoint
     * @return
     */
    @Around("execution(* *..*Service.*Pager(..))")
    public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取目标方法执行的参数
        Object[] params = joinPoint.getArgs();
        //定义PageBean对象
        PageBean pageBean=null;
        //循环遍历目标方法的参数
        for (Object param : params) {
            //判断目标参数是否与PageBean一致
            if(param instanceof PageBean){
                pageBean= (PageBean) param;
                break;
            }
        }
​
        //判断是否分页
        if(null!=pageBean&&pageBean.isPagination())
            PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
​
        //执行目标方法
        Object proceed = joinPoint.proceed(params);
​
        if(null!=pageBean&&pageBean.isPagination()){
                List lst = (List) proceed;
                PageInfo pageInfo=new PageInfo(lst);
                //将pageinfo中的总记录数存入pageBean中的total属性中
               //jsonResponseBody.setTotal(pageInfo.getTotal());
                pageBean.setTotal((int) pageInfo.getTotal());
        }
        return proceed;
    }
}

                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/793389.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据专业创新人才培养体系的探索与实践

一、引言 随着大数据技术的迅猛发展&#xff0c;其在各行各业中的应用日益广泛&#xff0c;对大数据专业人才的需求也日益增长。我国高度重视大数据产业的发展&#xff0c;将大数据作为国家战略资源&#xff0c;推动大数据与各行业的深度融合。教育部也积极响应国家战略&#…

202-502SF 同轴连接器

型号简介 202-502SF是Southwest Microwave的连接器。这款连接器外壳采用不锈钢&#xff0c;接触件采用 BeCu 并进行金镀处理&#xff0c;绝缘体采用聚四氟乙烯&#xff0c;防尘环采用 UltiFume 1000&#xff0c;电缆适配器采用黄铜并进行金镀处理&#xff0c;电缆螺母也采用不锈…

跨境电商API的全球视野:打破地域限制,连接全球消费者与商家

在全球化日益加深的今天&#xff0c;跨境电商已成为推动全球经济一体化的重要力量。它不仅为消费者提供了前所未有的购物体验&#xff0c;让世界各地的商品触手可及&#xff0c;更为商家开辟了全新的市场蓝海&#xff0c;实现了业务的全球化拓展。在这一进程中&#xff0c;跨境…

基于vue的地图特效(飞线和标注)

这段代码的主要功能是在页面加载完成后&#xff0c;初始化一个 echarts 地图图表&#xff0c;并配置了相关的地理数据、散点数据、线条数据以及样式效果&#xff0c;最后在指定的 div 元素中进行展示。 需要再vue中的框架实现&#xff0c;不能单独直接运行。 标注 type: effe…

使用simulink进行esp32开发,进行串口收发数据需要注意的地方,为什么收发不成功

1&#xff0c;主要是因为simulink里的配置文件配置的波特率和串口接受软件配置的波特不一致导致的 2&#xff0c;主要有以下三个界面 a.配置文件 b.模型 模型直接选择使用的是那组串口就行了&#xff0c;一般情况下我们收发使用同一组就可以&#xff0c;这样收发模块填写的端…

浪潮服务器内存物理插槽位置

浪潮服务器内存物理插槽位置 如下图所示

光伏电站逆变器选型方法

前言&#xff1a;光伏逆变器是光伏发电系统两大主要部件之一&#xff0c;光伏逆变器的核心任务是跟踪光伏阵列的最大输出功率&#xff0c;并将其能量以最小的变换损耗、最佳的电能质量馈入电网。由于逆变器是串联在光伏方阵和电网之间&#xff0c;逆变器的选择将成为光伏电站能…

Socks5代理为何比HTTP代理快?

在网络世界中&#xff0c;代理服务器扮演着重要的角色&#xff0c;它们能够帮助我们访问被限制的网站、提高网络安全性以及优化网络性能。其中&#xff0c;Socks5代理和HTTP代理是两种常见的代理类型。然而&#xff0c;很多用户发现&#xff0c;相较于HTTP代理&#xff0c;Sock…

探索 Electron:窗口菜单以及生命周期和对话框讲解

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

小程序问题

1.获取节点 wx.createSelectorQuery() wx.createSelectorQuery().in(this) //组件中加in(this)&#xff0c;不然获取不到 2.使用实例 wx.createSelectorQuery().in(this).select(#share).fields({node: true,size: true}).exec(async (res) > {const canvas res[0].node;…

【栈和队列OJ题】

栈和队列OJ题 文章目录 栈和队列OJ题1. 用队列实现栈2. 用栈实现队列3. 括号匹配问题4. 循环队列 1. 用队列实现栈 OJ链接&#xff1a;225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 好的&#xff0c;我们一起来看一下题目&#xff0c;题目是这样说的 思路&…

【斯坦福因果推断课程全集】2_无混淆和倾向分1

目录 Beyond a single randomized controlled trial Aggregating difference-in-means estimators Continuous X and the propensity score 随机试验的一个最简单的扩展是无约束下的干预效果估计。从定性上讲&#xff0c;当我们想估计一种并非随机的治疗效果&#xff0c;但一…

PyTorch | 加速模型训练的妙招

引言 提升机器学习模型的训练速度是每位机器学习工程师的共同追求。训练速度的提升意味着实验周期的缩短&#xff0c;进而加速产品的迭代过程。同时&#xff0c;这也表示在进行单一模型训练时&#xff0c;所需的资源将会减少。简而言之&#xff0c;我们追求的是效率。 熟悉 PyT…

mybatis的拦截器

文章目录 第三个是参数拦截器第四个是结果集拦截器mybatis拦截器-笔试题1.笔试题 JDBC的执行流程3.执行sql语句,返回执行结果 mybatis的四种拦截器 第一个是执行拦截器: Executor&#xff08;执行器拦截器&#xff09;&#xff1a; 用途&#xff1a;拦截MyBatis执行器方法的…

AI版Siri要明年见,研究表明ChatGPT暂无法取代程序员,Kimi推出浏览器插件

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 根据彭博社记者马克古尔曼的最新消息&#xff0c;苹果公司今年不会推出全新的Apple Intelligence驱动的Siri&#xff0c;该公司计划在明年1月开始测试&#xff0c;并在iOS 18.4中才推出正式版本。 此前…

未来工业革命:区块链在工业4.0中的角色与应用

随着科技的迅猛发展&#xff0c;人类社会正在逐步迈向工业4.0时代。在这一新时代的背景下&#xff0c;区块链技术作为一种创新性的分布式账本技术&#xff0c;正逐步在工业领域展示其独特的价值和潜力。本文将深入探讨区块链在工业4.0中的角色与应用&#xff0c;分析其对工业生…

windows安装Docker Desktop及国内镜像

简介 Docker 是一个开源的应用容器引擎&#xff0c;它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。通过Docker工具&#xff0c;简化了应用的部署、配置和管理过程&#xff0c;提高…

dataX入门

下载dataX https://datax-opensource.oss-cn-hangzhou.aliyuncs.com/202308/datax.tar.gz 然后 下载后解压至本地某个目录&#xff0c;进入bin目录&#xff0c;即可运行同步作业&#xff1a; $ cd {YOUR_DATAX_HOME}/bin $ python datax.py {YOUR_JOB.json} 要求你有python…

FPGA上板项目(一)——点灯熟悉完整开发流程、ILA在线调试

目录 创建工程创建 HDL 代码仿真添加管脚约束添加时序约束生成 bit 文件下载ILA 在线调试 创建工程 型号选择&#xff1a;以 AXU9EG 开发板为例&#xff0c;芯片选择 xczu9eg-ffvb1156-2-i 创建 HDL 代码 注意&#xff1a;由于输入时钟为 200MHz 的差分时钟&#xff0c;因此…

【Python】已解决:ModuleNotFoundError: No module named ‘nltk’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘nltk’ 一、分析问题背景 在使用Python进行自然语言处理或文本分析时&#xff0c;我们经常会用到各种库来辅助我们的工…