搭建springboot工程_学习笔记

1. springboot介绍

2.搭建springboot环境

2.1 使用maven项目

在pox.xml文件中加入parent

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
    </parent>

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

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

创建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创建。
在这里插入图片描述
在这里插入图片描述

2.3 使用Spring initlalizr阿里云

在这里插入图片描述

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

在这里插入图片描述
下载一个压缩包,解压后通过idea打开,就是一个springboot 工程。

3. springboot parent和starter

所有springboot项目要继承的项目
在其中, 依赖了一个spring-boot-dependencies,在里面规范了使用的各第三方依赖的版本号。
在这里插入图片描述

4.启动类

主启动类的位置
在这里插入图片描述

5.springboot 支持的三种服务器

内置tomcat默认的处理器
jetty: 更轻量级的容器
pom.xml文件中配置 的

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!--取消tomcat服务器-->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--加入jetty服务器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

undertow:

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!--取消tomcat服务器-->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--加入undertow服务器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

6. springboot配置文件

创建springboot工程时会自动创建一个application.properties文件。
还可以支持application.yml 和application.yaml格式的文件。
主要应用的是application.yml格式的文件。
如果没有出自动提示,解决方式如下:
在这里插入图片描述

7. 以jar包的方式运行

1.打包的处理
可以 mvn package
也可以使用idea中maven生命周期package,双击
在这里插入图片描述
打包成功,在工程的target目录下找到jar包。进入target目录,运行java -jar 文件名.jar

8.springboot整合swagger3

步骤1:加入依赖

        <!--引入swagger3 的依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

步骤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文件中加入相关依赖

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

