前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot学习笔记(六)——分页、跨域、上传、定制banner、Lombok

SpringBoot学习笔记(六)——分页、跨域、上传、定制banner、Lombok

作者头像
张果
发布2022-05-11 14:13:38
1.3K0
发布2022-05-11 14:13:38
举报
文章被收录于专栏:软件开发软件开发

一、分页(pagehelper)

 pagehelper 是一个强大实用的 MyBatis 分页插件,可以帮助我们快速的实现MyBatis分页功能,而且pagehelper有个优点是,分页和Mapper.xml完全解耦,并以插件的形式实现,对Mybatis执行的流程进行了强化,这有效的避免了我们需要直接写分页SQL语句来实现分页功能。

github项目地址:https://github.com/pagehelper/Mybatis-PageHelper

中文帮助:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md

1.1、快速起步

1.1.1、添加依赖

代码语言:javascript
复制
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

这里需要注意也MyBatis的兼容问题,如果springboot pagehelper插件启动报错 [com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration]则需要更换版本,我使用2.5.13的Spring Boot与1.3.0的pagehelper是兼容的,示例项目完整的pom如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zhangguo</groupId>
    <artifactId>mybatisdemo3</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatisdemo3</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

1.1.2、添加配置

在application.yaml文件中添加如下配置信息:

代码语言:javascript
复制
# pagehelper
pagehelper:
  helperDialect: mysql  #数据库类型
  reasonable: true #查询合理化 当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页
  supportMethodsArguments: true  #支持方法参数 支持通过 Mapper 接口参数来传递分页参数
  params: count=countSql  #参数

1.1.3、数据访问接口

StudentDao.java:

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3.dao;

import com.zhangguo.mybatisdemo3.entity.Student;
import java.util.List;

public interface StudentDao {
    //查询学生并分页
    public List<Student> selectPager();
}

1.1.4、接口映射

resource/mapper/StudentDao.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.zhangguo.mybatisdemo3.dao.StudentDao">
    <select id="selectPager" resultType="Student">
        SELECT
            student.id,
            student.`name`,
            student.sex
        FROM
            student
    </select>
</mapper>

1.1.4、实现分页

StudentService.java:

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhangguo.mybatisdemo3.dao.StudentDao;
import com.zhangguo.mybatisdemo3.entity.Student;
import com.zhangguo.mybatisdemo3.util.PageRequest;
import com.zhangguo.mybatisdemo3.util.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentService {
    @Autowired
    StudentDao studentDao;

    public PageInfo<Student> selectPager(int pageNum,int pageSize){
        //开始分页,指定页码与每页记录数
        PageHelper.startPage(pageNum,pageSize);
        //执行查询,请求会被分页插件拦截
        List<Student> students = studentDao.selectPager();
        //返回分页对象与数据
        return new PageInfo<Student>(students);
    }
}

1.1.5、调用分页方法

 PageController.java:

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3.controller;

import com.github.pagehelper.PageInfo;
import com.zhangguo.mybatisdemo3.entity.Student;
import com.zhangguo.mybatisdemo3.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PageController {

    @Autowired
    StudentService studentService;

    @GetMapping
    public PageInfo<Student> hello(@RequestParam(value = "pageNum",required = false,defaultValue = "1") int pageNum, @RequestParam(value = "pageSize",required = false,defaultValue = "3")int pageSize){
        return studentService.selectPager(pageNum,pageSize);
    }
}

pageNum参数用于指定页号,默认值为1,pageSize用于指定每页记录数,默认值为3。

运行结果:

默认值情况

带参数情况

pageNum:当前页的页码 pageSize:每页显示的条数 size:当前页显示的真实条数 total:总记录数 pages:总页数 prePage:上一页的页码 nextPage:下一页的页码 isFirstPage/isLastPage:是否为第一页/最后一页 hasPreviousPage/hasNextPage:是否存在上一页/下一页 navigatePages:导航分页的页码数 navigatepageNums:导航分页的页码,[1,2,3,4,5]

1.2、封装请求与结果

默认情况下请求参数并没有使用对象封装,返回结果包含冗余信息且需要与具体的业务关联。

1.2.1、请求参数封装

PageRequest.java 

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3.util;
/**
 * 分页请求
 */
public class PageRequest {
    /**
     * 当前页码
     */
    private int pageNum;
    /**
     * 每页数量
     */
    private int pageSize;
    
    public int getPageNum() {
        return pageNum;
    }
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
}

1.2.2、响应结果封装

 PageResult.java

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3.util;
import com.github.pagehelper.PageInfo;

