SpringBoot zero-based entry to proficiency in integrated MyBatis-plus code generation

1. Introduction to Spring Boot

  1. Independently running Spring project Spring Boot can run independently in the form of a jar package, and the Spring Boot project can be run only through the command "java–jar xx.jar".
  2. Embedded Servlet container Spring Boot uses an embedded Servlet container (such as Tomcat, Jetty or Undertow, etc.), and the application does not need to be packaged as a WAR package.
  3. Provide starters to simplify Maven configuration Spring Boot provides a series of "starter" project object models (POMS) to simplify Maven configuration.
  4. Provides a large number of automatic configurations Spring Boot provides a large number of default automatic configurations to simplify project development, and developers also modify the default configurations through configuration files.
  5. Self-contained application monitoring Spring Boot can provide monitoring for running projects. 6. No code generation and xml configuration Spring Boot does not require any xml configuration to implement all configurations of Spring.

2. Build Spring Boot

insert image description here
insert image description here

insert image description here

SpringBoot uses a built-in container (the default container Tomcat) for deployment, so there is no need to configure Tomcat in the idea, just run the main method of the startup class directly

insert image description here
insert image description here

start effect
insert image description here

Look for this line, which means the startup is successful! By default it runs on port 8080

Write a case

1. Controller returns json

@RequestMapping(value = "/test",method = RequestMethod.GET)
    @ResponseBody
public Map<String,Object> test(){
    
    

        Map<String,Object> map = new HashMap<>();
        map.put("msg","测试成功!");

        return map;
    }

4. SpringBoot configuration file - YAML

5. Spring Boot configuration binding

The so-called "configuration binding" is to bind the value in the configuration file with the corresponding property in the JavaBean. Usually, we will put some configuration information (for example, database configuration) in the configuration file, then read the configuration file through Java code, and encapsulate the configuration specified in the configuration file into JavaBean (entity class).

1. Use @ConfigurationProperties annotation

yml file

# 测试配置
person:
  name: 蔡徐坤
  age: 180
  birth: 1994/11/12
  list:
    - a
    - b
    - c
  map:
   name: 宇将军
   age: 90
  son:
   name: 阿耶夫
   age: 18

java class

@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person implements Serializable {
    
    

    private String name;
    private int age;
    private Date birth;
    private List<String> list;
    private Map<String,Object> map;
    private Person son;

}

2. Use the @Value annotation to get the configuration

@Data
@Component
public class Person implements Serializable {
    
    

    @Value("${person.map.name}")
    private String name;
    private int age;
    private Date birth;
    private List<String> list;
    private Map<String,Object> map;
    private Person son;

}

3. Load the content of the configuration file except the application configuration file

Use @PropertySource

Create an aabbcc.properties configuration file and write the content

cxk.name: giao哥

loading method

@Data
@Component
@PropertySource(value= "classpath:aabbcc.properties")
public class Person implements Serializable {
    
    

    @Value("${cxk.name}")
    private String name;
    private int age;
    private Date birth;
    private List<String> list;
    private Map<String,Object> map;
    private Person son;

}

6. SpringBoot loads the Spring configuration file

1. @ImportResource annotation

Create an xml configuration file in the resources directory

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 注册一个person的实例 -->
    <bean id="person" class="com.example.springbootdemo2023.core.dto.Person" />

</beans>

Add the annotation @ImportResource to the head of the startup class

@ImportResource(locations = "classpath:spring.xml")//导入spring配置文件
@SpringBootApplication
public class SpringBootDemo2023Application {
    
    

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

}

use test

@Controller
@RequestMapping("/login")
public class LoginController {
    
    

    @Autowired
    private Person person;


