文章目录

  • 一、快速开始(hello-world)
  • 1、创建数据库
  • 2、创建一个springboot项目并导入依赖
  • 3、配置数据连接
  • 4、编写实体类
  • 5、编写Mapper接口
  • 6、测试
  • 二、日志配置
  • 三、插入操作 及 主键生成策略
  • 1、插入操作
  • 2、Mybatis-Plus 中的主键生成策略
  • 四、更新操作 及 自动填充处理
  • 1、更新操作
  • 2、自动填充
  • 五、查询操作 及 分页
  • 1、基本查询操作
  • 2、分页
  • 六、删除操作 及 逻辑删除
  • 1、删除操作
  • 2、逻辑删除
  • 七、乐观锁
  • 1、简介
  • 2、mybatis-plus中实现乐观锁
  • 八、条件构造器(Wrapper)
  • 案例1:= 、!=
  • 案例2:>、>=
  • 案例3:<、<=
  • 案例4:between ... and ..、not between ... and ..
  • 案例5:like、not like
  • 案例6:is null、is not null
  • 案例7:in、not in
  • 案例8:group by、order by
  • 案例9:order by
  • 案例10:or
  • 案例11:in (sql)、not in (sql)
  • 九、代码自动生成器


一、快速开始(hello-world)

1、创建数据库

我们需要创建一张如下的表:

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);
DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');



2、创建一个springboot项目并导入依赖

创建一个 springboot 项目的过程就省略了…

pom依赖

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

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

	<dependency>
	    <groupId>org.projectlombok</groupId>
	    <artifactId>lombok</artifactId>
	</dependency>


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



3、配置数据连接

mysql 8 的配置:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
    username: root
    password: 密码

mysql 5 的配置:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
    username: root
    password: 密码



4、编写实体类

值得注意的是,实体类中的属性名和类型,必须与数据中的字段名完全一致。

package com.tiger.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}



5、编写Mapper接口

这里与 mybatis 的最大的不同在于,这里我们是继承了 BaseMapper,在 BaseMapper 中已经实现了基本的 CURD 操作,已将帮我们实现了大部分常用的 SQL 操作。在这里需要注意的是,BaseMapper 的泛型是与该 Mapper 接口所对应的 pojo 实体类相对应的

package com.tiger.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tiger.pojo.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {

}



6、测试

@SpringBootTest
class MybatisPlusDemoApplicationTests {
    @Autowired
    private UserMapper userMapper;

    @Test
    void contextLoads() {
        List<User> list = userMapper.selectList(null);
        for (User user : list) {
            System.out.println(user.toString()+"\n");
        }
    }
}

mybatis plus 操作hive怎么样 mybatis-plus idwork_主键


二、日志配置

在 mybatis-plus 中日志显得很重要,因为在 mybatis-plus 中的 SQL 执行是不可见的,者难免给开发带来一一定的不便性,如果存在日志,那么就显得得心应手多了。

mybatis-plus 中的日志实现有很多种,如下:

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring boot_02

配置 application.yaml 文件:

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

配置日志之后的执行结果:

mybatis plus 操作hive怎么样 mybatis-plus idwork_User_03


三、插入操作 及 主键生成策略

1、插入操作

在 mybatis-plus 中实现插入操作 是十分的简单,在 快速开始 中我们知道当我们的 Mapper 继承了 BaseMapper,我们就可以直接调用 BaseMapper 中已经提前定义好的相关的 CURD 操作。

实现数据的插入:insert(Object o)

当我没有设置主键的时候,我们看一下会发生什么。

@Autowired
    private UserMapper userMapper;
    @Test
    void contextLoads02() {
    //insert into `user`(`name`,age,email) values("studiuostiger",18,"gygsshu@163.com");
        User u = new User();
        u.setName("studiuostiger");
        u.setAge(18);
        u.setEmail("gygsshu@163.com");
        userMapper.insert(u);

        for (User user : userMapper.selectList(null)) {
            System.out.println(user.toString()+"\n");
        }
    }

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring_04

在 Mybatis-Plus 中默认的主键生成策略是 ASSIGN_ID(雪花算法),下面我们会详细说明。



2、Mybatis-Plus 中的主键生成策略

说是 mybatis-plus 中的主键生成策略我们就要用到 @TableID 注解,在实体类中的主键字段上使用@TableID 注解可以帮我们选择ID生成策略。

当我点击进入 @TableID 注解后

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring boot_05


