SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等

SpringBoot

SpringBoot的简介
  • Spring Boot,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程简化 Maven 配置自动配置 Spring嵌入的 Tomcat,无需部署 WAR 文件,可直接运行
  • Spring家族为微服务提供了一整套的组件,统称为SpringCloud。
  • SpringBoot和微服务紧密联系在一起,是微服务的基石。SpringCloud开发微服务是建立在SpringBoot基础之上的
本文只记录SpringBoot的使用,关于SpringCloud微服务的下一文介绍。

(一)快速入门

(以Idea为例)

1、项目创建,工程主界面如下:
SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第1张图片 SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第2张图片 SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第3张图片 SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第4张图片
SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第5张图片
2、编写HelloController.java :

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String sayHello() {
        return "hello spring Boot!";
    }
}

3、启动SpringbootDemoApplication类main方法:
4、访问http://localhost:8080/hello

  • 项目说明
    • 默认有个xxxApplication类,里面是spring boot的载入函数
    • resources目录下有个application.properties文件,这个是Spring boot的配置文件
      • 这个Spring boot的配置文件又可以改为 application.yml文件(常用的是这种配置)
        • application.yml文件修改tomcat端口等示例(后面说明yml):
          • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第6张图片
    • test目录下有个测试类xxxApplicationTests,这个是spring boot的单元测试
    • pom.xml文件:
      • 一个继承spring-boot-starter-parent
      • 两个依赖,spring-boot-starter-web ,web项目依赖必须
      • spring-boot-starter-test spring boot项目单元测试依赖
    • Springboot程序启动方式
      • 方式一:通过idea直接启动,在启动类上run
      • 方式二:java -jar XX.jar 运行jar包

(二)基本web应用开发

1、SpringBoot 热部署

热部署:在修改项目文件后,不需要重启应用程序,修改之后就可以立刻生效。

配置步骤:

  • 1.1. 添加devtools依赖并开启热部署(修改pom.xml文件)

添加devtools依赖:

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

开启热部署

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <!--在原来spring-boot-maven-plugin 追加以下语句:开启热部署-->
    <configuration>
        <fork>true</fork>
    </configuration>
</plugin>
  • 1.2. 开启idea自动make功能
    • CTRL + SHIFT + A --> 查找make project automatically --> 选中 :
      或者点击file --> Settings: --> 选中:
      • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第7张图片
    • CTRL+SHIFT+A查找Registry并勾选compiler.automake.allow.when.app.running:
      • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第8张图片
    • 最后重启idea
  • 1.3. Chrome浏览器中禁用缓存
    • F12 --> NetWork --> Disable Cache(while DevTools is open) :
    • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第9张图片

2、SpringBoot对的json支持

  • @JsonFormat(timezone = “GMT+8”, pattern = “yyyy年MM月dd日 HH时mm分ss秒”)
    • 时间格式化成字符串的格式,即获取时间时会按照该格式返回。
    • GMT 是世界标准时间。中国所在时区就是gmt+8 。
  • @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)
    • 字符串格式化成时间的格式,在设置该属性时必须按照以上的格式要求 本例比如:2020-03-03 12:12:12
  • @JsonIgnore
    • 忽略字段,不转换为json
  • @JsonInclude(JsonInclude.Include.NON_NULL)
    • 当属性值为空时候,不转换为json 不为空时转换为json
  • @InitBinder
    • 用来格式化request请求中字符串(2018-01-19 17:25:29)为日期时间类型,如果字符串格式不满足要求,就会报错。
    • @InitBinder就相当于全局的时间格式化注解,而@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)只针对类的属性。

使用示例:
新建pojo:Goods.java

package com.offcn.demo.bean;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

public class Goods{
	private int id;
	private String name;
	private float price;
	
	//格式化输出,格式化日期时间类型
	//GMT 是世界标准时间。中国所在时区就是gmt+8 。
	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd hh:mm:ss")
	@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
	private Date createDate;
	
	//忽略字段,不转换为json
	@JsonIgnore
	private String memo;
	//当属性值为空时候,不转换为json
	@JsonInclude(JsonInclude.Include.NON_NULL)
	private String isnull;
	private String email;
	//Set、get方法略
}

创建controller:GoodsController.java

@RestController
public class GoodsController {
	@RequestMapping("/getGoods1")
	public Goods getGoods() {		
		Goods goods = new Goods();
		goods.setId(1);
		goods.setName("测试");
		goods.setPrice(100000.99F);
		goods.setCreateDate(new Date());
		goods.setMemo("描述");
		goods.setIsnull("不为空显示");
		return goods;
	}
	@InitBinder
	private void initBinder(WebDataBinder webDataBinder){
		webDataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
	}
}

启动访问

3、SpringBoot 请求传递参数

第一类:请求路径传参

  • @RequestParam 获取查询参数。即url?name=value
  • @PathVariable 获取路径参数。即url/{id} 这种形式
@RequestMapping("/getGoods2/{name}")
public Goods getGoodsById(@RequestParam(name="id") Integer id,
							@PathVariable(name="name") String name) {		
		Goods goods = new Goods();
		goods.setId(id);
		goods.setName(name);
		goods.setPrice(100000.99F);
		goods.setCreateDate(new Date());
		goods.setMemo("描述");
		goods.setIsnull("不为空显示");
		return goods;
}

第二类:@RequestBody参数

  • @RequestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。
  • 常用其来处理application/json类型,后台接收前台的json格式数据。比如说:"{‘title’:‘test’, ‘sub’ : ‘2’}"
@RequestMapping("/getGoods3")
public Goods getGoodsById(@RequestBody Goods goods) {
      return goods;
}	
  • 测试:开启postman,设置发出post请求,请求地址getGoods3接口:http://localhost:8080/getGoods3
  • 请求参数,选择body,选择 raw方式,发送JSON(application/json)请求
  • 请求数据数据:{"id":999,"name":"兰博基尼","price":9999.98,"createDate":"2018-12-15 9:18:28","memo":"描述","isnull":"不为空"}

第三类:Body参数(表单)

普通的表单提交方式。

@RequestMapping("/getGoods4")
public Goods getGoodsById(Goods goods) {
	return goods;
}	
@InitBinder
private void initBinder(WebDataBinder webDataBinder){
	webDataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
}
  • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第10张图片

4、SpringBoot 参数校验

PathVariable路径参数校验

    //[a-zA-Z0-9_]+ 表达式指定了 group 必须是以大小写字母、数字或下划线组成的字符串。
    @GetMapping("/user/{id:[a-zA-Z0-9_]+}")  
    public String getUserById(@PathVariable String id){
        return "根据id查询用户:"+id;
    }

尝试访问地址:http://localhost:8080/user/a8799
http://localhost:8080/user/a87-99

RequestParam请求参数校验

@RestController
@Validated  //开启数据有效性校验,添加在类上即为验证方法,/// 添加在方法参数中即为验证参数对象。
public class UserController {
    @GetMapping("/demo123")
    public String user(@NotBlank(message = "id不能为空!") @RequestParam("userid") String id,
                       @NotBlank(message = "name不能为空!") @RequestParam("username") String name,
                       @Email(message = "email格式不正确!") String email){
        return id+"==》"+name;
    }
}

测试:http://localhost:8080/valid2?group=&email=11

这里的异常名称叫ConstraintViolationException(违反约束异常)

附带异常的处理:
编写统一异常处理类
处理单个异常:

@ControllerAdvice //增强的 Controller 可以用来 全局异常处理  全局数据绑定和预处理 本示例处理异常
public class GlobalExceptionHandler {
	//@ExceptionHandler 是 Controller层面上异常处理注解
    @ExceptionHandler(ConstraintViolationException.class)//参数校验异常
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)  //400 : 参数报错
    public String handleValidationException(ConstraintViolationException e){
        String msg = "请求参数不合法,  ";
        for(ConstraintViolation<?> s:e.getConstraintViolations()){
            msg += s.getInvalidValue()+": "+s.getMessage() + ";";
        }
        return msg;
    }
}

处理多个异常:

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class) //Exception
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleValidationException(Exception e){
        if(e instanceof ConstraintViolationException ){
            ConstraintViolationException exception = (ConstraintViolationException)e;
            for(ConstraintViolation<?> s:exception.getConstraintViolations()){
                return s.getInvalidValue()+": "+s.getMessage();
            }
        }else if(e instanceof MethodArgumentNotValidException){
            return ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage();
        }
        return "请求参数不合法";
    }
}

对象参数校验(表单 pojo) JSR-303 标准的校验

注解 作用
@Validated (重要) 开启数据有效性校验,添加在类上即为验证方法,添加在方法参数中即为验证参数对象。
@NotNull 限制字段必须不为null value != null ? true : false
@NotEmpty 验证注解的元素值不为 null 且不为空,可用在字符串或集合。(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),@NotBlank只应用于字符串且在比较时会去除字符串的空格 value.trim() > 0 ? true : false
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在 min 到 max 之间(也可以用在集合上)
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
@Max(value) 限制必须为一个不大于指定值的数字 对应的数据库表字段也会添加一个check的约束条件
@Min(value) 限制必须为一个不小于指定值的数字 同上
@DecimalMax(value) 限制必须为一个不大于指定值的数字 没有上述作用
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Null 限制只能为null(很少用)
@AssertFalse 限制必须为false (很少用)
@AssertTrue 限制必须为true (很少用)
@Past 限制必须是一个过去的日期
@Future 限制必须是一个将来的日期
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过 integer,小数部分的位数不能超过 fraction (很少用)
@Length 被注释的字符串的大小必须在指定的范围内

示例:
1、修改Goods增加对参数的校验规则

public class Goods {
	@Max(value=100,message="id不能大于100")
	private int id;
	
	@NotBlank(message="用户名不能为空")
	@Length(min = 2, max = 10, message = "用户名 长度必须在 {min} - {max} 之间")
	private String name;
	
	@DecimalMin(value="1.0",message="价格最低1元")
	@DecimalMax(value="10.0",message="价格最高10元")
	private float price;
	
	//格式化日期时间类型
	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd hh:mm:ss")
	@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
	private Date createDate;
	
	//忽略字段,不转换为json
	@JsonIgnore
	private String memo;
	
	//复杂校验
	//当属性值为空时候,不转换为json
	@JsonInclude
	@NotNull(message="属性字段不能为空")
	@NotBlank(message="属性字段不能为空白")
	private String isnull;
	
	@NotBlank(message="手机号不能为空")
	@Pattern(regexp = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$",
		    message = "手机号格式不合法")
	private String telephone;
	//验证邮箱格式
	@Pattern(regexp = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$",
	message = "邮箱格式不合法")
	private String email;

	//Set get方法略
}

2、创建Controller

@RestController
public class GoodsValidation {
	@RequestMapping("/getGoodsvalidation1")
	public Goods getGoodsvalidation1(@RequestBody @Validated Goods goods) {
		return goods;
	}
}

3、

  • 开启postman,设置发出post请求,请求地址:http://localhost:8080/getGoodsvalidation1
  • 请求参数,选择body,选择 raw方式,发送JSON(application/json)请求
  • 请求数据数据1:{"id":999,"name":"你好","price":8.98,"createDate":"2018-12-15 9:18:28","memo":"描述","isnull":"不为空"}

5、SpringBoot 静态资源