    @RequestMapping(value = "/test",method = RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> test(){
    
    

        Map<String,Object> map = new HashMap<>();
        map.put("msg","测试成功!");

        System.out.println(person);

        return map;
    }

Print

Person(name=null, age=0, birth=null, list=null, map=null, son=null)

2. Using Spring annotation to import configuration method

configuration class

@Configuration
public class MyConfig {
    
    

    //等同于 <bean id="getPerson" class="com.example.springbootdemo2023.core.dto.Person" />
    @Bean
    public Person getPerson(){
    
    
        Person person = new Person();
        person.setName("gaojingbo");
        return person;
    }

}

7. SpringBoot multi-environment configuration

Slave environment configuration + main environment configuration = complete configuration of boot project

1. Create configuration files in different environments

Created rules:

Development environment: application-dev.yml

Test environment: application-test.yml

Production environment: application-prod.yml

application-dev.yml

# 开发环境配置
server:
  port: 8090

application-test.yml

# 测试环境配置
server:
  port: 8100

application-prod.yml

# 生产环境配置
server:
  port: 9010

Main configuration file - application.yml

The main environment configuration file can write some configuration items that will not change

# 主配置文件

# 激活环境配置
spring:
  profiles:
    active: test

2. Define the method to activate the environment configuration

1. Set by command parameter when running the jar package

insert image description here

2. Tool settings can be used during idea development

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-r1d49SYm-1678073315611)(note picture/image-20230228155426602.png)]

3. Use jvm parameter settings when packaging and running

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-GC5c8rQP-1678073315613)(note picture/image-20230228155359901.png)]

8. Loading priority of SpringBoot default configuration file

Configuration files in the root directory > configuration files in the config folder in the classpath directory > configuration files in the classpath directory

All writing priority: (the smaller the serial number, the higher the priority)

  1. ​ file:./config/
  2. file:./config/*/
  3. file:./
  4. classpath:/config/
  5. classpath:/

Note: file: refers to the root directory of the current project; classpath: refers to the classpath of the current project, namely the resources directory.

1. When the annotation configuration and the introduction of external configuration are mixed together, the priority of complete loading

  1. command line parameters
  2. JNDI properties from java:comp/env
  3. Java System Properties (System.getProperties())
  4. operating system environment variables
  5. Random.* property values ​​configured by RandomValuePropertySource
  6. Configuration files (YAML files, Properties files)
  7. The configuration file specified by @PropertySource on the @Configuration annotation class
  8. Default properties specified by SpringApplication.setDefaultProperties

9. SpringBoot usage log

1. Configuration log: add the following content to the springboot configuration file

# 日志配置
logging:
  level:
    com.example.springbootdemo2023: debug # 描述根包下所有的类都要进行日志记录
  file:
    path: F:\idea_logs\SpringBootDemo2023 # 离线生成的日志文件位置
  pattern:
    # 控制台日志的模板效果
    console: "%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %yellow(%-5level) %logger{50} - %m%n" 
    # 保存到文件中的日志效果
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %m%n"

10. Spring Boot interceptor

1. Define the interceptor

It is exactly the same as SpringMVC writing

/**
 * 模块名称:登录会话验证拦截器
 * 模块类型:
 * 编码人:高靖博
 * 创建时间:2023/3/1
 * 联系电话:18587388612
 */
public class LoginInterceptor implements HandlerInterceptor {
    
    

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    

        System.out.println("登录拦截器被调用!");
        return true;
    }
}

2. Register interceptor

Create a configuration class that implements the WebMvcConfigurer interface (a class annotated with @Configuration), override the addInterceptors() method, and call the registry.addInterceptor() method in this method to register the custom interceptor in the container.

InterceptorRegistration configures interceptor rules:

addPathPatterns: set the rules for entering the interceptor

excludePathPatterns: Set rules that do not enter the interceptor

Note: If the path does not exist, if it is 404, it will definitely enter the interceptor

// 1. 实现WebMvcConfigurer 接口
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    

    //2.重写addInterceptors方法
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        //3. 注册自定义编写的拦截器
        // 调用addInterceptor,参数传递拦截器实例
        InterceptorRegistration ic = registry.addInterceptor(new LoginInterceptor());
        //设置拦截器的拦截规则
        ic.addPathPatterns("/**");
        //放行拦截器(登录页面、登录请求、静态资源(js、css、img、video、font(字体文件))、阿里druid连接池监控中心、swaggerui)
        ic.excludePathPatterns(
                "/login/test2",
                "/sys/user/doLogin",
                "/js/**",
                "/css/**",
                "/imgs/**",
                "/druid/**",
                "/swagger-ui.html",
                "/v2/**",
                "/webjars/**",
                "/swagger-resources/**",
                "/sys/user/captcha",
                "/sys/platform/**",
                "/sys/files/**");
    }
}