点击进入 IdType

mybatis plus 操作hive怎么样 mybatis-plus idwork_mybatis-plus_06

package com.baomidou.mybatisplus.annotation;

public enum IdType {
    AUTO(0),
    NONE(1),
    INPUT(2),
    ASSIGN_ID(3),
    ASSIGN_UUID(4),
    @Deprecated
    ID_WORKER(3),
    @Deprecated
    ID_WORKER_STR(3),
    @Deprecated
    UUID(4);

    private final int key;
    private IdType(int key) {this.key = key;}
    public int getKey() {return this.key;}
}

我们可以发现在 mybatis-plus 中的主键生成策略有 8 种:

AUTO:主键自增(数据库主键需要设置自增)

NONE:如果你要操作的表中没有设置主键,那么可以使用 IdType.NONE 策略。

INPUT:插入数据前自行设置主键。如果你自定义了主键生成算法,那么可以使用 IdType.INPUT 策略。

ASSIGN_ID:如果不设置类型值,默认则使用 IdType.ASSIGN_ID 策略(自 3.3.0 起)。该策略会使用雪花算法自动生成主键 ID,主键类型为长或字符串(分别对应的 MySQL 的表字段为 bigint 和 varchar)【默认】

ASSIGN_UUID:如果使用 IdType.ASSIGN_UUID 策略,使用的设计 UUID 算法,但是取出生成的 UUID 中的 "- "。主键类型为 String,对应 MySQL 的表分段为 varchar(32)

ID_WORKER:已过时。全局唯一 id(雪花算法),要求数据库中的字段为。 long

ID_WORKER_STR:已过时。全局唯一 id(雪花算法),要求数据库中的字段为 varchar。

UUID:已过时。这个是使用的 java 原生的 API——UUID,其与ASSIGN_UUID的不同在于 UUID 是带 " - " 的。



最后分写一篇写的不错的文章:分布式系统唯一 ID 生成方案汇总。


四、更新操作 及 自动填充处理

1、更新操作

mybatis-plus给我们提供的更新操作的接口 updateById(Object o) ,我们专递的参数是一个实体对象。根据ID进行更新,所以setId() 是必须的操作,剩下的是对我们需要修改的数据进行setXxx()。

根据ID更新用户名:

@Autowired
private UserMapper userMapper;

@Test
void contextLoads03() {
	// update `user` set `name`="studiuostiger",age=5 where id=2;
    User u = new User();
    u.setId(2L);
    u.setName("studiuostiger");
    u.setAge("5")
    userMapper.updateById(u);
}

mybatis plus 操作hive怎么样 mybatis-plus idwork_mybatis-plus_07

2、自动填充

我们在开发时有这么一种需求:对于数据库中时间的修改与创建,应该是自动进行的,而不是我们手动的尽心操作。

现在我们修改一下数据库中的字段:

mybatis plus 操作hive怎么样 mybatis-plus idwork_User_08

在mybatis-plus中想要实现字段的自动填充只需要两步:

第一步:在需要自动填充的字段所对应的实体类中的属性上使用@TableField(fill = FieldFill.XXXX)注解。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @TableField(fill = FieldFill.INSERT)         //进行插入时进行填充
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)  //进行插入和更新时进行填充
    private Date updateTime;
}

上述的 FieldFill 中有如下几个属性:

public enum FieldFill {
    DEFAULT,         //进行删除时进行填充
    INSERT,			 //进行插入时进行填充
    UPDATE,			 //进行更新时进行填充
    INSERT_UPDATE;	 //进行插入和更新时进行填充

    private FieldFill() {
    }
}



第二步:自定义实现类 MyMetaObjectHandler 完成自动填充的具体内容的编写

insertFill(MetaObject metaObject):进行插入操作时,会触发该方法的执行。

updateFill(MetaObject metaObject):进行更新操作时会触发该方法的执行。

setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject):设置字段的内容

fieldName:将会被填充的字段对应的实体类中的属性名。

fieldVal:将会被填充的内容。

metaObject:填写 metaObject 即可。

package com.tiger.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;

