Bootstrap

Mybatis-Plus入门

MyBatisPlus

概述

MyBatisPlus官网:https://baomidou.com/

在这里插入图片描述

入门案例

建表、加数据

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)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

在这里插入图片描述

IDEA新建工程

SpringBoot选用2.2.1.RELEASE版本
在这里插入图片描述

POM依赖

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

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

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

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

    <!--lombok用来简化实体类-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

配置文件(关键)

配置文件内容

mysql5

#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus
spring.datasource.username=root
spring.datasource.password=123456

mysql8以上(spring boot 2.1)注意:driver和url的变化
2.1以上版本默认是用MySQL8的驱动

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

主要的区别就是新版本MySQL8在路径中多了个CJ、URL后面加入了时区
注意:

1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为Spring Boot 2.1 集成了 8.0版本的jdbc驱动,这个版本的 jdbc 驱动需要添加这个后缀,否则运行测试用例报告如下错误:

java.sql.SQLException: The server time zone value is unrecognized or represents more

2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,之前的 com.mysql.jdbc.Driver 已经被废弃,否则运行测试用例的时候会有 WARN 信息

导入其他类

导入实体类,Mapper等等内容
在这里插入图片描述
记得加入@Mapper,MP配置类加入@Configuration注解
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试一下

遍历表内容
在这里插入图片描述

SQL输出日志

在XML中加入日志配置,在控制台会输出

# MP 日志输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

主键策略

如果用自增,那么数据库中对应字段也要开启自增
在这里插入图片描述
(1)ID_WORKER

MyBatis-Plus默认的主键策略是:ID_WORKER 全局唯一ID

(2)自增策略

  • 要想主键自增需要配置如下主键策略
  • 需要在创建数据表的时候设置主键自增(自增出来的ID一定比之前的ID要大,但是这种大体现在具体的数值上,方便后续排序。也就是后面自增出来的一定比前面自增的ID要大)
  • 实体字段中配置 @TableId(type = IdType.AUTO)
@TableId(type = IdType.AUTO)
private Long id;

其它主键策略:分析 IdType 源码可知,是一个枚举类

public enum IdType {
     /**
     * 数据库ID自增
     */
    AUTO(0),
    
    /**
     * 该类型为未设置主键类型
     */
    NONE(1),
    
    /**
     * 用户输入ID
     * 该类型可以通过自己注册自动填充插件进行填充
     */    
    INPUT(2),
    
    /**
     * 全局唯一ID
     */    
    ASSIGN_ID(3),
    
    /**
     * 全局唯一ID (UUID)
     */
    ASSIGN_UUID(4),
    
    /** @deprecated */
    @Deprecated
    ID_WORKER(3),
    /** @deprecated */
    @Deprecated
    ID_WORKER_STR(3),
    /** @deprecated */
    @Deprecated
    UUID(4);
    private final int key;
    private IdType(int key) {
        this.key = key;
    }
    public int getKey() {
        return this.key;
    }
}

修改和分页

修改操作

在这里插入图片描述

分页查询

创建配置类

/**
 * 分页插件
 */
@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}

在这里插入图片描述
测试selectPage分页

IPage是page对象的接口,接收分页查询结果也是完全可以的
在这里插入图片描述
测试:最终通过page对象获取相关数据

删除

根据ID精确删

@Test
public void testDeleteById(){
    int result = userMapper.deleteById(目标ID);
    System.out.println(result);
}

批量删

  @Test
    public void testDeleteBatchIds() {
    //int result = userMapper.deleteBatchIds(ID集合,集合就可以自动遍历,Collection接口下的);
        int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));
        System.out.println(result);
    }

逻辑删除

物理删除:真删,这行数据直接干掉,彻底无了
逻辑删除:假删,字段加入标志,比如1是代表形式上没删除,0是形式上已经删除。在查询的时候0就跳过查不出来,假装自己被删了。
在这里插入图片描述
具体步骤
(1)数据库中添加 deleted字段
建议设置一下默认值

ALTER TABLE `user` ADD COLUMN `deleted` boolean

(2)实体类添加deleted字段

在逻辑删除字段上加入 @TableLogic 注解

@TableLogic
private Integer deleted;

(3)application.properties 加入配置

此为默认值,如果你的默认值和mp默认的一样,该配置可无