11. SpringBoot integrates Druid connection pool

1. Introduce dependencies

<!-- 和数据源相关操作必须引入 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
<!-- 数据源依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

2. Configure the springboot configuration file

# spring数据源配置
spring:
  datasource:
    # druid连接池
    type: com.alibaba.druid.pool.DruidDataSource
    # mysql驱动
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 数据库连接地址
    url: jdbc:mysql://localhost:3306/javatest?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    # 用户名、密码
    username: root
    password: cxk666
    # druid连接池配置
    # 初始化连接池最大值,连接中活跃数量最大值
    initial-size: 10
    max-active: 8
    # 获取连接等待的最长时间(毫秒)
    max-wait: 60000
    # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
    test-while-idle: true
    # 既作为检测的间隔时间又作为testWhileIdel执行的依据
    time-between-eviction-runs-millis: 60000
    # 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接(配置连接在池中的最小生存时间)
    min-evictable-idle-time-millis: 30000
    # 用来检测数据库连接是否有效的sql 必须是一个查询语句(oracle中为 select 1 from dual)
    validation-query: select 1 from dual
    # 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
    test-on-borrow: false
    # 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
    test-on-return: false
    # 是否缓存preparedStatement, 也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
    pool-prepared-statements: false
    # 置监控统计拦截的filters,去掉后监控界面sql无法统计,stat: 监控统计、Slf4j:日志记录、waLL: 防御sqL注入
    filters: stat,wall,slf4j
    # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
    max-pool-prepared-statement-per-connection-size: -1
    # 合并多个DruidDataSource的监控数据
    use-global-data-source-stat: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    web-stat-filter:
      # 是否启用StatFilter默认值true
      enabled: true
      # 添加过滤规则
      url-pattern: /*
      # 忽略过滤的格式
      exclusions: /druid/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico
    stat-view-servlet:
      # 是否启用StatViewServlet默认值true
      enabled: true
      # 访问路径为/druid时,跳转到StatViewServlet
      url-pattern: /druid/*
      # 是否能够重置数据
      reset-enable: false
      # 需要账号密码才能访问控制台,默认为root
      login-username: admin
      login-password: 123456
      # IP白名单
      allow: 127.0.0.1
      # IP黑名单(共同存在时,deny优先于allow)
      deny:

12. SpringBoot integrates MyBatis

1. Introduce dependencies

<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>

2. Modify the SpringBoot configuration file

mybatis:
  #xml文件路径映射(xml文件要和接口文件同名)
  mapper-locations: com/huawei/bootdemo2/mybatis/dao/*.xml
  #dto别名映射
  type-aliases-package: com.huawei.bootdemo2.mybatis.domain
  configuration:
    map-underscore-to-camel-case: true #驼峰映射规则   
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #mybatis默认日志

3. Add an annotation to scan the mapper interface on the startup class

@MapperScan("com.example.springbootdemo2023.mybatis.dao")// mapper接口所在的包
@SpringBootApplication
public class SpringBootDemo2023Application {
    
    

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

}

4. Write the interface and xml file of mybatis normally

Use the code generator to do it, ignoring

5. Configure maven static resource packaging

Because the xml file exists in the java source code directory, maven will only package the java file by default

Configuration in pom.xml

<build>
		...
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.yml</include>
                    <include>**/*.yaml</include>
                    <include>**/banner.txt</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

5. Test

This case is to introduce the mapper interface in the controller, which needs to be layered during development.

@Controller
@RequestMapping("/login")
public class LoginController {
    
    

    @Autowired
    private TGoodsMapper goodsMapper;

    @RequestMapping(value = "/test",method = RequestMethod.GET)
    @ResponseBody
    public TGoods test(){
    
    

        TGoods tGoods = goodsMapper.selectByPrimaryKey("101");

        return tGoods;
    }


}

6. SpringBoot integrates Mybatis paging tool

PageHepler

1. Introduce dependencies

<!-- 分页插件pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.3.0</version>
<!-- 排除依赖,因为pageHelper是和Mybatis天然集成所以强依赖mybatis,但是我们项目中已经有了mybatis依赖就去掉 -->
            <exclusions>
                <exclusion>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <groupId>org.mybatis.spring.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

2. Create a paged result set object

