搭建springboot工程
作者:mmseoamin日期:2023-12-14

1. springboot介绍

2.搭建springboot环境

2.1 使用maven项目

在pox.xml文件中加入parent


        org.springframework.boot
        spring-boot-starter-parent
        2.6.4
    

在pom.xml文件中加入依赖web

 
        
            org.springframework.boot
            spring-boot-starter-web
        
    

创建Controller

@RestController
public class IndexController {
    @GetMapping("/index")
    public String index(){
        return "helleo springboot1";
    }
}

创建启动服务器的主类

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

2.2 使用Spring initlalizr 官网

创建module,选择spring initlalizr创建,通过https://start.spring.io创建。

搭建springboot工程,在这里插入图片描述,第1张

搭建springboot工程,在这里插入图片描述,第2张

2.3 使用Spring initlalizr阿里云

搭建springboot工程,在这里插入图片描述,第3张

2.4 访问https://start.spring.io

搭建springboot工程,在这里插入图片描述,第4张

下载一个压缩包,解压后通过idea打开,就是一个springboot 工程。

3. springboot parent和starter

所有springboot项目要继承的项目

在其中, 依赖了一个spring-boot-dependencies,在里面规范了使用的各第三方依赖的版本号。

搭建springboot工程,在这里插入图片描述,第5张

4.启动类

主启动类的位置

搭建springboot工程,在这里插入图片描述,第6张

5.springboot 支持的三种服务器

内置tomcat默认的处理器

jetty: 更轻量级的容器

pom.xml文件中配置 的

		
            org.springframework.boot
            spring-boot-starter-web
            
            
                
                    org.springframework.boot
                    spring-boot-starter-tomcat
                
            
        
        
        
            org.springframework.boot
            spring-boot-starter-jetty
        

undertow:

		
            org.springframework.boot
            spring-boot-starter-web
            
            
                
                    org.springframework.boot
                    spring-boot-starter-tomcat
                
            
        
        
        
            org.springframework.boot
            spring-boot-starter-undertow
        

6. springboot配置文件

创建springboot工程时会自动创建一个application.properties文件。

还可以支持application.yml 和application.yaml格式的文件。

主要应用的是application.yml格式的文件。

如果没有出自动提示,解决方式如下:

搭建springboot工程,在这里插入图片描述,第7张

7. 以jar包的方式运行

1.打包的处理

可以 mvn package

也可以使用idea中maven生命周期package,双击

搭建springboot工程,在这里插入图片描述,第8张

打包成功,在工程的target目录下找到jar包。进入target目录,运行java -jar 文件名.jar

8.springboot整合swagger3

步骤1:加入依赖

        
        
            io.springfox
            springfox-boot-starter
            3.0.0
        

步骤2:编写swagger的配置类

package com.liqun.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
 * @ProjectName: springboot
 * @Package: com.liqun.config
 * @ClassName: Swagger3Config
 * @Description: java类作用描述
 * @Author: 滨海之君
 * @CreateDate: 2023/5/29 23:00
 */
@Configuration
public class Swagger3Config {
    @Bean
    public Docket apiConfig(){
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .select()
                //设置通过什么方式定位到需要生成文档的接口
                //定位了方法上的ApiOperation
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("springboot-swagger项目")
                .description("项目描述信息")
                .contact(new Contact("滨海之君","http://www.xx.com","binhaizhijun@163.com"))
                .version("1.0")
                .build();
    }
}

步骤3:

要在application.yml文件中配置,避免程序报错:

org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

spring.mvc.pathmatch.matching-strategy=ant_path_matcher

步骤4:

在主启动类上添加@EnableOpenApi注解 ,如果是swagger2,使用@EnableSwagger2

步骤5:

在Controller类上添加 注解:@Api(tags = {"对当前类的说明"})

步骤6:

在Controller方法上添加注解:@ApiOperation(value = "对方法的说明和用途")

步骤7:

在Controller方法上,为方法的参数说明:

    @GetMapping("/{id}")
    @ApiOperation("按给定id来查询学生信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "id",value = "学生id",required = true,
            paramType = "path",
            dataType = "Integer",dataTypeClass=Integer.class)
    )
    public Object selectById(@PathVariable int id){
        return new Student(id,"王某","男",23);
    }

步骤8:

在Controller方法参数中,加入说明

    @DeleteMapping("/{id}")
    @ApiOperation("按给定的id来删除学生信息")
     public Object deleteById(@ApiParam(name = "id",value = "学生id") @PathVariable int id){
        return "success";
     }

步骤9:

在实体类上加入参数说明:

@ApiModel(value = "学生对象",description = "学生对象,用来对应数据库表student")
public class Student {
    @ApiModelProperty(value = "学生id",required = true,example = "1001")
    private int id ;
    @ApiModelProperty(value = "学生姓名",required = true,example = "张三")
    private String name;
    @ApiModelProperty(value = "学生性别",required = true,example = "男")
    private String gender;
    @ApiModelProperty(value = "学生年龄",required = false,example = "12")
    private int age;
}

步骤10:测试swagger

访问地址:http://localhost:8080/swagger-ui/index.html

知识点

restful风格
学生管理
/student    查询  get
/student    新增  post
/student    更新  put
/student/1   删除 delete
/student/1   根据id查询  get

9. 设置springboot自动重启

9.1 springboot启动banner修改

在yml文件中配置:

spring:
  banner:
    location: banner.txt

resourses根路径下存放 banner.txt。

9.2 设置自动重启

步骤1:

在pom.xml文件中加入相关依赖

        
            org.springframework.boot
            spring-boot-devtools
        

步骤2:

勾选idea中的

搭建springboot工程,在这里插入图片描述,第9张

步骤3:

按住ctrl+shift+alt+/ 弹出菜单,选择Registry