@Slf4j      //日志
@Component  //添加到spring容器中
public class MyMetaObjectHandler implements MetaObjectHandler{
    @Override
    public void insertFill(MetaObject metaObject) {
        //setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}



测试:

@Autowired
private UserMapper userMapper;

@Test
void contextLoads03() {
    User u = new User();
    u.setId(1L);
    u.setAge(88);
    userMapper.updateById(u);
}

mybatis plus 操作hive怎么样 mybatis-plus idwork_mybatis-plus_09

mybatis plus 操作hive怎么样 mybatis-plus idwork_主键_10



五、查询操作 及 分页

1、基本查询操作

单用户查询:selectById(Serializable id)

此方法可以通过传递的ID,查询单个用户。

@Autowired
private UserMapper userMapper;
// 单用户查询
@Test
void contextLoads04() {
	// select * from `user` where id =1;
    User user = userMapper.selectById(1);
    System.out.println(user);
}

多用户查询:selectBatchIds(List list)

当我想要通过id同时查询多个用户信息,那么可以通过该方法进行查询,参数是List集合。

@Autowired
private UserMapper userMapper;
// 多用户查询
@Test
void contextLoads05() {
	// select * from `user` where id =1 and id=2 and id=3;
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    users.forEach(System.out::println);
}

等值条件查询:selectByMap(Map map)

我们可以通过selectByMap实现等值条件查询,例如:当我传递的是(“name”,“studioustiger”),那么其就相当于 select * from user where name = studioustiger;

@Autowired
private UserMapper userMapper;
//条件查询
@Test
void contextLoads06() {
	// select * from `user` where `name`="studioustiger";
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","studioustiger");

    List<User> users = userMapper.selectByMap(map);
}



2、分页

mybatis-plus中给我提供了分页插件,实现分页极其简单,只需要简单的两步。

第一步:配置插件

@Configuration
@MapperScan("com.tiger.mapper")
public class MybatisPlusConfig {
    //配置乐观锁
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

    //配置分页
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

第二步:使用

Page<>(1,3):一定要是 mybatisplus下的Page。Page<>(1,3) 表示查询3条记录作为第1页的结果。

selectPage():分页查询。

getRecords():获取查询的分页记录(结果)。

@Autowired
private UserMapper userMapper;
//分页查询
@Test
void contextLoads07() {
    Page<User> page = new Page<>(1,3);
    userMapper.selectPage(page, null);
    
    page.getRecords().forEach(System.out::println);
}

mybatis plus 操作hive怎么样 mybatis-plus idwork_User_11

Page中还有其他的一些方法,你可以自己去探索一下.

六、删除操作 及 逻辑删除

1、删除操作

① 删除单用户:deleteById(Serializable id)

② 删除多用户:deleteBatchIds(List list)

③ 条件删除:deleteByMap(Map map)



2、逻辑删除

倘若我们想要实现回收站的功能,那么我们也许就要用到逻辑删除。所谓的逻辑删除是指,我们在进行SQL删除操作的时候,我们并不会真正的将数据从数据库中删除,而是通过字段将其不可见。

所以我们需要完善数据字段,如下:

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring boot_12


相应的我们需要去完善实体类中的属性。

在mybatis-plus中实现逻辑删除十分的简单,只需要两步:

第一步:将实体类中的逻辑删除字段加上@TableLogic 注解

@TableLogic
private int deleted;

第二步:配置mybatis-plus的逻辑删除配置

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)

测试

逻辑删除记录:

@Autowired
private UserMapper userMapper;
//逻辑删除记录
@Test
void contextLoads08() {
    userMapper.deleteById(2);
}

mybatis plus 操作hive怎么样 mybatis-plus idwork_User_13

我们进行查询试一下:

@Test
    void contextLoads04() {
        User user = userMapper.selectById(1);
    }

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring boot_14



七、乐观锁

1、简介

当程序中可能出现并发的情况时,就需要保证在并发情况下数据的准确性,以此确保当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的。这就叫做并发控制。并发控制的目的是保证一个用户的工作不会对另一个用户的工作产生不合理的影响。

实现并发控制的主要手段分为乐观并发控制(乐观锁)悲观并发控制(悲观锁) 两种。

悲观锁

在进行数据更更新的过程中,不允许其他用户进行更新操作。在修改数据之前先将数据锁定,再修改的方式被称之为悲观并发控制(悲观锁)。

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring boot_15


乐观锁在进行数据更更新的过程中,不会先将数据锁定,而是允许其他的用户也进行更新操作。当A在更新数据D的过程中B也进行更新数据D(A比B先获取数据),此时分为两种情况:① 若A在更新完成后,B为完成更新,那么B将更新失败;② 若A在更新完成前B先完成了更新,那么A将更新失败 。

mybatis plus 操作hive怎么样 mybatis-plus idwork_mybatis-plus_16

2、mybatis-plus中实现乐观锁

乐观锁实现方式:

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

完善数据库:

mybatis plus 操作hive怎么样 mybatis-plus idwork_spring_17


完善实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    private Long version;
}



在mybatis-plus中实现乐观锁配置需要两步

第一步:在实体类的字段上加上@Version注解

@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 不能复用!!!

第二步:配置插件

spring boot注解方式:

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

spring xml方式:

<bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor" id="optimisticLockerInnerInterceptor"/>

<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    <property name="interceptors">
        <list>
            <ref bean="optimisticLockerInnerInterceptor"/>
        </list>
    </property>
</bean>

至此,我们就完成了乐观锁的配置。

八、条件构造器(Wrapper)

我们上面介绍的更新查询操作都是一些基本的更新查询操作,比如一些 like 、between、>、>=、not null 、order by、and 、or、in… 我们还都没有实现。

下面我们就来介绍一下,如何使用条件构造器(Wrapper)来实现上述的那些功能。

警告:不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输