/**
 * 模块名称:接收分页的结果DTO
 * 模块类型:
 * 编码人:高靖博
 * 创建时间:2023/3/1
 * 联系电话:18587388612
 */
@Data
public class MyPager<T> implements Serializable {
    
    

    private int page;//结果的页码
    private int pageSize;//每页显示行数
    private List<T> rows;//分页当前页的结果集
    private long total;//不分页所有数据总和(用于页码生成)
    
}

3. Create an entity that receives pagination query parameters

/**
 * 模块名称:用于接收分页查询参数
 * 模块类型:
 * 编码人:高靖博
 * 创建时间:2023/3/1
 * 联系电话:18587388612
 */
@Data
public class MyPageBand implements Serializable {
    
    
    
    private int page;
    private int size;
    
}

4. If there is a circular dependency problem

If the jdk you use is version 8~10, you can only reduce the springBoot version to 2.5.5

5. Test

@Autowired
    private TGoodsMapper goodsMapper;

    @RequestMapping(value = "/test",method = RequestMethod.GET)
    @ResponseBody
    public MyPager test(MyPageBand page){
    
    

        //创建条件对象
        TGoodsExample example = new TGoodsExample();

        //创建mybatis条件对象
        TGoodsExample.Criteria criteria = example.createCriteria();

//        criteria.andNameLike("%六个核弹%");
//        criteria.andPriceBetween(new BigDecimal(20),new BigDecimal(30));

        //1.创建分页对象
        MyPager<TGoods> myPager = new MyPager<TGoods>();
        //2.调用分页工具设置分页参数(页码,每页显示多少行数据)
        Page<TGoods> goodsPage = PageHelper.startPage(page.getPage(), page.getSize());

        //3.执行mapper的查询接口操作
        goodsMapper.selectByExample(example);// !!!!!!!

        List<TGoods> result = goodsPage.getResult();
        long total = goodsPage.getTotal();//数据查询的所有行数值

        myPager.setTotal(total);
        myPager.setRows(result);
        myPager.setPage(page.getPage());
        myPager.setPageSize(page.getSize());

        return myPager;
    }

13. SpringBoot integrates MyBatis-plus

Everything is born for simplicity

1. Replace dependencies

<!-- 删除mybati、pagehepler依赖 -->

<!-- 新:版本升级 mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

2. Modify the SpringBoot configuration file

#mybatis-plus配置
mybatis-plus:
  #dto别名映射
  type-aliases-package: com.example.springbootdemo2023.mybatis.domain
  #xml文件路径映射(xml文件要和接口文件同名)
  mapper-locations: com/example/springbootdemo2023/mybatis/dao/**/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启日志
    map-underscore-to-camel-case: false
  # 全局变量配置
  # 逻辑删除-如:每个表中都有一个通用的字段isDelete描述当前数据是否被删除,1:已删除 0:未删除
  global-config:
    db-config:
      # 当逻辑删除应该设置什么值:1
      logic-delete-value: 1
      logic-not-delete-value: 0
      logic-delete-field: isDelete

3. Define the myBatis-plus database table entity

@Data
@TableName("t_goods")
public class TGoods implements Serializable {
    
    
    
    // id一定要标注,也就表明:每个表都必须有主键
    @TableId(value = "goodsID",type = IdType.NONE)
    private String goodsID;
    private String name;
    private BigDecimal price;
    private String typeName;
}

4. Use MyBatis-plus to define the method of mapper interface (changed)

  1. Create a mybatismapper interface to integrate the BaseMapper interface of mybatis-plus
  2. Define generics at the interface: Generics are the database entity types corresponding to the current mapper interface operations

baseMapper has prepared all common interface methods in advance (addition, deletion, modification, query, page-by-page query)

The content that needs to be manually implemented by yourself is defined in the interface and xml file

@Mapper
public interface TGoodsMapper extends BaseMapper<TGoods> {
    
    
    
    
    
}

5. Define an empty xml file with the same name as the mapper interface

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springbootdemo2023.mybatis.dao.goods.TGoodsMapper">

</mapper>

As long as the above two steps 3 and 4 are completed, mybatis-plus has completed the automatic injection of code generation

6. Test