搭建springboot工程,![在这里插入图片描述](https://img-blog.csdnimg.cn/990625a62ef8411a8d5ce4e3f9caba1a.png,第10张

勾选搭建springboot工程,在这里插入图片描述,第11张

步骤4:

  • 重新启动服务器
  • 修改源文件
  • 切换到浏览器,查看效果
  • 再切换会idea,看控制台,已经自动重启

    9.3 自动重启设置原理

    Springboot提供的重启技术,通过两个类的加载器来完成。ClassLoader

    不会更改的类(来自第三方的jar包)被夹在到BaseClassLoader中,

    会更改的类被夹在到RestartClassLoader

    9.4 排除自动重启资源

    有一些资源,在更改是不一定需要触发自动重启。比如thymeleaf,

    配置排除的目录

    spring:
      devtools:
        restart:
          exclude: static/**,public/**,templates/**
    

    10. springboot配置文件位置

    springboot启动是会自动查找和加载application.properties和application.yml或者application.yaml。

    从一下位置

    fileL./config/

    file:./

    classpath:/config/

    classpath:./

    优先级从上到下。

    如果文件没那个不是默认名,需要通过 --spring.config.name=文件名(不要写扩展名) 进行设置搭建springboot工程,在这里插入图片描述,第12张

    或者(文件已经生成jar)

    java -jar 包名.jar --spring.config.name=文件名(不要写扩展名)

    11. yaml文件

    11.1 yaml文件的语法

    • yaml以数据为中心,比properties和xml更适合做配置文件
    • 和properties文件相比,更简洁。
    • 和xml文件相比,少了结构化代码,数据更直接。
    • 以空格的缩进程度来控制层级关系。
    • 大小写敏感。
    • 支持字面值、对象、数组数据结构,也支持复合结构。
    • 数据和前缀属性中间要有空格。
    • 字符串可以不加引号,如果需要处理特殊字符,需要使用双引号。
    • 使用集合、数组的时候,需要使用“-”,后面有空格。

      11.2 测试基本数据类型

      name: 张三
      age: 12
      money: 123.45
      birth: 1990/01/12
      

      11.3 将yml封装到实体类中

      pom.xml:

              
                  org.springframework.boot
                  spring-boot-configuration-processor
              
      

      yaml

      com:
        liqun:
          model:
            user:
              name: 张三
              age: 23
              gender: 男
              money: 234.45
              birth: 1990/01/12
      

      实体类:

      @Data
      @Component
      @ConfigurationProperties(prefix = "com.liqun.model.user")
      public class User {
          private String name;
          private int age;
          private String gender;
          private double money;
          private Date birth;
      }
      

      Controller中引入实体类:

      @RestController
      @RequestMapping("/user")
      public class UserController {
          @Resource
          private User user;
          @GetMapping("/userObj")
          public User user(){
              return user;
          }
      }
      

      11.4 将数据封装到Environment对象

      通过Environment对象的getProperties方法,获取yml文件中的数据

      com:
        liqun:
          model:
            user:
              name: 张三
              age: 23
              gender: 男
              money: 234.45
              birth: 2023/01/12
      projectName: springboot
      
          @Resource
          private Environment env;
          @GetMapping("env")
          public Object ev(){
              System.out.println(env.getProperty("projectName")); //springboot
              System.out.println(env.getProperty("com.liqun.model.user.name")); //张三
              return "sucess";
          }
      

      11.5.1 List类型

      likes:
        - 打球
        - 游泳
        - 游戏
      

      11.5.2 Set类型

      set: [xxx,yyy,zzz]
      

      11.5.3 Map类型

      map:
        k1: v1
        k2: v2
      map1: {k1: v1,k2: v2,k3: v3}
      

      11.5.4 集合封装对象类型

              stuList:
                - {name: 张三,age: 22}
                - {name: 李四,age: 30}
              stuList2:
                - name: 王五
                  age: 33
                - name: 高小红
                  age: 32
      

      11.5.5 @ConfigurationProperties注解

      查看自动配置,搭建springboot工程,在这里插入图片描述,第13张

      redis的配置

      搭建springboot工程,在这里插入图片描述,第14张

      @ConfigurationProperties(prefix = "spring.redis")
      

      11.6 yaml 松弛绑定

      springboot使用一些宽松的规则将Environment属性绑定到@ConfigurationProperties bean。因此Environment属性名和bean属性名称之间不需要完全匹配。例如: context-path绑定到contextPath, 大写的PORT 绑定到小写的port

      对于userName属性,下面四种方式,都可以绑定

      com:
        liqun:
          model:
            user:
              # user-name: 张三
              # userName: 高小红
              # user_name: 牟心智
              USER_NAME: 王五
      
      属性用法
      user-name烤肉串风格,推荐用于 .properties和.yml文件
      userName标准的驼峰式语法
      user_name下划线表示法,也是在.properties和.yml文件使用的另一种格式
      USER_NAME大写格式,在使用系统环境变量时推荐使用

      11.7 多环境配置

      spring profiles允许用户根据配置文件(dev,test,prod)来注册bean。因此,当应用程序开发运行时,只有某些bean可以加载。

      而生产环境中,某些其他bean可以加载。

      命名规范:application-{profiles}.yml 例如:application-dev.yml

      案例: 在开发环境中,使用8080端口,在生产环境中,使用8081端口

      分别开发两个不同的yml文件:

      开发环境中的文件: application-dev.yml

      方法1:

      server:
        port: 8080
      

      生产环境中的文件: application-prod.yml

      server:
        port: 8081
      

      全局配置文件中,指定哪个是被激活的:

      spring:
        profiles:
          active: dev
      

      方法2:

      在启动时通过参数指定,优先级大于yml配置文件

      通过启动参数:-Dspring.profiles.active=prod 指定。

      方法3:

      将项目使用maven打成jar报,在终端运行命令行:

      java -jar --spring.profiles.active=prod 指定。

      11.8 使用@Profile

      案例:现有一个接口,来实现支付处理,一个实现类,来模拟是使用支付宝支付,一个实现类来模拟使用微信支付,支付的方式跟着开发环境的不同,选择不同的处理方式。

      搭建springboot工程,在这里插入图片描述,第15张

      启动不同的换进,会调用不同的接口。

      11.9 yaml文件使用el配置

      搭建springboot工程,在这里插入图片描述,第16张

      11.10 随机值的引用

      搭建springboot工程,在这里插入图片描述,第17张

      12. springboot整个junit

      在pom.xml文件中放入junit相关依赖

      		
                  org.springframework.boot
                  spring-boot-starter-test
                  test
              
      

      测试类

      要写在test>java下面

      @SpringBootTest(classes = AppServer.class) //括号里指明引导类的位置

      @SpringBootTest
      public class AppTest {
          @Resource
          private UserService service;
          @Test
          void contextLoads() {
              List list = service.list();
              list.forEach(System.out::println);
          }
      }
      

      心得:

      1.工程中的包一定不要从其他工程复制,太坑了。

      2.test 下面的包结构 一定要和main 下面的一致,不一致的话,下面提到的尽管指定了引导类的位置,虽然也能启动,但是测试类在独立的IOC容器, 使用不了Service等组件注入。

      3.测试类@SpringBootTest(classes = AppServer.class) 尽量带上括号里面的,这样指定程序的主启动类,这样无论测试类放在那个包下,也不会出问题了。

      13. springboot整合mybatis

      pom.xml文件配置:
      
      
      
          
              springboot2
              com.liqun
              1.0-SNAPSHOT
          
          4.0.0
          springboot_mybatis2
          
              
                  org.springframework.boot
                  spring-boot-starter-web
              
              
                  org.mybatis.spring.boot
                  mybatis-spring-boot-starter
                  2.2.2
              
              
                  org.springframework.boot
                  spring-boot-devtools
                  runtime
                  true
              
              
                  mysql
                  mysql-connector-java
                  runtime
              
              
                  org.projectlombok
                  lombok
                  true
              
              
                  org.springframework.boot
                  spring-boot-starter-test
                  test
              
              
              
                  io.springfox
                  springfox-boot-starter
                  3.0.0
              
          
          
              
                  
                      org.springframework.boot
                      spring-boot-maven-plugin
                      
                          
                              
                                  org.projectlombok
                                  lombok
                              
                          
                      
                  
              
          
      
      

      配置application.yml文件:

      spring:
        mvc:
          pathmatch:
            matching-strategy: ant_path_matcher # 解决swagger3报错的
        # 配置数据库连接相关属性   
        datasource:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
          username: root
          password: 123456
      

      启动类,自动扫描Mapper

      @SpringBootApplication
      @MapperScan(basePackages = "com.liqun.mapper") //启动类扫描Mapper
      public class SpringBootMybatisApp {
          public static void main(String[] args) {
              SpringApplication.run(SpringBootMybatisApp.class,args);
          }
      }
      

      在启动类上添加@MapperScan(basePackages = "com.liqun.mapper"), 就不用再每个mapper接口上添加@mapper 注解了;如果不加这个@MapperScan, 则需要每个mapper接口都需要添加@mapper,有时候,很容易遗忘的。

      当然,也可以配置不同包路径下的扫描,例如:

      @MapperScan(basePackages = {"com.liqun.mapper","com.liqun.abc"})
      

      不要用@ComponentScan(basePackages = {"com.liqun.mapper","com.liqun.abc","com.liqun.*"}) 这种写法来代替@MapperScan(basePackages = {"com.liqun.mapper","com.liqun.abc"}) , 因为@ComponentScan 只会根据指定的扫描范围来扫描容器中包含@Controller 、@Service、@Mapper等组件。如果mapper接口中没有添加@Mapper,那就老老实实的使用@MapperScan(basePackages = {"com.liqun.mapper","com.liqun.abc"}).

      配置mybatis日志打印

      mybatis:
        configuration:
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      

      分页处理:

      pom.xml文件中添加分页插件

      
              
                  com.github.pagehelper
                  pagehelper-spring-boot-starter
                  1.4.1
              
      

      分页处理代码:

          @ApiOperation("分页显示学生信息")
          @GetMapping("/{start}/{size}")
          public Object listByPage(@PathVariable Integer start,@PathVariable Integer size){
              PageHelper.startPage(start,size);
      //        service.selectByPage(start,size);
              List list = service.selectList();
              PageInfo pageInfo = new PageInfo<>(list);
              return pageInfo;
          }
      

      日志打印:

      mybatis:
        configuration:
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      

      mapper.xml文件的位置配置:

      如果mapper.xml文件和mapper.java接口是同一个路径,不需要配置。

      如果mapper.xml文件和mapper.java接口不在同一个路径,需要做如下配置

      mybatis:
        mapper-locations: classpath:mapper/*.xml
      

      如果使用xml配置文件,指定类的别名:

      mybatis:
        type-aliases-package: com.liqun.entity # 设置别名
      

      14. mybatis-plus

      官网:https://baomidou.com

      14.1 整合mybatis

      14.1.1 创建一个mybatis项目

      pom.xml

      
      
          
              mybatis
              com.liqun
              1.0-SNAPSHOT
          
          4.0.0
          mybatis_1
         
          
              
                  org.projectlombok
                  lombok
                  1.18.22
              
              
                  org.mybatis
                  mybatis
                  3.5.9
              
              
                  mysql
                  mysql-connector-java
                  8.0.28
              
              
                  junit
                  junit
                  4.13.2
              
          
          
              
                  
                      src/main/java
                      
                          **/*.properties
                          **/*.xml
                      
                      false
                  
              
          
      
      

      mybaits配置文件:

      
      
      
           
          
              
                  
                  
                      
                      
                      
                      
                  
              
          
          
          
              
          
      
      

      数据库配置文件:db.properites

      jdbc.driver=com.mysql.cj.jdbc.Driver
      jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
      jdbc.username=root
      jdbc.password=123456
      

      编写测试类:

      public class TestMybatis {
          @Test
          public void test() throws IOException {
              SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
              SqlSessionFactory factory = builder.build(Resources.getResourceAsReader("SqlMapConfig.xml"));
              SqlSession sqlSession = factory.openSession();
              StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
              List list = mapper.selectList();
              list.forEach(System.out::println);
              sqlSession.close();
          }
      }
      

      参考Mybatis_学习笔记

      14.1.2 编写日志文件

      log4j.rootLogger = debug,stdout
      ### 输出信息到控制抬 ###
      log4j.appender.stdout = org.apache.log4j.ConsoleAppender
      log4j.appender.stdout.Target = System.out
      log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
      log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
      

      配置文件学习:

      ### 设置###
      log4j.rootLogger = DEBUG,stdout,D,E,datasource
      #%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL
      #%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},SSS为毫秒数(也可以写为SS,只不过SSS如果不足三位会补0),输出类似:2011-10-18 22:10:28,021
      #%r: 输出自应用启动到输出该日志耗费的毫秒数
      #%t: 输出产生日志的线程名称
      #%l: 输出日志事件的位置,相当于%c.%M(%F:L)的组合,包括类全名、方法、文件名以及在代码中行数。例如:cn.xm.test.PlainTest.main(PlanTest.java:12)
      #%c: 输出日志信息所属的类目,通常就是所在类的全名。可写为%c{num},表示取完整类名的层数,从后向前取,比如%c{2}取 "cn.qlq.exam"类为"qlq.exam"。
      #%M: 输出产生日志信息的方法名%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中
      #%%: 输出一个"%"字符
      #%F: 输出日志消息产生时所在的文件名称
      #%L: 输出代码中的行号
      #%m: 输出代码中指定的消息,产生的日志具体信息
      #%n: 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行
      ### 输出信息到控制抬 ###
      log4j.appender.stdout = org.apache.log4j.ConsoleAppender
      log4j.appender.stdout.Target = System.out
      log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
      log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
      ### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
      log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
      log4j.appender.D.File = E://logs/log.log
      log4j.appender.D.Append = true
      log4j.appender.D.Threshold = DEBUG 
      log4j.appender.D.layout = org.apache.log4j.PatternLayout
      log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
      ### 输出ERROR 级别以上的日志到=E://logs/error.log ###
      log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
      log4j.appender.E.File =E://logs/error.log 
      log4j.appender.E.Append = true
      log4j.appender.E.Threshold = ERROR 
      log4j.appender.E.layout = org.apache.log4j.PatternLayout
      log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
      #下面是配置将日志信息插入数据库,
      #配置输出目标为数据库(假如要将日志在控制台输出,配置为log4j.appender. stdout =org.apache.log4j.ConsoleAppender;
      # 将日志写入文件,配置为log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
      #这样的配置在许多地方都要有,需要可查有关资料),当然你也可以自己扩展org.apache.log4j.jdbc.JDBCAppender这个类,
      # 只需要在这里配置就可以了例如我们配置我自己扩展的MyJDBCAppender,配置为#log4j.appender.db=com.name.commons.MyJDBCAppender
      log4j.appender.datasource=org.apache.log4j.jdbc.JDBCAppender
      log4j.appender.datasource.layout=org.apache.log4j.PatternLayout
      log4j.appender.datasource.driver=com.mysql.cj.jdbc.Driver
      #定义什么级别的错误将写入到数据库中
      log4j.appender.datasource.Threshold = DEBUG 
      log4j.appender.datasource.BufferSize=1
      #设置缓存大小,就是当有1条日志信息是才忘数据库插一次,我设置的数据库名和表名均为user
      log4j.appender.datasource.URL=jdbc\:mysql\://localhost\:3306/logDB?characterEncoding\=UTF8&zeroDateTimeBehavior\=convertToNull&serverTimezone=UTC
      log4j.appender.datasource.user=root
      log4j.appender.datasource.password=123456
      log4j.appender.datasource.sql=insert into logmsg (class,method,create_time,log_level,log_line,msg) values ('%C','%M','%d{yyyy-MM-dd HH:mm:ss}','%p','%l','%m')
      

      14.1.3 加入mybatis-plus

      pom.xml文件修改

      
      
          
              mybatis
              com.liqun
              1.0-SNAPSHOT
          
          4.0.0
          mybatis_1
         
          
              
                  com.baomidou
                  mybatis-plus
                  3.5.1
              
              
                  org.springframework
                  spring-core
                  5.3.15
              
              
                  org.projectlombok
                  lombok
                  1.18.22
              
              
              
                  mysql
                  mysql-connector-java
                  8.0.28
              
              
                  junit
                  junit
                  4.13.2
              
              
                  org.slf4j
                  slf4j-log4j12
                  2.0.0-alpha7
              
          
          
              
                  
                      src/main/java
                      
                          **/*.properties
                          **/*.xml
                      
                      false
                  
              
          
      
      

      修改Mapper.java文件,继承BaseMapper<实体类》

      public interface StudentMapper extends BaseMapper {
      //    List selectList();
      }
      

      修改测试类,将SqlSessionFactoryBuilder对象创建MybatisSqlSessionFactoryBuilder类的对象。

          @Test
          public void test() throws IOException {
              SqlSessionFactoryBuilder builder = new MybatisSqlSessionFactoryBuilder();
              SqlSessionFactory factory = builder.build(Resources.getResourceAsReader("SqlMapConfig.xml"));
              SqlSession sqlSession = factory.openSession();
              StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
              Student student = new Student(100, "高淑红", 32, "女");
              int insert = mapper.insert(student);
              sqlSession.commit();
              System.out.println(insert);
              List list = mapper.selectList(null);
              list.forEach(System.out::println);
              sqlSession.close();
          }
      

      14.2 mybatis整合spring

      **步骤1 :**在pom.xml文件中添加相关依赖

      
      
          
              mybatis
              com.liqun
              1.0-SNAPSHOT
          
          4.0.0
          mybatis_spring
          
              
                  com.baomidou
                  mybatis-plus
                  3.5.1
              
              
                  org.springframework
                  spring-webmvc
                  5.3.15
              
              
                  org.springframework
                  spring-jdbc
                  5.3.15
              
              
                  org.springframework
                  spring-test
                  5.3.15
              
              
                  org.projectlombok
                  lombok
                  1.18.22
              
              
                  com.alibaba
                  druid
                  1.2.8
              
              
                  mysql
                  mysql-connector-java
                  8.0.28
              
              
                  junit
                  junit
                  4.13.2
              
              
                  org.slf4j
                  slf4j-log4j12
                  2.0.0-alpha7
              
          
          
              
                  
                      src/main/java
                      
                          **/*.properties
                          **/*.xml
                      
                      false
                  
              
          
      
      

      步骤2: 配置log4j.properties 和db.properties

      log4j.rootLogger = debug,stdout
      ### 输出信息到控制抬 ###
      log4j.appender.stdout = org.apache.log4j.ConsoleAppender
      log4j.appender.stdout.Target = System.out
      log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
      log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
      
      jdbc.driver=com.mysql.cj.jdbc.Driver
      jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
      jdbc.username=root
      jdbc.password=123456
      

      步骤3: 编写applicationContext.xml

      
      
          
          
          
              
              
              
              <--驱动类的名字不需要配置,会根据url自动改的去加载,会知道使用的是哪种数据库-->
          
          
          
              
          
          
          
              
          
      
      

      步骤4: 编写实体类

      @Data
      public class Student {
          private Integer id;
          private String StudentName;
          private String gender;
          private Integer age;
      }
      

      步骤5: 编写mapper接口

      public interface StudentMapper extends BaseMapper {
      }
      

      步骤6: 编写测试程序:

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration("classpath:applicationContext.xml")
      public class TestSprintMP {
          @Resource
          private StudentMapper mapper;
          @Test
          public void testList(){
              List students = mapper.selectList(null);
              students.forEach(System.out::println);
          }
      }
      

      14.3 mybatis-plus整合springboot

      pom.xml文件

      
      
         
          
              org.springframework.boot
              spring-boot-starter-parent
              2.6.4
          
          4.0.0
          springboot_mybatisplus
          
              
                  org.springframework.boot
                  spring-boot-starter-web
              
              
                  com.baomidou
                  mybatis-plus-boot-starter
                  3.5.1
              
              
                  mysql
                  mysql-connector-java
                  runtime
              
              
                  org.springframework.boot
                  spring-boot-starter-test
              
              
                  org.projectlombok
                  lombok
                  true
              
          
          
              
                  
                      org.springframework.boot
                      spring-boot-maven-plugin
                      
                          
                              
                                  org.projectlombok
                                  lombok
                              
                          
                      
                  
              
          
      
      

      配置application.yml

      spring:
        datasource:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
          username: root
          password: 123456
      

      实体类

       @Data
      public class Student {
           private Integer id;
           private String studentName;
           private Integer age;
           private String gender;
      }
      

      mapper接口

      public interface StudentMapper extends BaseMapper {
      }
      

      启动类

      @SpringBootApplication
      @MapperScan(basePackages = {"com.liqun.mapper"})
      public class MPServer {
          public static void main(String[] args) {
              SpringApplication.run(MPServer.class,args);
          }
      }
      

      测试类

      @SpringBootTest(classes = MPServer.class )
      public class MPtest {
          @Resource
          private StudentMapper mapper;
          @Test
          public void testMapper(){
              List students = mapper.selectList(null);
              students.forEach(System.out::println);
          }
      }
      

      14.4 详解BaseMapper

      insert
      deleteById
      deleteById
      deleteByMap
      delete
      deleteBatchIds
      updateById
      update
      selectById
      selectBatchIds
      selectByMap
      selectOne
      exists
      selectCount
      selectList
      selectMaps
      selectObjs
      selectPage
      selectMapsPage
      

      14.4.1 插入数据

      配置了mybatis-plus的日志打印

      mybatis-plus:
        configuration:
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      

      新增的操作:

      创建一个实体类对象

      使用@TableId(type=IdType.AUTO)指定主键的生成策略

       @Data
       @AllArgsConstructor
       @NoArgsConstructor
       @Accessors(chain = true)  //链式
       @TableName("student")
      public class Student {
           @TableId(type = IdType.AUTO)
           private Integer id;
           private String studentName;
           private Integer age;
           private String gender;
      }
      

      调用Mapper的insert方法,执行保存。

      14.4.2 @TableField注解

      用法:

      1.处理对象的属性和表字段名不匹配。

      2.对象的属性在表中不存在。

      3.隐藏对象属性在表中的查询。

      public class Student {
           @TableId(type = IdType.AUTO)
           private Integer id;
           @TableField(value = "name") //荡子算名和属性名不匹配时配置
           private String studentName;
           @TableField(select = false) //这个字段查询不返回值
           private Integer age;
           @TableField(exist = false) //表明这个字段在数据库表中不存在
           private String gender;
      }
      

      14.4.3 删除处理

      14.4.3.1 按指定id删除
          @Test
          void deleTest(){
              Student student = new Student();
              student.setId(100000);
              int i = mapper.deleteById(student);
              System.out.println("i==="+i);
          }
      
      14.4.3.2 按给定的Map条件删除
          @Test
          void deleteTest(){
              HashMap map = new HashMap<>();
              map.put("student_name","木木");
              int i = mapper.deleteByMap(map);
              System.out.println("i==="+i);
          }
      
      14.4.3.3 批量删除给定id数据
          @Test
          void deleBacthIds(){
              List ids =  Arrays.asList(100,1001);
              int i = mapper.deleteBatchIds(ids);
              System.out.println("i==="+i);
          }
      
      14.4.3.4 逻辑删除处理

      在application.yml文件中做配置

      mybatis-plus:
        global-config:
          db-config:
            logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
            logic-delete-value: 1 # 逻辑已删除值(默认为 1)
            logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
      

      修改数据库表结构,增加一个字段deleted ,默认值是0;

      在3.0.0版本之前,需要加入@TableLogic注解

          @TableLogic
          private Integer deleted;
      
      14.4.3.5 使用条件构造器删除
          @Test
          void deleteWQ2(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.eq("gender","男")
                      .like("student_name","顾");
              mapper.delete(wrapper);
          }
          @Test
          void deleteQW(){
              Student student = new Student();
              student.setStudentName("高小红").setGender("男");
              QueryWrapper wrapper = new QueryWrapper<>(student);
              mapper.delete(wrapper);
          }
          //使用Lambda方式
          @Test
          void delete2(){
              LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
              wrapper.like(Student::getStudentName,"高")
                      .eq(Student::getAge,32);
              mapper.delete(wrapper);
          }
      	//判定booleann类型的值,必须满女足给定的条件
          @Test
          void delete3(){
              Student student = new Student();
              student.setStudentName("高").setGender("nv");
              QueryWrapper wrapper = new QueryWrapper<>();
      //        wrapper.eq(!StringUtils.isNullOrEmpty(student.getGender()),"gender",student.getGender())
      //                .like(!StringUtils.isNullOrEmpty(student.getStudentName()),"student_name",student.getStudentName());
              LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
              lambdaQueryWrapper.like(!StringUtils.isNullOrEmpty(student.getStudentName()),Student::getStudentName,student.getStudentName());
              wrapper.eq("gender","男")
                      .like("student_name","高");
              mapper.delete(lambdaQueryWrapper);
          }
      

      14.4.4 修改处理

       @Test
          void updateById(){
              Student student = new Student();
              student.setAge(30).setGender("女").setId(4);
              mapper.updateById(student);
          }
          @Test
          void update1(){
              Student student = new Student();
      //        student.setGender("女").setAge(35);
              student.setAge(32).setGender("女");
              UpdateWrapper wrapper = new UpdateWrapper<>();
              wrapper.likeRight("student_name","高");
              mapper.update(student,wrapper);
          }
          @Test
          void update2(){
              UpdateWrapper wrapper = new UpdateWrapper<>();
              wrapper.set("gender","女").set("age","31")
                      .likeRight("student_name","高");
      //        mapper.update(new Student(),wrapper); //new Student() 可以写成null
              mapper.update(null,wrapper);
          }
          @Test
          void update3(){
              LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
              wrapper.set(Student::getGender,"女").set(Student::getAge,"25")
                      .likeRight(Student::getStudentName,"顾");
      //        mapper.update(new Student(),wrapper); //new Student() 可以写成null
              mapper.update(null,wrapper);
          }
      

      14.4.5 查询处理

      	 @Test
      	 //主键查询
          void selectById(){
              Student student = mapper.selectById(4);
              System.out.println(student);
          }
          @Test
          void selectByIds(){
              List students = mapper.selectBatchIds(Arrays.asList(4, 5));
              students.forEach(System.out::println);
          }
          @Test
          void selectByMap(){
              Map map = new HashMap<>();
              map.put("student_name","牟心智");
              List students = mapper.selectByMap(map);
              students.forEach(System.out::println);
          }
          @Test
          void selectOne(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.eq("student_name","牟心智");
              Student student = mapper.selectOne(wrapper); //查询多条会报错
              System.out.println(student);
          }
          @Test
          void exists(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.eq("student_name","高小红");
              boolean exists = mapper.exists(wrapper);
              System.out.println(exists);
          }
          @Test
          void count(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高");
              Long aLong = mapper.selectCount(wrapper);
              System.out.println(aLong);
          }
           @Test
           //查询结果以map封装
          void selectMaps(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高");
              List> list = mapper.selectMaps(wrapper);
              list.forEach(e->{
                  e.forEach((k,v)->{
                      System.out.println(k+"\t"+v);
                  });
              });
          }
          @Test
          //只返回第一个字段的值
          void selectObjs(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高");
              List objects = mapper.selectObjs(wrapper);
              objects.forEach(System.out::println);
          }
           @Test
          void selectList(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高");
              List students = mapper.selectList(wrapper);
              students.forEach(System.out::println);
          }
          @Test
          void selectList2(){
              QueryWrapper wrapper = new QueryWrapper<>();
      //        wrapper.like("student_name","高")
      //                .or()
      //                .eq("gender","女");
              List students = mapper.selectList( null);
              students.forEach(System.out::println);
          }
          @Test
          void selectList3(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高")
                      .or()
                      .eq("gender","女");
              List students = mapper.selectList( wrapper);
              students.forEach(System.out::println);
          }
          @Test
          void selectList4(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高").eq("gender","女")
                      .or()
                      .eq("gender","女");
              List students = mapper.selectList( wrapper);
              students.forEach(System.out::println);
          }
          @Test
          //姓高 and (age=女or  age>30)
          void selectList5(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.like("student_name","高")
                      .and(i->i.eq("gender","女").or()
                      .gt("age",30));
              List students = mapper.selectList( wrapper);
              students.forEach(System.out::println);
          }
          @Test
          //排序
          void selectListOrderBy(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.orderByAsc("age").orderByAsc("id");
              List students = mapper.selectList(wrapper);
              students.forEach(System.out::println);
          }
          @Test
          //实现子查询
          void selectSub(){
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.inSql("teacher_id","select id from teacher where teacher_name ='王老师'");
              List students = mapper.selectList(wrapper);
              students.forEach(System.out::println);
          }
       
      

      14.4.6 分页处理

      创建一个分页插件的配置类

      @Configuration
      public class MybatisPlusConfig {
          @Bean
          public MybatisPlusInterceptor mybatisPlusInterceptor() {
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
              return interceptor;
          }
      }
      
      @Test
          void selectPage(){
              Page page = new Page<>(1,2);
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.likeRight("student_name","高");
              mapper.selectPage(page,wrapper);
              System.out.println(page);
              List records = page.getRecords(); // 查询的数据
              long total = page.getTotal(); //总记录数
              long pages = page.getPages(); //总页数
              long current = page.getCurrent(); //当前页
              long size = page.getSize(); // 每页显示 ?条数据
              boolean b = page.hasPrevious(); //是否有上一页
              boolean b1 = page.hasNext(); //是否有下一页
          }
      
       @Test
          void selectMapsPage(){
              Page> page = new Page<>(1,2);
              QueryWrapper wrapper = new QueryWrapper<>();
              wrapper.likeRight("student_name","高");
              mapper.selectMapsPage(page,wrapper);
              System.out.println(page);
              List> records = page.getRecords(); // 查询的数据
              long total = page.getTotal(); //总记录数
              long pages = page.getPages(); //总页数
              long current = page.getCurrent(); //当前页
              long size = page.getSize(); // 每页显示 ?条数据
              boolean b = page.hasPrevious(); //是否有上一页
              boolean b1 = page.hasNext(); //是否有下一页
              records.forEach(System.out::println);
              records.forEach(map->map.forEach((k,v)-> System.out.println(k+"\t"+v)));
          }
      

      14.4.7 自动义查询语句处理

      要在yml.xml文件中配置mapper.xml文件路径和别名

      mybatis-plus:
        mapper-locations: classpath:/mapper/**/*.xml
        type-aliases-package: com.liqun.entity
      

      编写mapper接口和xml

      测试:

      搭建springboot工程,在这里插入图片描述,第18张

      14.5 主键生成策略

      五中策略

      • auto:数据库id自增
      • assign_id:通过雪花算法,生成id(number或string)
      • assign_uuid:使用UUID,主键string类型 32位长字符串(包含数字和字母)
      • nput:用户输入ID
      • none:没有指定主键的类型(注解里使用,跟随全局。全局里使用,相当于input)

        搭建springboot工程,在这里插入图片描述,第19张

        在yaml配置文件中配置全局主键生成策略

        mybatis-plus:
          configuration:
            db-config:
              id-type: auto
        

        14.6 自动填充功能

        实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler

        接口的实现类:

        @Slf4j
        @Component
        public class MyMetaObjectHandler implements MetaObjectHandler {
            @Override
            public void insertFill(MetaObject metaObject) {
                // 在插入时完成自动天车工功能
                this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
                this.strictInsertFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
            }
            @Override
            public void updateFill(MetaObject metaObject) {
                // 在更新时完成自动天车工功能
                this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
            }
        }
        

        将数据库表中加入两个字段

        create_time datetime类型

        update_time datetime类型

        在实体类中加入两个属性,并加入fill规则

            @TableField(fill = FieldFill.INSERT)
            private LocalDateTime createTime;
            @TableField(fill = FieldFill.INSERT_UPDATE)
            private LocalDateTime updateTime;
        

        插入数据库表时,createTime和updateTime会自动插入数据,

        更新数据库表时,updateTime会自动更新处理。

        14.7 通用枚举

        使用场景

        • 用户性别 男 女 未知
        • 商品状态 入库 出库
        • 用户状态 激活 未激活

        修改数据库表,加入status字段,类型是int

        在yml文件中添加枚举扫描

        mybatis-plus:
            # 支持统配符 * 或者 ; 分割
            typeEnumsPackage: com.baomidou.springboot.entity.enums
        

        创建枚举

        方式一: 实现Enum接口,重写getValue方法

        public enum StatusEnum  implements IEnum {
            IN(0,"入库"),
            OUT(1,"出库");
            StatusEnum(Integer stutusValue, String statusDesc) {
                this.stutusValue = stutusValue;
                this.statusDesc = statusDesc;
            }
        //    @EnumValue
            private final Integer stutusValue;
            private final String statusDesc;
            @Override
            public String toString() {
                return this.statusDesc;
            }
            @Override
            public Integer getValue() {
                return this.stutusValue;
            }
        }
        

        方式二:在枚举类型的值上加入@EnmuValue

        public enum StatusEnum {
            IN(0,"入库"),
            OUT(1,"出库");
            StatusEnum(Integer stutusValue, String statusDesc) {
                this.stutusValue = stutusValue;
                this.statusDesc = statusDesc;
            }
            @EnumValue
            private final Integer stutusValue;
            private final String statusDesc;
            @Override
            public String toString() {
                return this.statusDesc;
            }
        }
        

        在Goods实体类对象上,加入属性,是枚举类型的

        @Data
        public class Goods {
        //    @TableId(type= IdType.AUTO)
        //    @TableId(type = IdType.ASSIGN_ID)
            @TableId(type = IdType.ASSIGN_UUID)
            private String  id;
            private String name;
            @TableField(fill = FieldFill.INSERT)
            private LocalDateTime createTime;
            @TableField(fill = FieldFill.INSERT_UPDATE)
            private LocalDateTime updateTime;
            //创建枚举类型
            private StatusEnum status;
        }
        

        14.8 Service的接口和实现类

        新增一个service接口,击沉gIService接口

        public interface StudentService extends IService {
        }
        
        @Service
        public class StudentServiceImpl extends ServiceImpl implements StudentService   {
        }
        

        新增一个service实现类,继承ServiceImpl,实现自定义的service接口

        14.9 多数据源

        步骤1:导入依赖:

                
                    com.baomidou
                    dynamic-datasource-spring-boot-starter
                    3.6.1
                 
        

        步骤2:配置yml文件:

        spring:
          datasource:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
            username: root
            password: 123456
            dynamic:
              primary: master
              strict: false
              datasource:
                master:
                  url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
                  username: root
                  password: 123456
                  driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
                slave_1:
                  url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
                  username: root
                  password: 123456
                  driver-class-name: com.mysql.jdbc.Driver
        

        步骤4:在Service时尚加入@DS(“数据源名称”)

        @Service
        @DS("master")
        public class StudentServiceImpl extends ServiceImpl implements StudentService   {
        }
        @Service
        @DS("slave_1")
        public class EmpServiceImpl extends ServiceImpl implements EmpService {
        }
        

        @DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。

        14.10 乐观锁插件

        当要更新一条记录的时候,希望这条记录没有被别人更新

        乐观锁实现方式:

        • 取出记录时,获取当前 version
        • 更新时,带上这个 version
        • 执行更新时, set version = newVersion where version = oldVersion
        • 如果 version 不对,就更新失败

        配置乐观锁插件

        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
            return interceptor;
        }
        

        创建数据库表,增加version字段

        实体类添加@Version注解

        @Data
        public class Bank {
            @TableId(type = IdType.AUTO)
            private Integer id;
            private String name;
            private Integer money;
            @Version
            private Integer version;
        }
        

        说明:

        • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
        • 整数类型下 newVersion = oldVersion + 1
        • newVersion 会回写到 entity 中
        • 仅支持 updateById(id) 与 update(entity, wrapper) 方法
        • 在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

        14.11 ActiveRecord操作

        ActiveRecord(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。

        ActiveRecord一直广受动态语言(PHP、Ruby等)的喜爱,而java作为准静态语言,对应ActiveRecord往往只能感叹其优雅,所以MP也在AR道路上进行了一定的探索。

        支持ActiveRecord模式:

        • 支持ActiveRecord形式调用,实体类只需继承Model类即可进行强大的CRUD操作。
        • 需要项目中已注入对应实体的BaseMapper。

        继承实体类Model:

        @Data
        @Accessors(chain = true) //支持链式编程
        public class Emp extends Model {
            private Integer id;
            private String name;
            private String addr;
        }
        

        使用测试:

            @Test
            void testAR(){
                Emp emp = new Emp();
                emp.setName("李四").setAddr("天津");
                boolean insert = emp.insert();
                System.out.println(insert);
            }
        

        这里有个问题:多数据源的情况下,这个怎么选择不同的数据源呢?

        14.12 代码生成器

        步骤1:在pom.xml文件中加入相关依赖

        
        
            
                springboot2
                com.liqun
                1.0-SNAPSHOT
            
            4.0.0
            springboot_mybatisplus_generator
            
                8
            
            
                
                
                    org.springframework.boot
                    spring-boot-starter-freemarker
                
                
                    org.springframework.boot
                    spring-boot-starter-web
                
                
                    org.springframework.boot
                    spring-boot-devtools
                    runtime
                    true
                
                
                    mysql
                    mysql-connector-java
                    runtime
                
                
                    org.projectlombok
                    lombok
                
                
                    org.springframework.boot
                    spring-boot-starter-test
                
                
                    io.springfox
                    springfox-boot-starter
                    3.0.0
                
                
                    com.baomidou
                    mybatis-plus-boot-starter
                    3.5.1
                
                
                    com.baomidou
                    mybatis-plus-generator
                    3.5.2
                
            
            
                
                    
                        org.springframework.boot
                        spring-boot-maven-plugin
                        
                            
                                
                                    org.projectlombok
                                    lombok
                                
                            
                        
                    
                
            
        
        

        yaml 文件:

        spring:
          datasource:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
            username: root
            password: 123456
          mvc:
            pathmatch:
              matching-strategy: ant_path_matcher # 解决swagger3报错的
        mybatis-plus:
          global-config:
            db-config:
              logic-delete-field: deleted
        

        测试生成器:

            @Test
            void Generator(){
                FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8", "root", "123456")
                        .globalConfig(builder -> {
                            builder.author("滨海之君") // 设置作者
                                    .enableSwagger() // 开启 swagger 模式
                                    .fileOverride() // 覆盖已生成文件
                                    .outputDir(".\\src\\main\\java"); // 指定输出目录
                        })
        //                .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
        //                    int typeCode = metaInfo.getJdbcType().TYPE_CODE;
        //                    if (typeCode == Types.SMALLINT) {
        //                        // 自定义类型转换
        //                        return DbColumnType.INTEGER;
        //                    }
        //                    return typeRegistry.getColumnType(metaInfo);
        //
        //                }))
                        .packageConfig(builder -> {
                            builder.parent("com.liqun") // 设置父包名
                                    .moduleName("generator"); // 设置父包模块名
        //                            .pathInfo(Collections.singletonMap(OutputFile.xml, "D://")); // 设置mapperXml生成路径
                        })
                        .strategyConfig(builder -> {
                            builder.addInclude("t_emp") // 设置需要生成的表名
                                    .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                        })
                        .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                        .execute();
            }
        

        统一返回结果对象:

        public interface ResultCode {
            Integer SUCCESS = 20000;
            Integer ERROR = 20001;
        }
        
        @Data
        @Accessors(chain = true)
        public class Result {
            private Boolean isSuccess;
            private Integer code;
            private String message;
            private Map data;
            public static Result success(){
                return new Result().setIsSuccess(true)
                        .setCode(ResultCode.SUCCESS)
                        .setMessage("操作成功")
                        .setData(new HashMap<>());
            }
            public static Result error(){
                return new Result().setIsSuccess(false)
                        .setCode(ResultCode.ERROR)
                        .setMessage("操作失败")
                        .setData(new HashMap<>());
            }
            public Result setData(HashMap data){
                this.data = data;
                return this;
            }
            public Result setData(String key,Object value){
                this.data.put(key,value);
                return this;
            }
        }
        

        对于mapper.xml文件的使用

        在yml文件中配置mapper.xml的位置和别名个

        mybatis-plus:
          mapper-locations: mapper/**/*.xml
          type-aliases-package: com.liqun.generator.entity
        

        在生成器中,设置mapper.xml文件生成的位置

        搭建springboot工程,在这里插入图片描述,第20张

        14.13 使用MybatisX插件

        功能1: 在Mapper.java 和Mapper.xml 之间切换。

        功能2: 生成代码

        步骤1:配置idea的数据库链接

        步骤2:

        搭建springboot工程,在这里插入图片描述,第21张

        搭建springboot工程,在这里插入图片描述,第22张

        搭建springboot工程,在这里插入图片描述,第23张

        功能3:

        生成新增

        生成删除

        生成查询

        生成修改

        15. thymeleaf模板引擎

        配置pom.xml

        
        
            
                springboot2
                com.liqun
                1.0-SNAPSHOT
            
            4.0.0
            springboot_thymeleaf
            
                
                    org.springframework.boot
                    spring-boot-starter-thymeleaf
                
                
                    com.baomidou
                    mybatis-plus-boot-starter
                    3.5.1
                
                
                    org.springframework.boot
                    spring-boot-devtools
                    runtime
                    true
                
                
                    com.alibaba
                    druid-spring-boot-starter
                    1.2.8
                
                
                    mysql
                    mysql-connector-java
                    runtime
                
                
                    org.projectlombok
                    lombok
                
            
            
                
                    
                        org.springframework.boot
                        spring-boot-maven-plugin
                        
                            
                                
                                    org.projectlombok
                                    lombok
                                
                            
                        
                    
                
            
         
        

        配置yml文件

        spring:
          datasource:
            druid:
              url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
              username: root
              password: 123456
          thymeleaf:
            cache: false # (默认是打开的)。 开发环境下,关闭缓存,生产环境下,打开缓存
        mybatis-plus:
          configuration:
            log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
          global-config:
            db-config:
              logic-delete-field: deleted
        

        创建模板:

        File>Settings>Editor>file and Code Templates ,

        选择File对话框,点击加号,

        新建 名称 thymeleaf ,扩展名为html

        搭建springboot工程,在这里插入图片描述,第24张

        thymeleaf 中${} 报红处理

        搭建springboot工程,在这里插入图片描述,第25张

        解决方式1:

        
        

        解决方式2:

        在下面加入

        
        

        16. 上传处理

        网页:

        搭建springboot工程,在这里插入图片描述,第26张

        Controller:

        搭建springboot工程,在这里插入图片描述,第27张

        yml配置文件

        savePath: c:/uploadtest
        spring:
          servlet:
            multipart:
              max-file-size: 104857600
        

        17. springboot整合redis操作

        在yml文件中配置:

        spring:
          datasource:
            druid:
              url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
              username: root
              password: 123456
          redis:
            port: 6379
            host: localhost
        mybatis-plus:
          type-aliases-package: com.liqun.entity
          configuration:
            log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
        

        Controller中,使用RedisTemplate

        @RestController
        public class RedisController {
            @Resource
            private RedisTemplate redisTemplate;
            private StringRedisTemplate stringRedisTemplate; //这个可以解决乱码
            @GetMapping("/{key}")
            public Object get(@PathVariable String key){
                Object o = stringRedisTemplate.opsForValue().get(key);
                return o;
            }
            @PostMapping("/{key}/{value}")
            public Object set(@PathVariable String key,@PathVariable String value){
                stringRedisTemplate.opsForValue().set(key,value);
                return "ok";
            }
        }
        

        修改RedisTemplate序列化实现类:

        @Configuration
        public class RedisConfig {
            public RedisTemplate redisTemplate(RedisConnectionFactory factory){
                RedisTemplate redisTemplate = new RedisTemplate<>();
                redisTemplate.setConnectionFactory(factory);
                redisTemplate.setKeySerializer(new StringRedisSerializer());
                redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
                return redisTemplate;
            }
        }
         
        

        模拟缓存操作:

        @RestController
        @RequestMapping("/member")
        public class MenberController {
            @Resource
            private MemberService memberService;
            @Resource
            private RedisTemplate redisTemplate;
            @GetMapping("/{id}")
            public Object getById(@PathVariable int id){
                String key  = "member:"+id;
                //从缓存中查询数据
                Object member = redisTemplate.opsForValue().get(key);
                if(member==null){
                    //从数据库中查询
                    System.out.println("查询数据库");
                    Member m = memberService.getById(id);
                    //将查询结果仿佛缓存
                    redisTemplate.opsForValue().set(key,m);
                    return m;
                }else {
                    System.out.println("查询缓存数据成功");
                    return member;
                }
            }
        }
        

        可以设置redis客户端实现:

        spring:
          redis:
            client-type: lettuce