  • wrapper 很重
  • 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
  • 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
  • 我们拒绝接受任何关于 RPC 传输 Wrapper 报错相关的 issue 甚至
    pr

因为wrapper的方法众多,所以我们就以实例的方式给大家一一介绍。

案例1:= 、!=
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads01() {
        //select * from `use`r where `name` = 'studioustiger' and age = 20 and id!=5;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .eq("name","studioustiger")
                .eq("age",20)
                .ne("id",5);
        userMapper.selectCount(wrapper);
    }
案例2:>、>=
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads02() {
        //select * from `user` where age>18 and id>=2;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .gt("age",18)
                .ge("id",2);
        userMapper.selectCount(wrapper);
    }
案例3:<、<=
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads03() {
        //select * from `user` where age<22 and id<=3;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .lt("age",22)
                .le("id",3);
        userMapper.selectCount(wrapper);
    }
案例4:between … and …、not between … and …
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads04() {
        //select * from `user` where age between 20 and 24;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age",20,24);
        userMapper.selectCount(wrapper);

        //select * from `user` where age not between 20 and 24;
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2.between("age",20,24);
        userMapper.selectCount(wrapper2);
    }
案例5:like、not like
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads05() {
        //select * from `user` where `name` like "%o%";
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("name","o");
        userMapper.selectCount(wrapper);

        //select * from `user` where `name` like "%o%";
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2.notLike("name","o");
        userMapper.selectCount(wrapper2);

        //select * from `user` where `name` like "%o";
        QueryWrapper<User> wrapper3 = new QueryWrapper<>();
        wrapper3.likeLeft("name","o");
        userMapper.selectCount(wrapper3);

        //select * from `user` where `name` like "o%";
        QueryWrapper<User> wrapper4 = new QueryWrapper<>();
        wrapper4.likeRight("name","o");
        userMapper.selectCount(wrapper4);
    }
案例6:is null、is not null
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads06() {
        //select * from `user` where `name` is not null and email is null;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .isNotNull("name")
                .isNull("email");
        userMapper.selectCount(wrapper);
    }
案例7:in、not in
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads07() {
        //select * from `user` where age in (18,19,20);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.in("age",18,19,20);
        userMapper.selectCount(wrapper);

        //select * from `user` where age not in (21,22,23);
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2.notIn("age",21,22,23);
        userMapper.selectCount(wrapper2);
    }
案例8:group by、order by
@Autowired
    private UserMapper userMapper;
    