@Autowired
    private TGoodsMapper goodsMapper;

    @RequestMapping(value = "/test",method = RequestMethod.GET)
    @ResponseBody
    public MyResult test(MyPageBand page){
    
    

        MyResult result = new MyResult();

        TGoods tGoods = goodsMapper.selectById("101");

        result.setData(tGoods);

        return result;
    }

14. MyBatis-Plus

  1. mybatis-plus: About the definition method of DO entity class (there must be a class in Java corresponding to the table in the database)
  2. mybatis-plus:mapper mapping file and interface writing
  3. MyBatis-plus: Realize zero sql code addition, deletion, modification and query (using the method in baseMapper)
  4. Configuration of Mybatis-plus code generator

1. Definition rules of MyBatis-plus-DO entity

1. @TableName (table name) - must write

Implement class and table one-to-one mapping

@Data
@TableName("t_goods")
public class TGoods implements Serializable {
    
    
   ...   
}

2. @TableId - describes the primary key field - must write

value parameter: Specifies the name of the primary key field in the mapped table

type parameter: used to define the type of the primary key (the primary key strategy uses IdType to define)

​ IdType.AUTO: Use the database's own auto-increment key mode to realize id generation. Be sure to remember that the database must be set to auto-increment to be effective

​ IdType.NONE: Does not implement automatic generation of primary keys, no constraints

​IdType.INPUT : Does not implement automatic primary key generation, constrains this attribute to have a value, and allows developers to define it themselves

​ IdType.ASSIGN_ID: Generate an auto-incremented integer value through the mybatis mechanism

​IdType.ASSIGN_UUID : Generate -UUID value through mybatis mechanism

@Data
@TableName("t_goods")
public class TGoods implements Serializable {
    
    

    // id一定要标注,也就表明:每个表都必须有主键
    @TableId(value = "goodsID",type = IdType.ASSIGN_UUID)
    private String goodsID;
    private String name;
    private BigDecimal price;
    private String typeName;
}

3. @TableField- Definition description of ordinary fields-not required

value parameter: Specifies the field name mapped to it in the mapped table

exist parameter: (boolean)

​ false: This field may not exist in the corresponding table of the current entity, to prevent mybatis from generating the addition, deletion, and 'modification codes of this field

​ true: This field exists in the corresponding table of the current entity, and true is the default value

fill parameter: filling function (deleted nodes will also trigger UPDATE modification strategy)

​ FieldFill.INSERT: Trigger the filling strategy when inserting

​ FieldFill.UPDATE: Trigger the filling strategy when modified

​ FieldFill.INSERT_UPDATE: Trigger the filling strategy when modified or added

@Data
@TableName("t_goods")
public class TGoods implements Serializable {
    
    

    // id一定要标注,也就表明:每个表都必须有主键
    @TableId(value = "goodsID",type = IdType.ASSIGN_UUID)
    private String goodsID;
    private String name;
    private BigDecimal price;
    private String typeName;

    //当操作新增时,该字段自动填写当前时间
    @TableField(value = "insertTime",fill = FieldFill.INSERT)// 在什么时候要做某个事情
    private Date insertTime;

    @TableField(value = "updateTime",fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

}

When the filling strategy is defined, how to fill needs to be manually defined and implemented

/**
 * 模块名称:mybatis-plus字段自动填充策略实现
 * 模块类型:
 * 编码人:高靖博
 * 创建时间:2023/3/2
 * 联系电话:18587388612
 */
@Component
public class MyBatisPlusFillHandler implements MetaObjectHandler {
    
    

    //当触发新增填充策略时会调用的方法
    @Override
    public void insertFill(MetaObject metaObject) {
    
    
        //要给表中的insertTime字段设置一个当前系统时间
        setFieldValByName("inserTime",new Date(),metaObject);

    }

    //当触发修改填充策略时会调用的方法
    @Override
    public void updateFill(MetaObject metaObject) {
    
    
        //要给表中的insertTime字段设置一个当前系统时间
        setFieldValByName("updateTime",new Date(),metaObject);
    }
}

test code

@Autowired
    private TGoodsMapper goodsMapper;

    @RequestMapping(value = "/test",method = RequestMethod.GET)
    @ResponseBody
    public MyResult test(MyPageBand page){
    
    

        MyResult result = new MyResult();

        TGoods tGoods = new TGoods();
        tGoods.setName("iPhone1000");
        tGoods.setPrice(new BigDecimal("50"));
        tGoods.setTypeName("手机");

        int insert = goodsMapper.insert(tGoods);

        result.setData(insert);

        return result;
    }