步骤2:
勾选idea中的
在这里插入图片描述
步骤3:
按住ctrl+shift+alt+/ 弹出菜单,选择Registry
![在这里插入图片描述](https://img-blog.csdnimg.cn/990625a62ef8411a8d5ce4e3f9caba1a.png
勾选在这里插入图片描述
步骤4:

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

9.3 自动重启设置原理

Springboot提供的重启技术,通过两个类的加载器来完成。ClassLoader
不会更改的类(来自第三方的jar包)被夹在到BaseClassLoader中,
会更改的类被夹在到RestartClassLoader

9.4 排除自动重启资源

有一些资源,在更改是不一定需要触发自动重启。比如thymeleaf,
配置排除的目录

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

10. springboot配置文件位置

springboot启动是会自动查找和加载application.propertiesapplication.yml或者application.yaml
从一下位置
fileL./config/
file:./
classpath:/config/
classpath:./
优先级从上到下。
如果文件没那个不是默认名,需要通过 --spring.config.name=文件名(不要写扩展名) 进行设置在这里插入图片描述
或者(文件已经生成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:

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

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注解

查看自动配置,在这里插入图片描述
redis的配置
在这里插入图片描述

@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

案例:现有一个接口,来实现支付处理,一个实现类,来模拟是使用支付宝支付,一个实现类来模拟使用微信支付,支付的方式跟着开发环境的不同,选择不同的处理方式。
在这里插入图片描述
启动不同的换进,会调用不同的接口。

11.9 yaml文件使用el配置

在这里插入图片描述

11.10 随机值的引用

在这里插入图片描述

12. springboot整个junit

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

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

测试类
要写在test>java下面
@SpringBootTest(classes = AppServer.class) //括号里指明引导类的位置

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

心得:
1.工程中的包一定不要从其他工程复制,太坑了。
2.test 下面的包结构 一定要和main 下面的一致,不一致的话,下面提到的尽管指定了引导类的位置,虽然也能启动,但是测试类在独立的IOC容器, 使用不了Service等组件注入。
3.测试类@SpringBootTest(classes = AppServer.class) 尽量带上括号里面的,这样指定程序的主启动类,这样无论测试类放在那个包下,也不会出问题了。

13. springboot整合mybatis

pom.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot2</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot_mybatis2</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--引入swagger3 的依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

配置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文件中添加分页插件

<!--分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.1</version>
        </dependency>

分页处理代码:

    @ApiOperation("分页显示学生信息")
    @GetMapping("/{start}/{size}")
    public Object listByPage(@PathVariable Integer start,@PathVariable Integer size){
        PageHelper.startPage(start,size);
//        service.selectByPage(start,size);
        List<Student> list = service.selectList();
        PageInfo<Student> 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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mybatis</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis_1</artifactId>

   <!-- <properties>
        <maven.complier.source>8</maven.complier.source>
        <maven.complier.target>8</maven.complier.target>
    </properties>-->

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>

mybaits配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="db.properties"></properties> <!--引入数据库配置-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入我们自己编写的每一个接口的实现文件-->
    <mappers>
        <mapper resource="com/liqun/mapper/StudentMapper.xml"/>
    </mappers>
</configuration>

数据库配置文件: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<Student> 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文件修改

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mybatis</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis_1</artifactId>

   <!-- <properties>
        <maven.complier.source>8</maven.complier.source>
        <maven.complier.target>8</maven.complier.target>
    </properties>-->

    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.15</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <!--<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>2.0.0-alpha7</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>

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

public interface StudentMapper extends BaseMapper<Student> {
//    List<Student> 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<Student> list = mapper.selectList(null);
        list.forEach(System.out::println);
        sqlSession.close();
    }

14.2 mybatis整合spring

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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mybatis</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis_spring</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.15</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>2.0.0-alpha7</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>

步骤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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
">
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <!--配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <--驱动类的名字不需要配置,会根据url自动改的去加载,会知道使用的是哪种数据库-->
    </bean>
    <!--配置sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置mapper的扫描-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.liqun.mapper"/>
    </bean>
</beans>

步骤4: 编写实体类

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

步骤5: 编写mapper接口

public interface StudentMapper extends BaseMapper<Student> {
}

步骤6: 编写测试程序:

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

14.3 mybatis-plus整合springboot

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <!-- <parent>
        <artifactId>springboot2</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot_mybatisplus</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>



    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

配置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<Student> {
}

启动类

@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<Student> 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<String, Object> 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<Integer> 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<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("gender","男")
                .like("student_name","顾");
        mapper.delete(wrapper);
    }

    @Test
    void deleteQW(){
        Student student = new Student();
        student.setStudentName("高小红").setGender("男");
        QueryWrapper<Student> wrapper = new QueryWrapper<>(student);
        mapper.delete(wrapper);
    }
    //使用Lambda方式
    @Test
    void delete2(){
        LambdaQueryWrapper<Student> 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<Student> wrapper = new QueryWrapper<>();
//        wrapper.eq(!StringUtils.isNullOrEmpty(student.getGender()),"gender",student.getGender())
//                .like(!StringUtils.isNullOrEmpty(student.getStudentName()),"student_name",student.getStudentName());
        LambdaQueryWrapper<Student> 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<Student> wrapper = new UpdateWrapper<>();
        wrapper.likeRight("student_name","高");
        mapper.update(student,wrapper);
    }
    @Test
    void update2(){
        UpdateWrapper<Student> 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<Student> 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<Student> students = mapper.selectBatchIds(Arrays.asList(4, 5));
        students.forEach(System.out::println);
    }

    @Test
    void selectByMap(){
        Map<String,Object> map = new HashMap<>();
        map.put("student_name","牟心智");
        List<Student> students = mapper.selectByMap(map);
        students.forEach(System.out::println);
    }
    @Test
    void selectOne(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("student_name","牟心智");
        Student student = mapper.selectOne(wrapper); //查询多条会报错
        System.out.println(student);
    }
    @Test
    void exists(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("student_name","高小红");
        boolean exists = mapper.exists(wrapper);
        System.out.println(exists);
    }

    @Test
    void count(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高");
        Long aLong = mapper.selectCount(wrapper);
        System.out.println(aLong);
    }
     @Test
     //查询结果以map封装
    void selectMaps(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高");
        List<Map<String, Object>> list = mapper.selectMaps(wrapper);
        list.forEach(e->{
            e.forEach((k,v)->{
                System.out.println(k+"\t"+v);
            });
        });
    }
    @Test
    //只返回第一个字段的值
    void selectObjs(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高");
        List<Object> objects = mapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }
     @Test
    void selectList(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高");
        List<Student> students = mapper.selectList(wrapper);
        students.forEach(System.out::println);
    }
    @Test
    void selectList2(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
//        wrapper.like("student_name","高")
//                .or()
//                .eq("gender","女");
        List<Student> students = mapper.selectList( null);
        students.forEach(System.out::println);
    }
    @Test
    void selectList3(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高")
                .or()
                .eq("gender","女");
        List<Student> students = mapper.selectList( wrapper);
        students.forEach(System.out::println);
    }
    @Test
    void selectList4(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高").eq("gender","女")
                .or()
                .eq("gender","女");
        List<Student> students = mapper.selectList( wrapper);
        students.forEach(System.out::println);
    }
    @Test
    //姓高 and (age=女or  age>30)
    void selectList5(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.like("student_name","高")
                .and(i->i.eq("gender","女").or()
                .gt("age",30));

        List<Student> students = mapper.selectList( wrapper);
        students.forEach(System.out::println);
    }

    @Test
    //排序
    void selectListOrderBy(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("age").orderByAsc("id");
        List<Student> students = mapper.selectList(wrapper);
        students.forEach(System.out::println);
    }
    @Test
    //实现子查询
    void selectSub(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.inSql("teacher_id","select id from teacher where teacher_name ='王老师'");
        List<Student> 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<Student> page = new Page<>(1,2);
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.likeRight("student_name","高");
        mapper.selectPage(page,wrapper);
        System.out.println(page);
        List<Student> 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<Map<String,Object>> page = new Page<>(1,2);
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.likeRight("student_name","高");
        mapper.selectMapsPage(page,wrapper);
        System.out.println(page);
        List<Map<String,Object>> 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
测试:
在这里插入图片描述

14.5 主键生成策略

五中策略

  • auto:数据库id自增
  • assign_id:通过雪花算法,生成id(number或string)
  • assign_uuid:使用UUID,主键string类型 32位长字符串(包含数字和字母)
  • nput:用户输入ID
  • none:没有指定主键的类型(注解里使用,跟随全局。全局里使用,相当于input)
    在这里插入图片描述
    在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<Integer> {
    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<Student> {
}
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService   {
}

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

14.9 多数据源

步骤1:导入依赖:

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.6.1</version>
        </dependency> 

步骤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<StudentMapper, Student> implements StudentService   {
}

@Service
@DS("slave_1")
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> 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<Emp> {
    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文件中加入相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot2</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot_mybatisplus_generator</artifactId>
    <properties>
        <java.verson>8</java.verson>
    </properties>

    <dependencies>
        <!--模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

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

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

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<String,Object> 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<String,Object> 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文件生成的位置
在这里插入图片描述

14.13 使用MybatisX插件

功能1: 在Mapper.java 和Mapper.xml 之间切换。
功能2: 生成代码
步骤1:配置idea的数据库链接
步骤2:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
功能3:
生成新增
生成删除
生成查询
生成修改

15. thymeleaf模板引擎

配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot2</artifactId>
        <groupId>com.liqun</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot_thymeleaf</artifactId>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project> 

配置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
在这里插入图片描述
thymeleaf 中${} 报红处理
在这里插入图片描述
解决方式1:

<!--/*@thymesVar id="title" type=""*/-->

解决方式2:
<!DOCTYPE html>下面加入

<!--suppress ALL-->

16. 上传处理

网页:
在这里插入图片描述
Controller:
在这里插入图片描述
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<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(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
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值