默认静态资源映射

  • Spring Boot 默认将 /** 所有访问映射到以下目录:
    • classpath:/static
    • classpath:/public
    • classpath:/resources (resources下创建的resources目录)
    • classpath:/META-INF/resources
    • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第11张图片
  • 示例:
    • 如:在resources目录下新建 public、resources、static 三个目录并分别放入 a.jpg b.jpg c.jpg 图片
    • 浏览器分别访问:http://localhost:8080/a.jpg 、http://localhost:8080/b.jpg、http://localhost:8080/c.jpg均正常访问。

自定义静态资源目录访问

第一种方式
  • 1、配置类(Springboot推荐使用java的方式做配置)、注意::@Configuration注解 ==== applicationContent.xml
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 将所有D:\\springboot\\pic\\   访问都  映射到 /myPic/**   路径下
		registry.addResourceHandler("/myPic/**").addResourceLocations("file:D:\\springboot\\pic\\");
    }
}
  • 示例:在D:/springboot/pic/中有一张logo.jpg图片,重启项目后,在浏览器输入:http://localhost:8080/myPic/logo.jpg即可访问
第二种方式
  • 配置application.properties
web.upload-path=D:/springboot/pic/
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/a/b/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}
# 注意:
# web.upload-path:这个属于自定义的属性,指定了一个路径,注意要以/结尾;
# spring.mvc.static-path-pattern=/**:表示所有的访问都经过静态资源路径;
# spring.resources.static-locations:在这里配置静态资源路径,
# 这里的配置是覆盖默认配置,所以需要将默认的也加上,
# 否则static、public等这些路径将不能被当作静态资源路径,
# 在这个最末尾的file:${web.upload-path}之所以要加file:是因为指定的是一个具体的硬盘路径,
# 其他的使用classpath指的是系统环境变量。

6、WebJars:以jar包方式打包的web资源(jquery,bootstrap等)。

  • 在SpringBoot中,允许我们直接访问WEB-INF/lib下的jar包中的/META-INF/resources目录资源,即WEB-INF/lib/{*.jar}/META-INF/resources下的资源可以直接访问
  • WebJars也是利用了此功能,将所有前端的静态文件(如jQuery & Bootstrap)打包成一个jar包,和普通的jar引入是一样的,还能很好的对前端静态资源进行管理
使用示例:

1、添加jquery和Bootstrap的webjars依赖 如需其他,WebJars查询:https://www.webjars.org/all

<dependency>
    <groupId>org.webjarsgroupId>
    <artifactId>jqueryartifactId>
    <version>3.3.1-1version>
dependency>
<dependency>
    <groupId>org.webjarsgroupId>
    <artifactId>bootstrapartifactId>
    <version>4.2.1version>
dependency>

  • 如图:SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第12张图片

  • 可以了解到静态文件存放规则:META-INF/resources/webjars/${name}/${version}

2、html引入:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    
    <script src="webjars/jquery/3.3.1-1/jquery.js">script>
head>
<body>
	<div align="center">
		我的第一个springboot应用
	div>
	<script>
	    $(function () {
	        alert("jquery生效")
	    })
	script>
body>
html>

(三)SpringBoot属性配置

  • Spring Boot并不是『零配置』,它的理念是“习惯优于配置”采用了一些默认的习惯性配置,让你无需手动进行配置,从而让你的项目快速运行起来。所以要想玩转Spring Boot,了解这些默认配置还是必不可少的。

1、默认属性配置文件

  • 创建Spring Boot项目时,在src/main/resources目录下,会默认生成一个全局配置文件application.properties(可以修改后缀为.yml)
  • 注意:application.yml和application.properties编写的格式不一样
  • yml语法:
    • k: v 表示键值对关系,冒号后面必须有一个空格
    • 使用空格的缩进表示层级关系,左对齐的一列数据,都是同一个层级的

修改tomcat端口和访问路径示例:

server:
  port: 8888
  servlet:
    context-path: /java001

2、自定义属性及读取

  • 自定义属性简单赋值
  • 1、application.yml文件中,配置常量:
server:
  port: 8088
  servlet:
    context-path: /java001
my_ip: 1.1.1.1
my_port: 9999
  • 2、编写Controller类读取自定义属性:
@RestController
public class HelloConfigController {

	@Value("${server.port}")
	String port;
	@Value("${my_ip}")
	private String ip;
	@Value("${my_port}")
	private String port;
	
	@GetMapping("/getvalue")
	public String getValue() {
		return port +","+ ip +","+ port;
	}
}

浏览器访问:http://localhost:8088/getvalue

3、实体类属性赋值

  • 若属性参数变多的时候,习惯创建一个实体,用实体来统一接收这些属性值。

(1)、定义配置文件

userbody:
  name: me
  password: 123456
  birthday: 1992.10.28
  mobile: 13812345678
  address: 北京市朝阳区

(2)、创建实体类

//需要在实体类上增加注解@ConfigurationProperties,并指定prrfix前缀。
@ConfigurationProperties(prefix="userbody")
public class UserBody {
	    private String name;
	    private String password;
	    private String birthday;
	    private String mobile;
	    private String address;
	    //Setget方法略
}

(3)、编写Controller注入属性bean

@RestController
@EnableConfigurationProperties({UserBody.class})
public class HelloControllerBean {
	@Autowired
	UserBody userbody;

    @GetMapping("/getUser")
    public String getUser(){
        return userbody.toString();
    }
}

浏览器访问:http://localhost:8088/getUser

4、自定义配置文件

  • application.yml/application.properties是系统默认的配置文件(只能写一个)
  • 但也可以创建自定义配置文件,在路径src/main/resources下面创建文件test.properties/yml
  • 注意:spring boot 1.5版本后@PropertySource注解就不能加载自定义的yml配置文件了,但可以加载properties

1、定义test.properties

testuser.name = me
testuser.password = 123
testuser.birthday = 1978.10.28

2、将配置赋值到javabean

@Configuration
@PropertySource("classpath:test.properties")
@ConfigurationProperties(prefix = "testuser")
public class TestUser {
	private String name;
    private String password;
    private String birthday;
	//Set get方法略
}

3、Controller 读取配置

@RestController
@EnableConfigurationProperties({TestUser.class})
public class TestController {
    @Autowired
    TestUser testUser;
    
    @GetMapping("/getUser2")
    public String getUser2(){
        return testUser.toString();
    }

}

浏览器访问:http://localhost:8088/getUser2

5、多环境配置文件

  • 使用多个yml配置文件进行配置属性文件,将于环境无关的属性放置到application.yml文件里面;通过与配置文件相同的命名规范,创建application-{profile}.yml文件 存放不同环境特有的配置
  • 例如 application-test.yml 存放测试环境特有的配置属性,application-prod.yml 存放生产环境特有的配置属性。开发环境、测试环境、生产环境(正式环境) 等。
  • 通过这种形式来配置多个环境的属性文件,在application.yml文件里面spring.profiles.active=xxx来指定加载不同环境的配置如果不指定,则默认只使用application.yml属性文件,不会加载其他的profiles的配置。

创建application-dev.yml:

server:
  port: 8003
  servlet:
    context-path: /java003

创建application-test.yml:

server:
  port: 8001
  servlet:
    context-path: /java001

创建application-prod.yml:

server:
  port: 8002
  servlet:
    context-path: /java002

修改application.yml:active 的值对应不同的{profile}环境

spring:
   profiles:
    active: test
#   调用application-test.yml的环境配置文件

6、lombok的使用:

关于写pojo,和属性注入等,总是需要繁琐又无含量的操作,可以简单的注解形式来简化java代码,提高开发人员的开发效率。

使用步骤:
1、使用maven添加依赖

<dependency>
	<groupId>org.projectlombokgroupId>
	<artifactId>lombokartifactId>
	<version>1.16.18version>
	 
	<scope>providedscope>
dependency>

2、添加ide工具对Lombok的支持(本示例为Idea)

  • 打开file,点击Settings,点击Plugins,点击Browse repositories,在弹出的窗口中搜索lombok,然后安装即可

  • SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第13张图片
  • 常用的几个注解

注解 作用
@Setter 注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
@Getter 注解在类或字段,注解在类时为所有字段生成getter方法,注解在字段上时只为该字段生成getter方法。
@ToString 注解在类,添加toString方法。
@EqualsAndHashCode 注解在类,生成hashCode和equals方法。
@NoArgsConstructor 注解在类,生成无参的构造方法。
@AllArgsConstructor 注解在类,生成包含类中所有字段的构造方法。
@RequiredArgsConstructor 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@NonNull注解的字段。
@Data 作用于类上,生成所有属性的get和set方法、toString 方法、hashCode方法、equals方法

在pojo上的简单使用:

import lombok.Data;
@Data
public class User {
    private int id;
    private String name;
}

在调度层上的简单使用

@RestController
@RequestMapping(value="/person")
@AllArgsConstructor(onConstructor_ ={@Autowired} ) //相当于对属性进行了注入
public class PersonController {
    
    //类上面有这句话 @AllArgsConstructor(onConstructor_ ={@Autowired} )  
    // 属性 就不用再写这个 @Autowired
    // @Autowired 
    PersonDao personDao;
    
    @RequestMapping("/add")
    public Person add(){
        Person person = new Person();
        person.setName("sss");
        person.setAge(222);
        Person save = personDao.save(person);
        return save;
    }
}

(四)SpringBoot使用JPA操作数据库

1、JPA介绍:

  • JPA(Java Persistence API),dao层的框架,是用来描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
  • JPA支持面向对象的查询语言JPQL;(SQL是面向数据库的
  • JPA定义了独特的JPQL(Java Persistence Query Language),它是针对实体的一种查询语言操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等高级查询特性以及子查询

2、JPA注解

注解 作用
@Entity 声明类为实体或表,@Entity 说明这个 class 是实体类,默认 class 名即数据库表中表名,也可以指定表名: @Entity(name=“ss”) 用来指定映射的表名(但不建议使用该方式)
@Table 声明表名,@Table 注解指定了 Entity 所要映射带数据库表,其中 @Table(name=“ss”) 用来指定映射表的表名(指定表名建议使用这种方式)。存在表名优先级:@Table > @Entity
@Basic 指定非约束明确的各个字段
@Embedded 指定类或它的值是一个可嵌入的类的实例的实体的属性
@Id 指定的类的属性,用于识别(一个表中的主键)
@GeneratedValue 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值,默认值是自动,相当于sql的主键的自增概念
@Transient 指定的属性,它是不持久的,即:该值永远不会存储在数据库中
@Column 指定持久属性栏属性
@SequenceGenerator 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列
@TableGenerator 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表
@AccessType 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量
@JoinColumn 指定一个实体组织或实体的集合。这是用在多对一和一对多关联
@UniqueConstraint 指定的字段和用于主要或辅助表的唯一约束
@ColumnResult 参考使用select子句的SQL查询中的列名
@ManyToMany 定义了连接表之间的多对多一对多的关系
@ManyToOne 定义了连接表之间的多对一的关系
@OneToMany 定义了连接表之间存在一个一对多的关系
@OneToOne 定义了连接表之间有一个一对一的关系
@NamedQueries 指定命名查询的列表
@NamedQuery 指定使用静态名称的查询

3、SpringBoot 使用JPA入门

1、添加jpa依赖以及mysql、jdbc驱动、连接池druid驱动

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-jpaartifactId>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>druidartifactId>
        <version>1.1.10version>
    dependency>

2、修改springboot配置文件application-dev.yml增加如下jpa配置:配置数据源 账号密码等

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/springboot-001?serverTimezone=GMT%2B8
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  • 这里:show-sql: true是在控制台打印sql语句,
  • jpa.hibernate.ddl-auto属性的主要作用是:自动创建、更新、验证数据库表结构。
    • 常见配置值如下:
      • create:每次加载jpa时都会删除上一次生成的表,然后根据model实体类重新生成新表。
      • update:最常用的属性,第一次加载jpa时,根据model实体类会自动建表(前提是先建立好数据库),以后加载jpa时,根据model类自动更新表结构,表中数据不会删除。 要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。

3、在application.yml中加载dev环境的配置文件

spring:
  profiles:
    active: dev

4、创建实体

import lombok.*;
import javax.persistence.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tb_Person")//指定表名为 tb_Person 若默认使用类名作为表名 不用加 @Table 注解
public class Person {
        @Id  //声明为主键
        @GeneratedValue  //设置自动增长,+1
        private Long id;

        //字段标注 @Column  name默认不写就是属性名和字段名一致。 nullable是否可为空 length长度
        @Column(name = "name", nullable = true, length = 20)
        private String name;

        @Column(name = "age", nullable = true, length = 4)
        private int age;
}

5、新建数据访问接口

  • Jpa中提供了JpaRepository接口,创建一个接口继承这个接口便拥有了一些基本的单表crud操作
///*JpaRepository  实体类的类型:Person,主键的类型:Long*/
public interface PersonDao extends JpaRepository<Person, Long> {
}