	@Test
    void contextLoads08() {
        //select * from `user` where age>18 group by age order by id desc;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .gt("age",18)
                .groupBy("age")
                .orderByDesc("id");
        userMapper.selectCount(wrapper);

        //select * from `user` where age>18 group by age order by id asc;
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2
                .gt("age",18)
                .groupBy("age")
                .orderByDesc("id");
        userMapper.selectCount(wrapper2);
    }
案例9:order by
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads09() {
        //select * from `user` where age>18 order by age desc;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .gt("age",18)
                .orderByDesc("age");
        userMapper.selectCount(wrapper);

        //select * from `user` where age>18 order by age asc;
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2
                .gt("age",18)
                .orderByAsc("age");
        userMapper.selectCount(wrapper2);
    }
案例10:or
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads10() {
        //select * from `user` where age>18 or id>4;
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .gt("age",18)
                .or()
                .gt("id",4);
        userMapper.selectCount(wrapper);
    }
案例11:in (sql)、not in (sql)
@Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads11() {
        //select * from `user` where `name` in (select `name` from `user` where age>=21);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.inSql("id","select * from user where age>=21");
        userMapper.selectCount(wrapper);
        
        //select * from `user` where `name` in (select `name` from `user` where age>=21);
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2.notInSql("id","select * from user where age>=21");
        userMapper.selectCount(wrapper2);
    }



九、代码自动生成器

MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

若要实现代码自动生成器。只需要两步:

第一步:导入依赖

MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:

<!--代码生成器 依赖-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>
<!--模本引擎依赖(默认)-->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>latest-velocity-version</version>
</dependency>



第二步:编写代码生成器模版

我们需要变动的地方只有三个地方

pc.setParent("com.tiger"):parent包设置
pc.setModuleName("blog") :模块名设置
strategy.setInclude("user","admin"):参与项目的表名设置

@Test
public void autoCoder(){
    // 代码生成器
    AutoGenerator mpg = new AutoGenerator();

    // 1、全局配置
    GlobalConfig gc = new GlobalConfig();
    String projectPath = System.getProperty("user.dir");
    gc.setOutputDir(projectPath + "/src/main/java");         // 代码输出路径
    gc.setAuthor("StudiousTiger");                           // 设置作者
    gc.setOpen(false);                                       // 无需打开文件夹
    gc.setFileOverride(false);                               // 无需覆盖原本生成的文件
    gc.setServiceName("%sService");                          // 去除Service的前缀 I
    gc.setIdType(IdType.ASSIGN_ID);                          // 设置IdType
    gc.setDateType(DateType.ONLY_DATE);                      // 设置时间类型
//        gc.setSwagger2(true);                                    // 实体属性 Swagger2 注解
    mpg.setGlobalConfig(gc);

    // 2、数据源配置
    DataSourceConfig dsc = new DataSourceConfig();
    dsc.setUrl("jdbc:mysql://localhost:3306/mybatisplus?useUnicode=true&useSSL=false&characterEncoding=utf8");
    dsc.setDriverName("com.mysql.cj.jdbc.Driver");
    dsc.setUsername("root");
    dsc.setPassword("root123123");
    dsc.setDbType(DbType.MYSQL);                               // 数据库类型
    mpg.setDataSource(dsc);

    // 3、包配置
    PackageConfig pc = new PackageConfig();
    pc.setModuleName("blog");                                  // 模块名设置
    pc.setParent("com.tiger");                                 // parent包设置
    pc.setEntity("pojo");                                      // 实体类层包名设置
    pc.setMapper("mapper");                                    // dao层包名设置
    pc.setController("controller");                            // controller层包名设置
    pc.setService("service");                                  // service层包名名设置
    pc.setServiceImpl("service");                              // service实现类包名设置
    mpg.setPackageInfo(pc);


    // 4、策略配置
    StrategyConfig strategy = new StrategyConfig();
    strategy.setNaming(NamingStrategy.underline_to_camel);       // 下划线转驼峰
    strategy.setColumnNaming(NamingStrategy.underline_to_camel);
    strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
    strategy.setEntityLombokModel(true);                         // 使用lombok
    strategy.setLogicDeleteFieldName("deleted");                 // 配置逻辑删除(参与项目的表中需要有此字段)
    strategy.setVersionFieldName("version");                     // 乐观锁的配置(参与项目的表中需要有此字段)
    strategy.setRestControllerStyle(true);                       // 使用RestFul风格
    strategy.setControllerMappingHyphenStyle(true);              // controller映射地址:驼峰转连字符

    ArrayList<TableFill> tableFill = new ArrayList<>();
    tableFill.add(new TableFill("gmt_create", FieldFill.INSERT));         // 设置insert时自动填充(参与项目的表中需要有此字段)
    tableFill.add(new TableFill("gmt_modified", FieldFill.INSERT_UPDATE));// 设置insert_update时自动填充(参与项目的表中需要有此字段)
    strategy.setTableFillList(tableFill);

    strategy.setInclude("user","admin");                                            // 设置相关表名
    mpg.execute();
}



测试

如下都是自动生成的:

mybatis plus 操作hive怎么样 mybatis-plus idwork_mybatis-plus_18




mybatis plus 操作hive怎么样 mybatis-plus idwork_主键_19