    @RequestMapping(value = "/test2",method = RequestMethod.GET)
    @ResponseBody
    public MyResult test2(MyPageBand page){
    
    

        MyResult result = new MyResult();

        TGoods tGoods = new TGoods();
        tGoods.setGoodsID("101");
        tGoods.setName("switch");
        tGoods.setPrice(new BigDecimal("2"));

        int insert = goodsMapper.updateById(tGoods);

        result.setData(insert);

        return result;
    }

    @RequestMapping(value = "/test3",method = RequestMethod.GET)
    @ResponseBody
    public MyResult test3(MyPageBand page){
    
    

        MyResult result = new MyResult();

        int insert = goodsMapper.deleteById("101");

        result.setData(insert);

        return result;
    }

2. mybatis-plus:mapper mapping file and interface writing

Interface file (XXXMapper.java)

Implement the BaseMapper interface

BaseMapper provides methods for adding, deleting, modifying, checking, and paging based on generic definitions

BaseMapper源码
    public interface BaseMapper<T> extends Mapper<T> {
    
    
    int insert(T entity);

    int deleteById(Serializable id);

    int deleteById(T entity);

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);

    int delete(@Param("ew") Wrapper<T> queryWrapper);

    int deleteBatchIds(@Param("coll") Collection<?> idList);

    int updateById(@Param("et") T entity);

    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

    T selectById(Serializable id);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

    default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
    
    
        List<T> ts = this.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(ts)) {
    
    
            if (ts.size() != 1) {
    
    
                throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
            } else {
    
    
                return ts.get(0);
            }
        } else {
    
    
            return null;
        }
    }

    default boolean exists(Wrapper<T> queryWrapper) {
    
    
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0L;
    }

    Long selectCount(@Param("ew") Wrapper<T> queryWrapper);

    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

    <P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);

    <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
}

sql mapping file xml (XXXXMapper.xml)

There is no difference from mybatis, as long as the namespace attribute in the mapper tag defines the fully qualified name of the mapper interface with the same name

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springbootdemo2023.mybatis.dao.goods.TGoodsMapper">
  ...
</mapper>

3. MyBatis-plus: Realize zero sql code addition, deletion, modification and query (using the method in baseMapper)

1. Added -insert

 TGoods tGoods = new TGoods();
        tGoods.setName("iPhone1000");
        tGoods.setPrice(new BigDecimal("50"));
        tGoods.setTypeName("手机");

        int insert = goodsMapper.insert(tGoods);

2. Modify

update method:

​ Parameter 1: The entity object to be updated

​ Parameter 2: update condition

TGoods tGoods = new TGoods();
        tGoods.setName("掌中宝");

        //更新条件
        QueryWrapper<TGoods> updateWrapper = new QueryWrapper<>();

        // 修改goodsID为101的数据
        // where goodsID = '101'
        updateWrapper.eq("goodsID","101");

        int insert = goodsMapper.update((tGoods),updateWrapper);

updateById

Parameter 1: The entity object that needs to be updated, the primary key field value of the data to be updated must be passed

TGoods tGoods = new TGoods();
        tGoods.setGoodsID("101");
        tGoods.setName("掌中宝12312312312");

        // where 主键字段名=101
        int insert = goodsMapper.updateById(tGoods);// 主键字段必须有值

3. Delete operation

deleteById(Serializable keyid) : directly pass in the primary key value

Parameter 1: The primary key field value of the data to be deleted must be passed

int insert = goodsMapper.deleteById("101");

deleteById (entity parameter): The primary key attribute in the entity object must have a value

TGoods tGoods = new TGoods();
        tGoods.setGoodsID("101");

int insert = goodsMapper.deleteById(tGoods);

delete:

Parameter 1: pass condition object

//删除价格在10元以及10元以上,30元以下的数据
        QueryWrapper<TGoods> deleteWarapper = new QueryWrapper<>();

        /**
         * ge:双参数写法==》   >=
         * ge:三参数写法:第一个参数描述是否使用等于
         *    如: ge(true,"price",10);   ===》   price>=10
         *         ge(false,"price",10);   ===》   price>10
         */
        deleteWarapper.ge(true,"price",10);
        deleteWarapper.le(false,"price",30);

        int insert = goodsMapper.delete(deleteWarapper);