6、创建Controller

import com.example.jpademo.dao.PersonDao;
import com.example.jpademo.pojo.Person;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(value="/person")
public class PersonController {

    @Autowired
    PersonDao personDao;

    @RequestMapping("/add")
    public Person add(){
        Person person = new Person();
        person.setName("sss");
        person.setAge(222);
        Person save = personDao.save(person);
        return save;
    }
    @RequestMapping("/delete/{id}")
    public void  delete(@PathVariable Long id){
        personDao.deleteById(id);
    }

    @RequestMapping("/update/{id}")
    public void  update(@PathVariable Long id){
        Person person = personDao.findById(id).get();
        person.setName("教育");
        personDao.save(person); //没有主键 id,调用该方法就为添加,有id的,就为修改
    }
    @RequestMapping("/findAll")
    public List<Person> findAll(){
        return personDao.findAll();
    }
}

7、测试数据

8、再修改Person添加属性

@Column(name = "password", nullable = true, length = 20)
private String password;

9、重启工程,person表会更新出password字段。

4、按照规定格式命名方法来实现查询

  • 通过继承JpaRepository接口,除了拥有基本CRUD操作方法之外,还可以通过官方规定的格式来命名方法自动创建复杂的CRUD操作,命名规则表如下:
  • find/get/query开头都代表查询
    SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第14张图片
    使用示例:
    1、编辑PersonDao,新增如下方法
public interface PersonDao extends JpaRepository<Person, Long> {
	//查询指定用户姓名的用户
	public Person findByNameIs(String name);
	//查询指定用户姓名和密码都相同的用户
	public Person findByNameIsAndPassword(String name,String password);
	//查询包含指定名字的用户
	public List<Person> findByNameContaining(String name);
}

2、新增Controller 类Person2Controller

@RestController
@RequestMapping("/person2")
public class Person2Controller {

	@Autowired
	PersonDao personDao;
	
	@GetMapping("findByNameIs/{name}")	
	public Person findByNameIs(@PathVariable String name) {
		return personDao.findByNameIs(name);
	}
	
	@GetMapping("findByNameIsAndPassword/{name}/{password}")	
	public Person findByNameIsAndPassword(@PathVariable String name,
											@PathVariable String password) {
		return personDao.findByNameIsAndPassword(name, password);
	}
	
	@GetMapping("findByNameContaining/{name}")	
	public List<Person> findByNameContaining(@PathVariable String name) {
		return personDao.findByNameContaining(name);
	}
}

4、测试

5、使用@Query实现自定义查询语句

  • 在接口方法中通过定义@Query 注解 自定义接口方法的JPQL语句
  • 注意:@Query的查询语句默认是面向对象的语法,也可以设置nativeQuery=true来使用原始sql语句。 见示例:

1、编辑PersonDao,新增如下方法

	//查询指定用户姓名的用户 使用名字参数查询
	@Query("select p from Person p where p.name=:name") //这是JPQL语句
	public Person getPerson(@Param("name") String name);

	//用户登录验证(多个参数的写法) 使用位置参数查询
	@Query("select p from Person p where p.name=?1 and p.password=?2")
	Public Person login(@Param("name") String name,@Param("password") String password);
	
	//模糊查询用户名里面包含指定字符 
	@Query("select p from Person p where p.name like %:name%")
	public List<Person> getNamesLike(@Param("name") String name);
	
	//查询密码是5位数的全部用户 使用原始sql查询
	@Query(value="select * from person where length(password)=5",nativeQuery=true) //使用原始sql
	public List<Person> getPasswordisFive();

6、@Modifying、@Transactional组合进行更新、删除

  • @Modifying的主要作用是声明执行的SQL语句是更新(增删改)操作@Transactional的主要作用是提供事务支持(提供例如隔离性等事务特性,JPA默认会依赖JDBC默认隔离级别)。
  • 默认情况下JPA的每个操作都是事务的,在默认情况下,JPA的事务会设置为只读

示例:
1、编辑PersonDao,新增如下方法

	//修改用户名称,使用自定义语句来更新,需要显示声明开启写事务
	@Modifying
	@Transactional(readOnly = false)
	@Query("update Person p set p.name=?2 where p.id=?1")
	int UpdateName(Long id,String name);
	
	//删除指定用户用户,需要显示声明开启写事务
    @Modifying
    @Transactional(readOnly = false)
    @Query("delete from Person p where p.name=?1")
    int DeleteName(String name);

2、编辑Controller 类Person3Controller新增方法updateName

	@PutMapping(path="updateName/{id}/{name}")
	public int updateName(@PathVariable Long id,@PathVariable String name) {
		return personDao.UpdateName(id,name);
	}
	
	@DeleteMapping(path="deleteName/{name}")
	public int DeleteName(@PathVariable String name) {
		return personDao.DeleteName(name);
	}

7、分页和排序

  • Spring Data JPA 默认实现了分页功能,在查询的方法中,需要传入参数 Pageable,当查询中有多个参数的时候,建议 Pageable作为最后一个参数传入。
  • Sort排序对象,按照指定字段排序(升/降)。
  • Pageable 是 Spring 封装的分页实现类,需要传入页数、每页条数和排序规则。

使用示例:
1、编辑PersonDao,新增如下方法

	// 排序查询,返回list集合
	List<Person> findByNameContaining(String name, Sort sort);

	//分页查询, 查询计算元素总个数、总页数,数据多的情况下,代价是昂贵的
    Page<Person> findByNameContaining(String name ,Pageable pageable);
    //分页查询,返回的是一个片段,它只知道下一片段或者上一片段是否可用。
    Slice<Person> getByNameContaining(String name,Pageable pageable);

2、新增Controller 类Person4Controller

@RestController
@RequestMapping("/person4")
public class Person4Controller {

    @Autowired
    PersonDao personDao;
    
	//sort指排序方向,asc/desc
    @GetMapping("findByNameSort/{sort}/{name}")
    public List<Person> findByNameSort(@PathVariable String name, 
										@PathVariable String sort) {//desc/asc
		Sort sort = Sort.by(Sort.Direction.fromString(sort),"id");
        return personDao.findByNameContaining(name, sort);
    }