mybatis-plus.global-config.db-config.logic-delete-value=1   #默认被删除了就是1
mybatis-plus.global-config.db-config.logic-not-delete-value=0 #默认没删除了就是0

(4)测试逻辑删除

  • 测试后发现,数据并没有被删除,deleted字段的值由0变成了1
  • 测试后分析打印的sql语句,是一条update
  • 注意:被删除数据的deleted 字段的值必须是 0(也就是没被删除,这时才能被删),才能被选取出来执行逻辑删除的操作

在这里插入图片描述

条件构造器

MP提供的条件构造器,输入一些条件就可以快速进行单表的增删改查操作
注意,是单表。多表是无法操作的,只能写SQL语句

类图

在这里插入图片描述
Wrapper : 条件构造抽象类,最顶端父类

AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

QueryWrapper : Entity 对象封装操作类,不是用lambda语法

UpdateWrapper : Update 条件封装,用于Entity对象更新操作

AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。

LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper

LambdaUpdateWrapper : Lambda 更新封装Wrapper

注意:以下条件构造器的方法入参中的 column 均表示数据库字段

QueryWrapper使用

ge、gt、le、lt

ge:大于
gt:大于等于
le:小于
lt:小于等于

@Test
public void testSelect() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.ge("参数表字段名称", 参数值);//其余同理
    queryWrapper.ge("age", 28);//age字段大于28的
    queryWrapper.gt("age", 28);//age字段大于等于28的
    queryWrapper.le("age", 28);//age字段小于28的
    queryWrapper.lt("age", 28);//age字段小于等于28的
    List<User> users = userMapper.selectList(queryWrapper);
    System.out.println(users);
}

eq、ne

eq:等于
ne:不等于

注意:seletOne返回的是一条实体记录,当出现多条时会报错

@Test
public void testSelectOne() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("name", "Tom");//name字段等于Tom的
    queryWrapper.eq("name", "Tom");//name字段不等于Tom的
    User user = userMapper.selectOne(queryWrapper);
    System.out.println(user);
}

SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name = ?

like、likeLeft、likeRight

like:模糊匹配
likeLeft:左侧模糊匹配
likeRight:右侧模糊匹配

selectMaps返回Map集合列表

@Test
public void testSelectMaps() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    
    queryWrapper.like("name", "e");//只要是在name字段包含e的,就算匹配到位相当于(%e%)
    queryWrapper.likeLeft("email", "t");//只要是在email字段包以t结尾的,就算匹配到位相当于(t%)
    queryWrapper.likeRight("email", "t");//只要是在email字段包以t开头的,就算匹配到位相当于(%t)
    List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
    maps.forEach(System.out::println);
}

SELECT id,name,age,email,create_time,update_time,deleted,version

FROM user WHERE deleted=0 AND name LIKE ? AND email LIKE ?

orderByDesc、orderByAsc

orderByDesc:降序
orderByAsc:升序

@Test
public void testSelectListOrderBy() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.orderByDesc("id");//按字段降序
    queryWrapper.orderByAsc("id");//按字段升序
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
}

SELECT id,name,age,email,create_time,update_time,deleted,version

FROM user WHERE deleted=0 ORDER BY id DESC

LambdaQueryWrapper 使用

与QueryWrapper相比,LambdaQueryWrapper支持Lambda表达式
里面内置的方法和QueryWrapper 内的方法保持一致

@Test
public void testLambdaQuery() {
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(User::getAge,30);//对象::get属性 是Java8的写法
    queryWrapper.like(User::getName,"张");
    List<User> list = userMapper.selectList(queryWrapper);
    System.out.println(list);
}

SELECT id,name,age,email,create_time,update_time,deleted,version

FROM user WHERE deleted=0 AND age = ? AND name LIKE ?

MyBatisPlus封装Service层

在这里插入图片描述

创建service

public interface UserService extends IService<User> {
    
}

创建service实现类

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

底层封装了注入Mapper过程
在这里插入图片描述

方法调用测试

@SpringBootTest
class TestApplicationTests {

    //注入service
    @Autowired
    private UserService userService;
    
    //查询表所有数据
    @Test
    public void findAll() {
        List<User> userList = userService.list();
        for (User user:userList) {
            System.out.println(user);
        }
    }
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;