deleteBatchIds: Batch delete according to the primary key value

Parameter 1: Pass the collection that holds the primary key value to be deleted

List<String> ids = new ArrayList<>();
        ids.add("101");
        ids.add("3552f64ba1f71fb41b2a612d636ce186");

        int insert = goodsMapper.deleteBatchIds(ids);

4. Query

1. selectList - query the result set according to the condition

//查询未被删除的数据
        QueryWrapper<TGoods> tGoodsQueryWrapper = new QueryWrapper<>();

        List<TGoods> tGoods = goodsMapper.selectList(tGoodsQueryWrapper);

        result.setData(tGoods);

2. selectMap - query the result set according to the condition - the result set is List类型

//查询未被删除的数据
        QueryWrapper<TGoods> tGoodsQueryWrapper = new QueryWrapper<>();

        List<Map<String, Object>> maps = goodsMapper.selectMaps(tGoodsQueryWrapper);

3. selectCount- the number of rows in the conditional query statistical result set

//查询未被删除的数据
        QueryWrapper<TGoods> tGoodsQueryWrapper = new QueryWrapper<>();

        Long aLong = goodsMapper.selectCount(tGoodsQueryWrapper);

4. selectOne - conditional query results only receive one row of data

//查询未被删除的数据
        QueryWrapper<TGoods> tGoodsQueryWrapper = new QueryWrapper<>();
        
        // 查询结果只有一行数据时可以使用该方法,
        //如果有多行数据就会抛出:One record is expected, but the query result is multiple records
        TGoods tGoods = goodsMapper.selectOne(tGoodsQueryWrapper);

5. selectById - query based on the primary key field

TGoods tGoods = goodsMapper.selectById("101");

6. mybatis-plus paging query

To implement paging, you must first configure the paging component

Add the following code in the startup class

//分页配置
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 分页的方法-以mysql分页方式实现
        return interceptor;
    }
1.selectPage-conditional paging method-use the paging method in the baseMapper interface
 page.setPage(1);//第一页
        page.setSize(2);//每页显示2行

        MyPager<TGoods> pager = new MyPager<>();

        //查询商品名字中有"P"的商品
        QueryWrapper<TGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name","P");

        Page<TGoods> tGoodsPage = goodsMapper.selectPage(PageDTO.of(page.getPage(), page.getSize()), queryWrapper);

        List<TGoods> records = tGoodsPage.getRecords();//分页的结果
        long total = tGoodsPage.getTotal();//不分页所有数据的行数

        pager.setPageSize(page.getSize());
        pager.setRows(records);
        pager.setTotal(total);
        pager.setPage(page.getPage());
2. How to page through special customized interface methods

mapper interface definition

/**
     * 自定义分页写法
     * @param of mp 的分页参数
     * @param goods 自己条件实体
     * @return IPage<TGoods>
     */
    IPage<TGoods> selectGoodsPages(Page of, @Param("goods") TGoods goods);

xml definition

<!-- 虽然传入了分页参数,但是不需要用参数写limit语句,mp会自动拼接生成 -->
    <!-- 自定义查询sql语句,就不会拼接逻辑删除字段条件了,需要手动添加 -->
    <select id="selectGoodsPages" resultType="com.example.springbootdemo2023.mybatis.domain.goods.TGoods">
        select * from t_goods
        <where>
            <if test="goods.name!=null and goods.name!=''">
                and name like '%${
    
    goods.name}%'
            </if>
        </where>
                 
    </select>

test implementation

page.setPage(1);//第一页
        page.setSize(2);//每页显示2行

        MyPager<TGoods> pager = new MyPager<>();

        TGoods tGoods = new TGoods();
        tGoods.setName("P");// 查询name中包含P的商品条件

        IPage<TGoods> tGoodsIPage = goodsMapper.selectGoodsPages(PageDTO.of(page.getPage(), page.getSize()), tGoods);

        List<TGoods> records = tGoodsIPage.getRecords();//分页的结果
        long total = tGoodsIPage.getTotal();//不分页所有数据的行数

        pager.setPageSize(page.getSize());
        pager.setRows(records);
        pager.setTotal(total);
        pager.setPage(page.getPage());