    @GetMapping("findByNamePage1/{page}/{size}/{sort}/{name}")
    public Page<Person> findByNamePage1(@PathVariable String name, 
										@PathVariable int page, //第几页(0:首页)
										@PathVariable int size, //每页条数
										@PathVariable String sort) {//排序方向asc、desc
		Sort sort = Sort.by(Sort.Direction.fromString(sort),"id");
		return personDao.findByNameContaining(name, PageRequest.of(page, size , sort);//先排序后分页
	}


    @GetMapping("findByNamePage2/{page}/{size}/{sort}/{name}")
    public Slice<Person> findByNamePage2(@PathVariable String name,
										 @PathVariable int page, @PathVariable int size,
										 @PathVariable String sort) {
		Sort sort = Sort.by(Sort.Direction.fromString(sort),"id");
		return personDao.getByNameContaining(name, PageRequest.of(page,size,sort);
    }
}

8、限制查询,返回指定条数

  • JPA限制查询 例如:返回第一条、返回前十条。

1、编辑PersonDao,新增如下方法

	//按照name查询并且,按照Id降序排序返回第一条
	Person findFirstByNameOrderByIdDesc(String name);
	//按照name查询并且,按照Id升序排序返回第一条
	Person findTopByNameOrderByIdAsc(String name);
	
	//模糊查询指定用户名称,按照id降序排序返回前10条记录
	List<Person> findFirst10ByNameLikeOrderByIdDesc(String name);  
	//模糊查询指定用户名称,按照id升序排序返回前10条记录
	List<Person> findTop10ByNameLikeOrderByIdAsc(String name);

2、新增Controller 类Person5Controller

@RestController
@RequestMapping("/person5")
public class Person5Controller {

	@Autowired
	PersonRepository personRepository;
	
	@GetMapping("findFirstByNameOrderByIdDesc/{name}")	
	public Person findFirstByNameOrderByIdDesc(@PathVariable String name) {
		return personRepository.findFirstByNameOrderByIdDesc(name);
	}
	
	@GetMapping("findFirst10ByNameLikeOrderByIdDesc/{name}")	
	public List<Person> findFirst10ByNameLikeOrderByIdDesc(@PathVariable String name) {
		return personRepository.findFirst10ByNameLikeOrderByIdDesc("%"+name+"%");
	}
	
	@GetMapping("findTopByNameOrderByIdAsc/{name}")	
	public Person findTopByNameOrderByIdAsc(@PathVariable String name) {
		return personRepository.findTopByNameOrderByIdAsc(name);
	}
	
	@GetMapping("findTop10ByNameLikeOrderByIdAsc/{name}")	
	public List<Person> findTop10ByNameLikeOrderByIdAsc(@PathVariable String name) {
		return personRepository.findTop10ByNameLikeOrderByIdAsc("%"+name+"%");
	}
}

9、SpringBoot 使用JPA多表查询

  • JPA定义了one-to-one、one-to-many、many-to-one、many-to-many 注解用来表示表与表之间的4种关系。

1、新建实体Dog

@Entity
@Data
public class Dog {
	@Id
    @GeneratedValue
    private Long id;
    private String name;
    private Long personId;  //personId属于外键字段,记录一方表的主键
}

2、编辑Person添加List dogs

//设置级联操作:
@OneToMany(mappedBy = "personId", cascade = CascadeType.ALL)
private List<Dog> dogs;
  • 通过设置cascade={options}可以设置级联操作的行为,其中options可以是以下组合:
    • CascadeType.MERGE 级联更新
    • CascadeType.PERSIST 级联保存
    • CascadeType.REFRESH 级联刷新
    • CascadeType.REMOVE 级联删除
    • CascadeType.ALL 级联上述4种操作

3、编辑PersonDao,新增如下方法

@Query("select p from Person p join p.dogs d where p.id=?1")
Person findPerson(@Param("id") Long id);

@Modifying
@Transactional(readOnly = false)
void deleteById(Long id);

4、编辑Controller 类Person5Controller,新增方法

	@GetMapping("findPerson/{id}")	
	public Person findPerson(@PathVariable Long id) {
		return personDao.findPerson(id);
	}
	@GetMapping("deletePerson/{id}")
	public void delete(@PathVariable Long id){
	    personRepository.deleteById(id);
	}

5、测试 按id获取用户信息方法findPerson、deletePerson
http://localhost:8080/person5/findPerson/2
http://localhost:8080/person5/deletePerson/2

(五)SpringBoot使用Thymeleaf 模板引擎(非重点)

Thymeleaf模板:

  • Thymeleaf模板是SpringBoot官方推荐的模板引擎,它是一个Java类库,是一个xml/xhtml/html5的模板引擎,属于View视图层技术。可以使用Thymeleaf完全替代JSP

1、入门实例

  • 1、增加Thymeleaf依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  • 2、修改application.yml增加Thymeleaf相关配置 (开启thymeleaf设置:禁用模板缓存 )
spring:   
  thymeleaf:   
    cache: false   
  • 3、编写Controller文件
@Controller
public class FirstThymeleafController {
    /**
     * 访问http://localhost:8080/first
     * 将数据message填充到templates/index.html
     * @param model
     * @return
     */
    @GetMapping("/first")
    public String indexPage(Model model) {
        String message = "Hello, Thymeleaf!";
        model.addAttribute("message", message);
        return "index";
    }
}
  • 4、编写模板文件(在resources/templates 下新建 index.html)

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"> 
<head>
    <meta charset="UTF-8">
    <title>首页title>
head>
<body>
	
	
    <h1 th:text="${message}">h1>
body>
html>
  • 5、运行访问地址 http://localhost:8080/first

2、常量文字读取(读取属性配置文件的内容)

  • 1、修改application.yml,增加国际化消息属性设置
    • 以下操作为:设置内容编码:UTF-8,读取配置文件名字:message_zh_CN。(简写方式是固定的,zh_CN代表是中文,en代表是英文)
spring:   
 thymeleaf:   
  cache: false   
 messages:
  encoding: UTF-8
  basename: message_zh_CN
  • 2、在resources下新建UTF-8编码的文件:message_zh_CN.properties
title=这是标题
message1=这是消息2
message2=这是消息2
  • 3、编写模板文件:在resources/templates 下编辑 index.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="#{title}">title>  
head>
<body>
    <h1 th:text="${message}">h1>
body>
html>
  • 4、访问运行地址http://localhost:8080/first

3、打印对象属性

  • 1、新建一个实体bean–> User,内容如下
@Data
public class User {
	private Integer id;
	private String name;
	private int age;
}
  • 2、新建一个Controller,内容如下
@Controller
public class SecondThymeleafController {

  @GetMapping("/second")
  public String indexPage(Model model) {
      String message = "Hello, Thymeleaf!";
      User u = new User();
      u.setId(1);
      u.setName("tc");
      u.setAge(18);
      
      Map<String,Object> map=new HashMap<>();
      map.put("src1","1.jpg");
      map.put("src2","2.jpg");
      
      model.addAttribute("message", message);
      model.addAttribute("user", u);
      model.addAttribute("src", map);
      
      return "index2";
  }
}

  • 3、在resources/templates 下,新增模板文件index2.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页title>
head>
<body>
	<h1 th:text="${message}">h1>
	
	<img th:src="${src.src1}"/>br>
	
	<img th:src="${src.src2}"/>br>
	
	<span th:text="${user.id}">span>
	
	<span th:text="${user.name}">span>
	
	<span th:text="${user.age}">span>
body>
html>
  • 4、测试:访问地址:http://localhost:8080/second

4、循环遍历集合

  • 1、新建一个Controller,内容如下:
@Controller
public class ThreeThymeleafController {

    @GetMapping("/three")
    public String indexPage(Model model) {
        List<User> list=new ArrayList<User>();

        User u1 = new User();
        u1.setId(1);
        u1.setName("me1");
        u1.setAge(18);
        list.add(u1);

        User u2 = new User();
        u2.setId(2);
        u2.setName("me2");
        u2.setAge(28);
        list.add(u2);

        User u3 = new User();
        u3.setId(3);
        u3.setName("me3");
        u3.setAge(88);
        list.add(u3);

        User u4 = new User();
        u4.setId(4);
        u4.setName("JAVA第一");
        u4.setAge(888);
        list.add(u4);

        model.addAttribute("userList", list);
        return "index3";
    }
}
  • 2、在resource/templates 下,新增模板文件index3.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div align="center">
    <table cellpadding="10px" cellspacing="0" border="1px solid">
        <thead>
        <tr>
            <th>idth>
            <th>nameth>
            <th>ageth>
            <th>iterStat.indexth>  
            <th>iterStat.countth>  
            <th>iterStat.sizeth> 
            <th>iterStat.currentth> 
            <th>iterStat.eventh>  
            <th>iterStat.oddth>   
            <th>iterStat.firstth>  
            <th>iterStat.lastth>  
        tr>
        <tr th:each="user,iterStat:${userList}">  
            <td th:text="${user.id}">td>
            <td th:text="${user.name}">td>
            <td th:text="${user.age}">td>
            
            <td th:text="${iterStat.index}">indextd>
            <td th:text="${iterStat.count}">counttd>
            <td th:text="${iterStat.size}">sizetd>
            <td th:text="${iterStat.current}">currenttd>  
            <td th:text="${iterStat.even}">eventd>  
            <td th:text="${iterStat.odd}">oddtd> 
            <td th:text="${iterStat.first}">firsttd>  
            <td th:text="${iterStat.last}">lasttd>  
        tr>

        thead>
    table>
div>
body>
html>
  • 3、访问地址:http://localhost:8080/three

5、赋值、字符串拼接

  • 1、新建一个Controller,内容如下:
@Controller
public class FourThymeleafController {
    @GetMapping("/four")
    public String indexPage(Model model) {
        model.addAttribute("userName", "优就业");
        model.addAttribute("href", "http://www.ujiuye.com");
        return "index4";
    }
}
  • 2、在resources/templates 下,新增模板文件index4.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页title>
head>
<body>
    
    <h1 th:text="${userName}">h1>

    
    <input type="text" name="names" th:value="${userName}"/>br>

    
    <span th:text="'欢迎来:'+${userName}+'学习!'">span>br>
    
body>
html>
  • 3、访问地址:http://localhost:8080/four

6、条件判断、选择语句

  • 1、新建一个Controller,内容如下:
@Controller
public class FiveThymeleafController {

    @GetMapping("/five")
    public String indexPage(Model model) {

        model.addAttribute("flag", "yes");
        model.addAttribute("menu", "admin");
        return "index5";
    }
}
  • 2、在resource/templates 下,新增模板文件index5.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div align="center">
    
    <h1 th:if="${flag=='yes'}" >111h1>

    
    <h1 th:unless="${flag=='no'}" >2222h1>
    
    <div th:switch="${menu}">
        <p th:case="'admin'">User is an administratorp>
        <p th:case="'manager'">User is a managerp>
    div>
div>
body>
html>

7、静态资源加载

1、新建静态资源文件:
SpringBoot的快速入门、热部署、参数处理、WebJars、属性配置、JPA操作数据库、Thymeleaf 模板引擎、JPA+Thymeleaf、RESTful风格、Swagger2构建API等_第15张图片
2、在html上引入静态资源文件:


<link rel="stylesheet" type="text/css" media="all"  href="/css/gtvg.css"  th:href="@{/css/gtvg.css}" />
<script src="/js/jquery1.42.min.js" th:src="@{/js/jquery1.42.min.js}">script>

8、fragment定义片段

  • 介绍:在html文件中,可以将多个地方都要出现的元素块用fragment包起来使用,抽象成模块,然后在需要的时候引用。
  • 定义fragment:所有的fragment可以写在一个文件里面,也可以单独存在
  • 在Springboot中,默认读取thymeleaf文件的路径是:src/main/resources/templates
  • fragment的引用:
    • th:insert:保留自己的主标签,保留th:fragment的主标签。
    • th:replace:不要自己的主标签,保留th:fragment的主标签。
    • th:include:保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)

示例