import java.util.List;
/**
 * 分页返回结果
 */
public class PageResult {
    /**
     * 当前页码
     */
    private int pageNum;
    /**
     * 每页数量
     */
    private int pageSize;
    /**
     * 记录总数
     */
    private long totalSize;
    /**
     * 页码总数
     */
    private int totalPages;
    /**
     * 数据模型
     */
    private List<?> content;

    public int getPageNum() {
        return pageNum;
    }
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public long getTotalSize() {
        return totalSize;
    }
    public void setTotalSize(long totalSize) {
        this.totalSize = totalSize;
    }
    public int getTotalPages() {
        return totalPages;
    }
    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }
    public List<?> getContent() {
        return content;
    }
    public void setContent(List<?> content) {
        this.content = content;
    }

    /**
     * 将分页信息封装到统一的接口
     * @return
     */
    public static PageResult getPageResult(PageInfo<?> pageInfo) {
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(pageInfo.getPageNum());
        pageResult.setPageSize(pageInfo.getPageSize());
        pageResult.setTotalSize(pageInfo.getTotal());
        pageResult.setTotalPages(pageInfo.getPages());
        pageResult.setContent(pageInfo.getList());
        return pageResult;
    }
}

二、跨域

2.1、跨域概要

跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

例如:a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。注意:跨域限制访问,其实是浏览器的限制。理解这一点很重要!!!

同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;

 2.2、返回新的CorsFilter(全局跨域)

CORS,全称Cross-Origin Resource Sharing  ,是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。

在任意配置类,返回一个 新的 CorsFIlter Bean ,并添加映射路径和具体的CORS配置路径。

代码语言:javascript
复制
@Configuration
public class GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        config.addAllowedOrigin("*");
        //是否发送 Cookie
        config.setAllowCredentials(true);
        //放行哪些请求方式
        config.addAllowedMethod("*");
        //放行哪些原始请求头部信息
        config.addAllowedHeader("*");
        //暴露哪些头部信息
        config.addExposedHeader("*");
        //2. 添加映射路径
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**",config);
        //3. 返回新的CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }
}

2.3、重写WebMvcConfigurer(全局跨域)

代码语言:javascript
复制
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                //是否发送Cookie
                .allowCredentials(true)
                //放行哪些原始域
                .allowedOrigins("*")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

2.4、使用注解 (局部跨域)

在控制器(类上)上使用注解 @CrossOrigin:,表示该类的所有方法允许跨域。

代码语言:javascript
复制
@RestController
@CrossOrigin(origins = "*")
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "hello world";
    }
}

在方法上使用注解 @CrossOrigin:

代码语言:javascript
复制
  @RequestMapping("/hello")
  @CrossOrigin(origins = "*")
   //@CrossOrigin(value = "http://localhost:8081") //指定具体ip允许跨域
  public String hello() {
        return "hello world";
  }

2.5、手动设置响应头(局部跨域)

使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。