15. MyBatis-plus code generator

generate:

controller class, service interface, service implementation class, database mapping entity class, mapper interface and mapper.xmlsql mapping file

1. Introduce freemarker framework dependency

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

2. Introduce the mybatis-plus code generation toolkit

<!-- mp代码生成器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>

3. Write a code generator

private final static String URL = "jdbc:mysql://localhost:3306/familydb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai";
    private final static String USER_NAME = "root";
    private final static String PWD = "cxk666";
    private final static String AUTHOR = "GaoJingBo";
    private final static String OUT_PUT_DIR = "D://mybatis";
    private final static String PARENT_PACKAGE_NAME = "com.gdones.fmbase.business";
    private final static String PARENT_MODEL_NAME = "ckt";
    private final static String TABLE_NAME = "t_ckt_designes";
    private final static String PREFIX = "t_";


    public static void main(String[] args) {
    
    

        FastAutoGenerator.create(URL, USER_NAME, PWD)
                .globalConfig(builder -> {
    
    
                    builder.author(AUTHOR) // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .dateType(DateType.ONLY_DATE)// 日期类型
                            .commentDate("yyyy-MM-dd") //公共默认日期格式
                            .outputDir(OUT_PUT_DIR); // 指定输出目录
                })
                .packageConfig(builder -> {
    
    
                    builder.parent(PARENT_PACKAGE_NAME) //设置父路径根包
                            .moduleName(PARENT_MODEL_NAME) //设置模块名称
                            .entity("dto") //dto实体
                            .service("service") //业务接口
                            .serviceImpl("service.impl") //业务实现
                            .mapper("mapper") //mybatis-plus-mapper接口
                            .xml("mapper.xml") mybatis-plus-mapper接口映射xml
                            .controller("controller") //控制器
                            .other("other");
                })
                .strategyConfig(builder -> {
    
    
                    builder.controllerBuilder()
                           .enableHyphenStyle()
                           .enableRestStyle();
                    builder.mapperBuilder()
                            .enableMapperAnnotation();
                    builder.entityBuilder()
                            .enableLombok()
                            .logicDeleteColumnName("isDelete")// 逻辑删除表字段名
                            .logicDeletePropertyName("isDelete")// 逻辑删除实体属性名
                            // 添加填充规则
                            .addTableFills(new Column("insertTime", FieldFill.INSERT))
                            .addTableFills(new Column("updateTime", FieldFill.INSERT_UPDATE))
                            .idType(IdType.NONE);
                    builder.addInclude(TABLE_NAME) // 设置需要生成的表名
                            .enableSkipView()//跳过视图
                            .addTablePrefix(PREFIX); // 设置过滤表前缀

                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

4. Complete usage

1. Copy the generated code to the root package

2. Modify mybatis-plus-mapper and xml mapping rule path

#mybatis-plus配置
mybatis-plus:
  #dto别名映射 !!!!!!!!!
  type-aliases-package: com.example.springbootdemo2023.bus.**.dto
  #xml文件路径映射(xml文件要和接口文件同名) !!!!!!!
  mapper-locations: classpath*:com/example/springbootdemo2023/bus/dao/**/mapper/*.xml

3. Modify the path of MapperSacn on the startup class

@MapperScan("com.example.springbootdemo2023.bus.**.mapper") !!!!!
@SpringBootApplication
public class SpringBootDemo2023Application {
    
    
    。。。

4. Check your package structure

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-omoZ5nyw-1678073315615)(note picture/image-20230302172547865.png)]

5. Write code - Controller is written for the entry

@RestController
@RequestMapping("/goods/goods")
public class GoodsController {
    
    

    @Resource(name = "goodsServiceImpl")
    private IGoodsService goodsService;

    @GetMapping("/getGoodsByID")
    public MyResult getGoodDataByGoodID(String id){
    
    

        MyResult result = new MyResult();
		
        // 调用代码生成器生成的方法,业务层零代码直接可以实现增删改查
        Goods byId = goodsService.getById(id);

        result.setData(byId);

        return result;

    }


}

Guess you like

Origin blog.csdn.net/gjb760662328/article/details/129358424