  • 1、 在resources/templates 下,新增模板文件footer.html
<body>
  <h1 th:fragment="copy">
        &copy; 1999-2018 Offcn.All Rights Reserved
    </h1>
</body>
  • 2、编写Controller
@Controller
public class SixThymeleafController {

    @GetMapping("/six")
    public String indexPage(Model model) {
        return "index6";
    }
}
  • 3、在resources/templates 下,新增视图文件index6.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页title>
head>
<body>
    
    <div th:insert="~{footer :: copy}">div>br>

    
    <div th:replace="~{footer :: copy}">div>br>

    
    <div th:include="~{footer :: copy}">div>
body>
html>
  • 4、访问地址http://localhost:8080/six 运行

9、内置对象使用

  • 常见内置工具对象:
    • #dates 与java.util.Date对象的方法对应,格式化、日期组件抽取等等
    • #numbers 格式化数字对象的工具方法
    • #strings 与java.lang.String对应的工具方法

示例:

  • 1、编写Controller
@Controller
public class SevenThymeleafController {

    @GetMapping("/seven")
    public String indexPage(Model model) {
        //日期时间
        Date date = new Date();
        //小数的金额
        double price=128.5678D;
        //长文本
        String str1="一二三四五六七八九十1234567890";
        //定义字符串
        String str2="JAVA--idea";

        model.addAttribute("date", date);
        model.addAttribute("price", price);
        model.addAttribute("str1", str1);
        model.addAttribute("str2", str2);

        return "index7";
    }
}
  • 2、resource/templates 下,新增模板文件index7.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    时间:<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}">2008</span></br>

    金额:<span th:text="'¥'+${#numbers.formatDecimal(price,1,2)}">10.00</span> </br>

    <!-- str1+...)一共显示5位,其中后三位固定显示"...",显示的位数少于3就报错! -->
    <p th:text="${#strings.abbreviate(str1,5)}">内容内容内容</p>

    <!-- 判断字符串是否为空 -->
    <span th:if="${!#strings.isEmpty(str2)}">字符串str2不为空</span></br>

    <!-- 截取字符串,指定长度 -->
    <span th:text="${#strings.substring(str2,0,4)}">字符串str2的值</span>

</body>
</html>
  • 3、运行访问地址 http://localhost:8080/seven

(六)JPA+Thymeleaf集成开发应用(非重点)

使用SpringBoot集成Jpa 、Thymeleaf实现一个web版的用户增删改查基本功能

示例:

  • 1、创建SpringBoot工程
    • 创建SpringBoot项目,项目名称:jpa_thymeleaf
    • 模块选择:Web、Thymeleaf 、JPA 、MySQL
  • 2、修改application.properties
#声明要连接的数据库地址
spring.datasource.url=jdbc:mysql://localhost:3306/jpadb?serverTimezone=GMT%2b8
#数据库的账号
spring.datasource.username=root
#数据库的密码
spring.datasource.password=root
#数据库的驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 自动创建、更新、验证数据库表结构
spring.jpa.hibernate.ddl-auto=update
# 打印sql语句
spring.jpa.show-sql=true
# thymeleaf设置:禁用模板缓存 
spring.thymeleaf.cache=false
  • 3、创建实体类User.java
@Data
@Entity
@Table(name = "tb_user")//设置数据库表名
public class User {
    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "name", nullable = true, length = 200)
    private String name;

    @Column(name = "age", nullable = true, length = 4)
    private Integer age;
}
  • 4、创建DAO接口 UserDao.java