代码语言:javascript
复制
@RequestMapping("/index")
public String index(HttpServletResponse response) {

    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

2.6、使用自定义filter实现跨域

首先编写一个过滤器,可以起名字为MyCorsFilter.java

代码语言:javascript
复制
package cn.wideth.aop;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

@Component
public class MyCorsFilter implements Filter {

  public void doFilter(ServletRequest req, ServletResponse res, 
  FilterChain chain) throws IOException, ServletException {
  
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
    chain.doFilter(req, res);
    
  }
  
  public void init(FilterConfig filterConfig) {}
  public void destroy() {}
}

三、上传

前端使用Vue+Axios实现AJAX上传文件,upfile.html如下:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传文件示例</title>
</head>
<body>
    <div id="app">
        <h2>上传文件示例</h2>
        <input type="file" @change="getfiles($event)"/>
        <button type="button" @click="upfiles($event)">提交</button>
    </div>
    <script src="vue/vue.js"></script>
    <script src="axios/axios.min.js"></script>
    <script>
        var app=new Vue({
            el:"#app",
            data:{
                file:{}
            },
            methods:{
                getfiles(event){
                    this.file=event.target.files[0];
                    console.log(this.file);
                },
                upfiles:function(event){
                    event.preventDefault;
                    var formdata=new FormData();
                    formdata.append("file",this.file);

                    axios.post("http://localhost:8080/upfile",formdata,{
                        Headers:{
                            "Content-Type":"multipart/form-data"
                        }
                    }).then(function(response){
                        console.log(response);
                        console.log("ok");
                    }).catch(function(error){
                        console.log(error);
                    });
                }
            }
        });
    </script>
</body>
</html>

application.yaml文件

代码语言:javascript
复制
#文件的限制大小
  servlet:
    multipart:
      max-file-size: 100MB  #文件最大值
      max-request-size: 100MB #请求最大值
prop:
  up-folder: F:\NF\Spring boot\demos\CORSDemo1\uploads\  #上传目标位置

后端控制器

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
public class UpfileController {
    @Value("${prop.up-folder}")
    String path;
    
    @PostMapping("/upfile")
    public String upfile(@RequestPart("file") MultipartFile file) throws IOException {
        String oldname=file.getOriginalFilename();
        //新的文件名=UUID+原文件后缀名
        String newname= UUID.randomUUID().toString()+oldname.substring(oldname.lastIndexOf("."));
        file.transferTo(new File(path+file.getOriginalFilename()));
        return newname;
    }
}

运行效果

四、启动Banner定制

我们在应用启动的时候,可以看到控制台显示了Spring的Banner信息,我们可以通过定制这个功能,来放置我们自己的应用信息。

 如果要定制自己的Banner, 只需要在 resources 下放置一个 banner.txt 文件,输入自己的banner字符即可。

 重新启动项目

Banner字符可以通过类似以下网站生成:

http://patorjk.com/software/taag

http://www.network-science.de/ascii/

五、lombok

5.1、lombok概要

Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。仅五个字符(@Data)就可以替换数百行代码从而产生干净,简洁且易于维护的Java类。

在项目中使用Lombok可以减少很多重复代码的书写。比如说getter/setter/toString等方法的编写。

“Boilerplate”是一个术语,用于描述在应用程序的许多部分中很少改动就重复的代码。对Java语言最常见的批评就是在大多数项目中都可以找到这种类型的代码,由于语言本身的局限性而更加严重。龙目岛计划(Project Lombok)旨在通过用简单的注释集代替众多的代码。

Lombok也存在一定风险,在一些开发工具商店中没有Project Lombok支持选择。 IDE和JDK升级存在破裂的风险,并且围绕项目的目标和实施存在争议。

常用注解:

  1. @Setter :注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
  2. @Getter :使用方法同上,区别在于生成的是getter方法。
  3. @ToString :注解在类,添加toString方法。
  4. @EqualsAndHashCode: 注解在类,生成hashCode和equals方法。
  5. @NoArgsConstructor: 注解在类,生成无参的构造方法。
  6. @RequiredArgsConstructor: 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@NonNull注解的字段。
  7. @AllArgsConstructor: 注解在类,生成包含类中所有字段的构造方法。
  8. @Data: 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
  9. @Slf4j: 注解在类,生成log变量,严格意义来说是常量。

5.2、引入依赖

在pom文件中添加如下部分。(不清楚版本可以在Maven仓库中搜索)

代码语言:javascript
复制
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

5.3、使用注解

代码语言:javascript
复制
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data  //注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
@AllArgsConstructor  // 注解在类,生成包含类中所有字段的构造方法。
@NoArgsConstructor  //注解在类,生成无参的构造方法。
public class Department {
  private Integer departmentId;
  private String departmentName;
}

 5.4、运行测试

测试类:

代码语言:javascript
复制
package com.zhangguo.mybatisdemo3;

import com.zhangguo.mybatisdemo3.entity.Department;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class DepartmentTest {
    @Test
    public void lombokTest(){
        Department department=new Department(1,"研发部");
        System.out.println(department);
    }
}

测试结果:

代码语言:javascript
复制
Department(departmentId=1, departmentName=研发部)

可以看到有带参构造方法,toString方法也被重写过了。

需要注意的是新版本的IDEA不再需要安装插件,已经默认整合了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、分页(pagehelper)
    • 1.1、快速起步
      • 1.1.1、添加依赖
      • 1.1.2、添加配置
      • 1.1.3、数据访问接口
      • 1.1.4、接口映射
      • 1.1.4、实现分页
      • 1.1.5、调用分页方法
    • 1.2、封装请求与结果
      • 1.2.1、请求参数封装
      • 1.2.2、响应结果封装
  • 二、跨域
    • 2.1、跨域概要
      •  2.2、返回新的CorsFilter(全局跨域)
        • 2.3、重写WebMvcConfigurer(全局跨域)
          • 2.4、使用注解 (局部跨域)
            • 2.5、手动设置响应头(局部跨域)
              • 2.6、使用自定义filter实现跨域
              • 三、上传
              • 四、启动Banner定制
              • 五、lombok
                • 5.1、lombok概要
                  • 5.2、引入依赖
                    • 5.3、使用注解
                      •  5.4、运行测试
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档