1、什么是SpringBoot
SpringBoot是一个用于创建独立的、基于Spring的Java应用程序框架。它通过约定优于配置的方式来简化Spring应用程序的开发过程,使开发者能够更快速地搭建和部署应用程序。Spring Boot 提供了自动化配置,减少了手动配置的工作量,并集成了大量常用的第三方库,从而简化了开发者的工作。Spring Boot 应用程序可以打包为独立的JAR包,并通过内嵌的Servlet容器(如Tomcat、Jetty)来运行,无需外部的Web服务器。(开箱即用)
总结来说,Spring Boot 是Spring框架的一个扩展,旨在简化和加速Spring应用程序的开发、配置、部署过程。
优点:
-
简化配置: Spring Boot 使用约定优于配置的理念,大大简化了Spring应用程序的配置过程,减少了开发者的工作量。
-
快速启动: Spring Boot 应用程序可以打包为独立的JAR包,并且集成了嵌入式的Servlet容器,如Tomcat或Jetty,因此可以快速启动和运行,无需外部的Web服务器。
-
自动化配置: Spring Boot 提供了大量的自动化配置选项,可以根据项目的依赖和环境自动配置Spring应用程序,使得开发者可以更专注于业务逻辑而不是配置细节。
-
集成大量开箱即用的组件: Spring Boot 预集成了大量常用的第三方库和框架(如Spring Data、Spring Security等),开发者可以直接引入依赖并开始使用,提高了开发效率。
-
微服务支持: Spring Boot 很好地支持微服务架构,可以通过Spring Cloud等相关项目来轻松构建和管理微服务。
-
与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;
}
}
为什么要使用枚举,何为类型检查?
-
类型安全性:
-
枚举类常量: 枚举类常量是枚举类型的一部分,因此它们具有严格的类型安全性。编译器会确保你只能使用该枚举类中定义的常量,这样可以避免使用不相关的常量或值。
-
实现类或实体类常量: 如果使用实现类或实体类中的常量,通常是通过类的静态常量或静态 final 字段来实现的。这些常量不会有与枚举常量相同的类型检查,因为它们只是普通的类成员。编译器不会强制确保只使用预定义的常量,因此可能会导致使用不正确的常量值的风险。
-
-
可读性和维护性:
-
枚举类常量: 枚举类常量明确地列在枚举类的定义中,使得代码更具可读性。添加或修改枚举常量时,IDE和编译器会提供支持,因此更易于维护和更新。
-
实现类或实体类常量: 这些常量可能会散布在类的不同部分或者在整个代码库中,可读性和维护性较差。如果有多个类定义了相似的常量,则可能会导致命名冲突或混淆。
-
-
编程实践:
-
通常情况下,枚举类常量更适合表示一组相关的常量选项,例如颜色、状态、选项等。这样的使用方式可以提高代码的结构化和清晰度。
-
实现类或实体类常量通常用于表示不可变的全局值,如数学常数或应用程序的配置参数。
-
差异:
实现类或实体类中定义的常量存在被修改的风险。因为这些常量通常是通过静态 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;
}
}