public interface UserDao extends JpaRepository<User,Long> {
}
  • 5、创建Service接口 UserService.java
//用户数据操作业务接口
public interface UserService {
    //获取全部用户数据
    public List<User> getUserList();
    //新增用户数据
    public void createUser(User user);
    //获取指定id用户信息
    public User getUser(Long id);
    //更新指定id用户信息
    public void updateUser(Long id,User user);
    //删除指定id用户
    public void deleteUser(Long id);
}
  • 6、创建Service实现类 UserServiceImpl.java
@Service
@AllArgsConstructor(onConstructor_  ={@Autowired} )
public class UserServiceImpl implements UserService {

    UserDao userDao;

    @Override
    public List<User> getUserList() {
        return userDao.findAll();
    }

    @Override
    public void createUser(User user) {
        userDao.save(user);
    }

    @Override
    public User getUser(Long id) {
        User user = userDao.getOne(id);
//        User user1 = userDao.findById(id).get(); //等价findOne()
        return user;
    }

    @Override
    public void updateUser(Long id, User user) {
        user.setId(id);
        userDao.saveAndFlush(user);

    }

    @Override
    public void deleteUser(Long id) {
        userDao.deleteById(id);
    }

}
  • 7、创建UserController.java
@Controller
@RequestMapping("/manageruser")
@AllArgsConstructor(onConstructor_  ={@Autowired} )
public class UserController {

    UserService userService;

    /***
     * 获取全部用户信息
     * @return
     */
    @GetMapping("/getUserList")
    public String getUserList(Model model){
        List<User> list = userService.getUserList();
        model.addAttribute("page", list);
        return "user/list";   //转发到user/list模板
    }

    /***
     * 跳转到新增用户界面
     * @return
     */
    @RequestMapping("/toAdd")
    public String toadd(){
        return "user/userAdd";//跳转到userAdd.html
    }

    /***
     * 新增用户
     * @param user
     * @return
     */
    @PostMapping("/add")
    public String createUser(User user) {
        userService.createUser(user);
        return "redirect:/manageruser/getUserList";//重定向到getUserList
    }

    /***
     * 回显
     */
    @RequestMapping("/toEdit/{id}")
    public String toEdit(Model model,@PathVariable("id")Long id){
        User user = userService.getUser(id);
        model.addAttribute("user",user);
        return "user/userEdit"; //跳转到userEdit.html页面
    }
    /***
     * 修改后保存
     */
    @RequestMapping("/edit")
    public String edit(User user){
        userService.updateUser(user.getId(), user);
        return "redirect:/manageruser/getUserList";//获取列表数据并显示
    }

    /***
     * 删除指定id用户
     * @param id
     * @return
     */
    @GetMapping("/delete/{id}")
    public String deleteUser(@PathVariable("id") Long id) {
        userService.deleteUser(id);
        return "redirect:/manageruser/getUserList";
    }
}
  • 8、修改pom.xml引入bootstrap的 webJars
<dependency>
    <groupId>org.webjarsgroupId>
    <artifactId>bootstrapartifactId>
    <version>4.2.1version>
dependency>
  • 9、创建前端页面

(1)myfragment.html:

<h1 th:fragment="head" align="center">用户管理系统h1>
<h1 th:fragment="foot">
    © 1999-2018 Offcn.All Rights Reserved
h1>

(2)list.html:


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>userListtitle>
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" href='webjars/bootstrap/4.2.1/css/bootstrap.min.css'>
head>
<body class="container">
    <div th:insert="~{user/myfragment :: head}">div><br/>
    <h1>用户列表h1><br/><br/>
    <div class="with:80%">
        <div class="form-group">
            <div class="col-sm-2 control-label">
                <a href="toAdd" th:href="@{toAdd}" class="btn btn-info">adda>
            div>
        div>
        <table class="table table-hover">
            <thead>
            <tr>
                <th>#th>
                <th>Nameth>
                <th>Ageth>
                <th>Editth>
                <th>Deleteth>
            tr>
            thead>
            <tbody>
            <tr  th:each="user : ${page}">
                <th scope="row" th:text="${user.id}">1th>
                <td th:text="${user.name}">neotd>
                <td th:text="${user.age}">6td>
                <td><a th:href="@{'toEdit/'+${user.id}}">edita>td>
                <td><a th:href="@{'delete/'+${user.id}}">deletea>td>
            tr>
            tbody>
        table>
    div>
    <div th:include="~{user/myfragment :: foot}">div>
body>
html>

(3)userAdd.html


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>usertitle>
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" href='webjars/bootstrap/4.2.1/css/bootstrap.min.css'>
head>
<body class="container">
<div th:insert="~{user/myfragment :: head}">div>
<br/>
<h1>添加用户h1>
<br/><br/>
<div class="with:80%">
    <form class="form-horizontal"   th:action="@{add}"  method="post">
        <div class="form-group">
            <label for="name" class="col-sm-2 control-label">namelabel>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="name"  id="name" placeholder="name"/>
            div>
        div>

        <div class="form-group">
            <label for="age" class="col-sm-2 control-label">agelabel>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="age"  id="age" placeholder="age"/>
            div>
        div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <input type="submit" value="Submit" class="btn btn-info" />
                     
                <input type="reset" value="Reset" class="btn btn-info" />
            div>

        div>
    form>
div>
<div th:include="~{user/myfragment :: foot}">div>
body>
html>

(4)userEdit.html


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>usertitle>
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" href='webjars/bootstrap/4.2.1/css/bootstrap.min.css'>
head>
<body class="container">
<div th:insert="~{user/myfragment :: head}">div>
<br/>
<h1>修改用户h1>
<br/><br/>
<div class="with:80%">
    <form class="form-horizontal"   th:action="@{/manageruser/edit}" th:object="${user}"  method="post">
        <input type="hidden" name="id" th:value="*{id}" />
        <div class="form-group">
            <label for="name" class="col-sm-2 control-label">namelabel>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="name"  id="name" th:value="*{name}" placeholder="name"/>
            div>
        div>

        <div class="form-group">
            <label for="age" class="col-sm-2 control-label">agelabel>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="age"  id="age" th:value="*{age}" placeholder="age"/>
            div>
        div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <input type="submit" value="Submit" class="btn btn-info" />
                     
                <a href="/manageruser/" th:href="@{/manageruser/}" class="btn btn-info">Backa>
            div>

        div>
    form>
div>
<div th:include="~{user/myfragment :: foot}">div>
body>
html>

9、运行测试:http://localhost:8080/manageruser/getUserList(需要添加信息,列表才有显示)

(七)SpringBoot构建RESTful API

RESTful介绍

  • RESTful是一种软件架构风格,但也可以不按照这种风格规定
  • RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和delete增删查改)操作,分
  • 对应于4个HTTP方法(4个http动词):
    • GET用来获取资源,@GetMapping
    • POST用来新建资源(也可以用于更新资源),@PostMapping
    • PUT用来更新资源, @PutMapping
    • DELETE用来删除资源 @DeleteMapping

这样就统一了数据操作的接口,仅通过不同的HTTP方法,就可以完成对数据的所有增删查改工作

使用示例:

  • controller上示例:
@RestController
@Validated  //开启数据有效性校验,添加在类上即为验证方法,/// 添加在方法参数中即为验证参数对象。
public class UserController {


    @Autowired
    private UserService userService;

    //    @GetMapping("/getUser")
	//    @PutMapping
	//    @DeleteMapping
	//    @PostMapping
	//    @PatchMapping
    @RequestMapping("/getUser")
    public String getUser() {
        return userService.getUserName();
    }

