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;
    }
}

 

                

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 07:48:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 07:48:05       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 07:48:05       58 阅读
  4. Python语言-面向对象

    2024-07-14 07:48:05       69 阅读

热门阅读

  1. 开源科学工程技术软件

    2024-07-14 07:48:05       17 阅读
  2. 2060:【例1.1】计算机输出

    2024-07-14 07:48:05       24 阅读
  3. Debian ip6tables allow IPv6 traffic on TCP port 18917

    2024-07-14 07:48:05       26 阅读
  4. ubuntu 物理内存爆炸而不使用虚拟内存的问题

    2024-07-14 07:48:05       20 阅读
  5. Unity宏和编辑器

    2024-07-14 07:48:05       21 阅读
  6. (C++栈与队列02) 栈的应用 单调队列

    2024-07-14 07:48:05       27 阅读
  7. 基于物联网的智慧校园建设与发展

    2024-07-14 07:48:05       32 阅读
  8. DNS是什么

    2024-07-14 07:48:05       21 阅读
  9. Bug及优化

    2024-07-14 07:48:05       19 阅读