    @GetMapping("/user/{id:[\\w_]+}")
    public String getUserById(@PathVariable String id){
        return "根据id查询用户:"+id;
    }

    @GetMapping("/user")
    public String getAllUser(){
        return "查询所有用户";
    }

    @DeleteMapping("/user/{id}")
    public String deleteById(@PathVariable String id){
        return "根据id删除:"+id;
    }

    @DeleteMapping("/user")
    public String deleteAll(){
        return "删除所有";
    }
    @PostMapping("/user")
    public User add(@RequestBody  User user){ //不加@RequestBody 就模拟表单传输
        return user;
    }
    @PutMapping("/user")
    public User update(@RequestBody  User user){
        return user;
    }

    @GetMapping("/demo123")
    public String user(@NotBlank(message = "id不能为空!") @RequestParam("userid") String id,
                       @NotBlank(message = "name不能为空!") @RequestParam("username") String name,
                       @Email(message = "email格式不正确!") String email){
        return id+"==》"+name+email;
    }
}

(八)SpringBoot使用Swagger2构建API文档

Swagger2介绍

  • 编写和维护接口文档是每个程序员的职责,前面我们已经写好的接口,现在需要提供一份文档,这样才能方便调用者使用。
  • 采用Swagger2这套自动化文档工具来生成文档,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。
  • 相关注解说明 详情引用:A点点圈圈A-swagger2 注解说明:
注解 作用
@Api() 用于类,表示标识这个类是swagger的资源
@ApiOperation() 用于方法,表示一个http请求的操作
@ApiParam() 用于方法,参数,字段说明,表示对参数的添加元数据(说明或是否必填等)
@ApiModel() 用于类,表示对类进行说明,用于参数用实体类接收
@ApiModelProperty() 用于方法,字段,表示对model属性的说明或者数据操作更改
@ApiIgnore() 用于类,方法,方法参数 ,表示这个方法或者类被忽略
@ApiImplicitParam() 用于方法 ,表示单独的请求参数
@ApiImplicitParams() 用于方法,包含多个 @ApiImplicitParam

使用示例:

  • 1、pom.xml中加入Swagger2的依赖
<dependency>
    <groupId>io.springfoxgroupId>
    <artifactId>springfox-swagger2artifactId>
    <version>2.9.2version>
dependency>
<dependency>
    <groupId>io.springfoxgroupId>
    <artifactId>springfox-swagger-uiartifactId>
    <version>2.9.2version>
dependency>
  • 2、创建Swagger2配置类
    • 第一种:Java的方式配置bean(@Configuration,创建方法使用@Bean注解)
    • 第二种:Xml的方式配置bean
@Configuration
@EnableSwagger2 //生成api文档
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //这里需要注意,需要指定那些需要生成api文档的controller。 com.example.jpademo.controller
                .apis(RequestHandlerSelectors.basePackage("com.example.jpademo.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("优乐选项目api文档")
                .description("项目组-001")
                .termsOfServiceUrl("http://www.ujiuye.com/")
                .contact(new Contact("作者:tcy","xxxx.com","[email protected]"))
                .version("version:1.0")
                .build();
    }
}
  • 3、修改Controller增加文档注释
@RestController
@Api(tags = "用户接口")//tags="说明该类的作用"
public class UserController {

    /**
     * 新增用户
     * @param user
     * @return
     */
    @ApiOperation(value="新增", notes="新增用户信息")/*value="说明方法的作用" notes="方法的备注说明"*/
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户实体对象", dataType = "User"),/*方法参数说明*/
            @ApiImplicitParam(name = "id", value = "用户id", dataType = "Integer")
    })
    @PostMapping("/user")
    public String createUser(User user,Integer id) {

        return "success-添加成功";
    }

    /***
     * 根据id删除用户
     * @param id
     * @return
     */
    @ApiOperation(value="删除", notes="根据用户id删除")/*value="说明方法的作用" notes="方法的备注说明"*/
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "Long")
    })
    @DeleteMapping("/user/{id}")
    public String deleteUser(@PathVariable("id") Long id) {
        return "success-删除成功";
    }

    /**
     * 更新用户信息
     * @return
     */
    @ApiOperation(value="更新", notes="更新用户信息")/*value="说明方法的作用" notes="方法的备注说明"*/
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "需要更新的用户实体", dataType = "User")
    })
    @PutMapping("/user")
    public String updateUser(User user) {
         return "success-修改成功";
    }
}
  • 4、重启应用,访问地址:http://localhost:8080/swagger-ui.html

(九)框架整合

1、SpringBoot整合MyBatis

  • 1.pom依赖

<dependency>
    <groupId>org.mybatis.spring.bootgroupId>
    <artifactId>mybatis-spring-boot-starterartifactId>
    <version>1.3.2version>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
dependency>

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>druid-spring-boot-starterartifactId>
    <version>1.1.10version>
dependency>

<dependency>
    <groupId>com.github.pagehelpergroupId>
    <artifactId>pagehelper-spring-boot-starterartifactId>
    <version>1.2.5version>
dependency>
  • 2.配置数据库信息(在application.yml中配置MySQL数据库的配置信息)
spring:
  datasource:
      name: datasource
      type: com.alibaba.druid.pool.DruidDataSource
      #druid相关配置
      druid:
        #基本属性
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/mybatisdb
?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8

        username: root
        password: root
        #监控统计拦截的filters
        filters: stat
        #配置初始化大小/最小/最大
        initial-size: 1
        min-idle: 1
        max-active: 20
        #获取连接等待超时时间
        max-wait: 60000
        #间隔多久进行一次检测,检测需要关闭的空闲连接
        time-between-eviction-runs-millis: 60000
        #一个连接在池中最小生存的时间
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 'x'
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
		# 打开PSCache,并指定每个连接上PSCache的大小。
		# oracle设为true,mysql设为false。分库分表较多推荐设置为false
        pool-prepared-statements: false
        max-pool-prepared-statement-per-connection-size: 20
        
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.offcn.pojo

pagehelper:
    helperDialect: mysql
    reasonable: true
    supportMethodsArguments: true
    params: count=countSql
  • -(1)创建mybatisdb数据库,并创建employee表
  • -(2)在resources下创建mapper目录,作为mapper映射文件的存储目录
  • -(3)创建com.offcn.pojo包,并创建Employee实体类
@Data
public class Employee {
    private Integer eid;
    private String ename;
}
  • 3.修改项目启动类
@SpringBootApplication
//在Springboot01Application上添加 @MapperScan("com.offcn.dao")注解,
//在com.offcn.dao包中扫描Dao接口。
@MapperScan("com.offcn.dao")
public class Springboot01Application {
    public static void main(String[] args) {
        SpringApplication.run(Springboot01Application.class, args);
    }
}
  • 4.创建Dao接口以及Mapper映射
  • 5.创建Service层接口及其实现类

2、SpringBoot整合单机redis

  • 1.pom依赖
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
<version>2.0.4.RELEASEversion>
dependency>
  • 2.资源文件中对redis进行配置
redis:
  host: 192.168.145.128
  port: 6379
  • 3.RedisTemplate的使用

3、SpringBoot整合MongoDB

  • 1.pom依赖
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-mongodbartifactId>
    <version>2.0.4.RELEASEversion>
dependency>
  • 2.MongoDB数据源配置
data:
  mongodb:
    # 账号密码admin:123456 链接路径端口s以及数据库 192.168.145.128:27017
    uri: mongodb://admin:[email protected]:27017/mydb
  • 3.定义一个简单的实体
  • 4.MongoRepository实现Dao操作
    • 定义一个接口,继承MongoRepository,这个接口默认封装了基本的CURD的功能。

你可能感兴趣的:(MySQL,Java框架)