MyBatisPlus-黑马-笔记

2023-10-27

MyBatisPlus


MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提供效率。

入门案例

package com.itheima.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserDao extends BaseMapper<User> {
}

MP的特性:

  • 无侵入:只做增强不做改变,不会对现有工程产生影响
  • 强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作
  • 支持 Lambda:编写查询条件无需担心字段写错
  • 支持主键自动生成
  • 内置分页插件

标准数据层开发

标准CRUD使用

在这里插入图片描述

package com.itheima;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class Myp01ApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testSave(){
        User user = new User();
        user.setName("wyuy");
        user.setAge(18);
        user.setPassword("123456");
        user.setTel("400000000");
        userDao.insert(user);
    }

    @Test
    void testUpdate(){
        User user = new User();
        user.setId(1L);
        user.setName("666");
        userDao.updateById(user);
    }

    @Test
    void testGetById(){
        User user = userDao.selectById(2L);
        System.out.println(user);
    }

    @Test
    void testDelete(){
        userDao.deleteById(1543586654940942338L);
    }

    @Test
    void testGetAll() {
        List<User> userList = userDao.selectList(null);
        System.out.println(userList);
    }

}

 		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        ======================
//lombok
//@Setter
//@Getter
//@ToString
//@NoArgsConstructor
//@AllArgsConstructor
//@EqualsAndHashCode
@Data
public class User {
    private Long id;
    private String name;
    private String password;
    private Integer age;
    private String tel;

}

分页

    @Test
    void testGetByPage(){
        //1 创建IPage分页对象,设置分页参数,1为当前页码,3为每页显示的记录数
        IPage page = new Page(1,2);
        //2 执行分页查询
        userDao.selectPage(page,null);
        //3 获取分页结果
        System.out.println("当前页码值:"+page.getCurrent());
        System.out.println("每页显示数:"+page.getSize());
        System.out.println("一共多少页:"+page.getPages());
        System.out.println("一共多少条数据:"+page.getTotal());
        System.out.println("数据:"+page.getRecords());
    }
package com.itheima.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor(){
        //1 创建MybatisPlusInterceptor拦截器对象
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //2 添加分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

DQL编程控制

条件查询

@SpringBootTest
class Myp02ApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testGetAll() {
        //方式一: 条件查询
        QueryWrapper qw = new QueryWrapper();
        qw.lt("age",18);
        List<User> userList = userDao.selectList(qw);
        System.out.println(userList);

//        //方式二: Lambda条件查询
        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.lambda().lt(User::getAge,10);
        List<User> userList = userDao.selectList(qw);
        System.out.println(userList);

        //方式三: Lambda条件查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.lt(User::getAge,10);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);

        //多条件
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        //10-30
        lqw.lt(User::getAge,30).gt(User::getAge,10);
        //<10  >30
        lqw.lt(User::getAge,10).or().gt(User::getAge,30);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);
    }

}

null判定

 //模拟页面传递过来的查询数据
        UserQuery uq = new UserQuery();
       // uq.setAge(10);
        uq.setAge2(30);

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//        lqw.lt(User::getAge,uq.getAge2());
        lqw.lt(null != uq.getAge2(),User::getAge,uq.getAge2());
        lqw.gt(null != uq.getAge(),User::getAge,uq.getAge());
//        lqw.gt(User::getAge,uq.getAge());
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);

查询投影

//查询投影
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.select(User::getId,User::getName,User::getAge);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);

        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.select("id","name","age");
        List<User> userList1 = userDao.selectList(qw);
        System.out.println(userList1);
QueryWrapper<User> qw = new QueryWrapper<User>();
        //计数
        qw.select("count(*) as count, tel");
        //分组
        qw.groupBy("tel");
        List<Map<String,Object>> userList2 = userDao.selectMaps(qw);
        System.out.println(userList2);
@SpringBootTest
class Mybatisplus02DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll(){
QueryWrapper<User> lqw = new QueryWrapper<User>();
//lqw.select("count(*) as count");
//SELECT count(*) as count FROM user
//lqw.select("max(age) as maxAge");
//SELECT max(age) as maxAge FROM user
//lqw.select("min(age) as minAge");
//SELECT min(age) as minAge FROM user
//lqw.select("sum(age) as sumAge");
//SELECT sum(age) as sumAge FROM user
lqw.select("avg(age) as avgAge");
//SELECT avg(age) as avgAge FROM user
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
}
}

查询条件

等值查询

//条件查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.eq(User::getName,"Jerry").eq(User::getPassword,"jerry");
        User user = userDao.selectOne(lqw);
        System.out.println(user);

范围查询

// 范围查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        //使用lt()、le()、gt()、ge()、between()进行范围查询
        lqw.between(User::getAge,10,30);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);
  • gt():大于(>)
  • ge():大于等于(>=)
  • lt():小于(<)
  • lte():小于等于(<=)
  • between():between? and ?

模糊查询

 // 模糊查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.like(User::getName,"J");
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);
  • like():前后加百分号,如 %J%
  • likeLeft():前面加百分号,如 %J
  • likeRight():后面加百分号,如 J%

映射匹配兼容性

  • 问题1:表字段与编码属性设计不同步
    MP给我们提供了一个注解@TableField ,使用该注解可以实现模型类属性名和表的列名之间的映射关
  • 问题2:编码中添加了数据库中未定义的属性
    具体的解决方案用到的还是@TableField 注解,它有一个属性叫exist ,设置该字段是否在数据库表中存在,如果设置为false则不存在,生成sql语句查询的时候,就不会再查询该字段了。
  • 问题3:采用默认查询开放了更多的字段查看权限
    解决方案是@TableField 注解的一个属性叫select ,该属性设置默认是否需要查询该字段的值,true(默认值)表示默认查询该字段,false表示默认不查询该字段。
  • 问题4:表名与编码开发设计不同步
    解决方案是使用MP提供的另外一个注解@TableName 来设置表与模型类之间的对应关系。
package com.itheima.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("tbl_user")
public class User {
    private Long id;
    private String name;
    @TableField(value = "pwd",select = false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist = false)
    private Integer online;
}

DML编程控制

id生成策略控制

  • NONE:不设置id生成策略,MP不自动生成,约等于INPUT,所以这两种方式都需要用户手动设置,但是手动设置第一个问题是容易出现相同的ID造成主键冲突,为了保证主键不冲突就需要做很多判定,实现起来比较复杂
  • AUTO:数据库ID自增,这种策略适合在数据库服务器只有1台的情况下使用,不可作为分布式ID使用
  • ASSIGN_UUID:可以在分布式的情况下使用,而且能够保证唯一,但是生成的主键是32位的字符串,长度过长占用空间而且还不能排序,查询性能也慢
  • ASSIGN_ID:可以在分布式的情况下使用,生成的是Long类型的数字,可以排序性能也高,但是生成的策略和服务器时间有关,如果修改了系统时间就有可能导致出现重复主键
  • 综上所述,每一种主键策略都有自己的优缺点,根据自己项目业务的实际情况来选择使用才是最明 智的选择。
package com.itheima.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("tbl_user")
public class User {
//    @TableId(type = IdType.AUTO)
//    @TableId(type = IdType.INPUT)
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    @TableField(value="pwd",select=false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist=false)
    private Integer online;
}

# mp日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
   banner: false
   db-config:
    id-type: assign_id
    table-prefix: tbl_

多记录操作

@Test
    void testDelete(){
        List<Long> list = new ArrayList<>();
        list.add(1543586654940942339L);
        list.add(1543586654940942340L);
        list.add(1543849463314489346L);
        userDao.deleteBatchIds(list);

		list.add(1L);
        list.add(2L);
        list.add(3L);
        userDao.selectBatchIds(list);
    }

逻辑删除

 //逻辑删除字段,标记当前记录是否删除
    @TableLogic(value = "0",delval = "1")
    private Integer deleted;
    logic-delete-field: deleted
    logic-delete-value: 1
    logic-not-delete-value: 0

乐观锁

package com.itheima.domain;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

@Data
//@TableName("tbl_user")
public class User {
//    @TableId(type = IdType.AUTO)
//    @TableId(type = IdType.INPUT)
//    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    @TableField(value="pwd",select=false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist=false)
    private Integer online;
    //逻辑删除字段,标记当前记录是否删除
//    @TableLogic(value = "0",delval = "1")
    private Integer deleted;

    @Version
    private Integer version;
}

拦截器

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor(){
        MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
        mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mpInterceptor;
    }
}

模拟

//模拟
        User user = userDao.selectById(3L); //version=3

        User user2 = userDao.selectById(3L);//version=3
        //2.将要修改的属性逐一设置进去
        user.setName("Jockaaa");
        userDao.updateById(user);

        user2.setName("Jockbbb");
        userDao.updateById(user2);

代码生成器实现

<!--代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--velocity模板引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
package com.itheima;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;

public class CodeGenerator {
    public static void main(String[] args) {
        //1.获取代码生成器的对象
        AutoGenerator autoGenerator = new AutoGenerator();
//设置数据库相关配置
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db? serverTimezone=UTC");
                dataSource.setUsername("root");
        dataSource.setPassword("123456");
        autoGenerator.setDataSource(dataSource);
//设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/myp_04/src/main/java"); //设置代码生成位置
                globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("黑马程序员"); //设置作者
        globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);
//设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setEntity("domain"); //设置实体类包名
        packageInfo.setMapper("dao"); //设置数据层包名
        autoGenerator.setPackageInfo(packageInfo);
//策略设置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tbl_user"); //设置当前参与生成的表名,参数为可变参数
        strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称,模块名 =数据库表名 - 前缀名 例如: User = tbl_user - tbl_
        strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格
        strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名
        strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名
        strategyConfig.setEntityLombokModel(true); //设置是否启用lombok
        autoGenerator.setStrategy(strategyConfig);
//2.执行生成操作
        autoGenerator.execute();
    }
}

在这里插入图片描述


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatisPlus-黑马-笔记 的相关文章

随机推荐

  • matlab 批量读取execl(csv)文件

    一直没时间整理自己写的垃圾代码 如今代码乱的一团糟 今天把matlab读取excel文件拿出来 需要根据数据格式稍作修改就可以用 读取核心的语句莫过这两句 dir csvread 文件下载 read csvdata author enjoy
  • NoSQL和关系型数据库的区别和使用场景

    NoSQL和关系型数据区别 文章目录 NoSQL和关系型数据区别 一 关系型数据库遵循ACID规则 1 A Atomicty 原子性 2 C Consistency 一致性 3 I Isolation 独立性 4 D Durability
  • Linux笔记

    命令 提供一定功能的工具 ssh 提供远程登录功能 参数 命令的作用对象 193 3 3 3 远程登录的作用主机 选项 命令作用的方式 p 22 通过22端口登录到主机 电脑 外壳shell 内核 输入输出设备 用户 提供意愿 转化为命令与
  • nestjs:Cannot read property ‘retryAttempts‘ of undefined

    描述 Cannot read property retryAttempts of undefined 解决 检查数据库的配置是否有问题
  • 日期格式化方法

    时间格式化 有时候我们会用到时间的展示 时间的展示种类也是各种各样 对于不用的产品需要不同的样式 这时候就需要我们做一下时间的格式化处理 下面是一种常见的日期显示方式 代码如下 格式化时间 param String date 原始时间格式
  • 23种设计模式(七) —— 手写实现 Builder 模式 (组装复杂实例)

    文章目录 一 Builder 模式 二 示例 2 1 示例实现功能 2 2 具体实现 2 3 运行结果 三 Builder 模式中登场的角色 四 原文链接 Author Gorit Date 2021 10 24 2021年发表博文 22
  • 你还不知道的简历准备及面试技巧

    最近已经不止听到一位朋友吐槽工作不好找了 一波又一波的裁员潮 ChatGPT 等人工智能工具的爆火 1158 万的应届毕业生 都让今年 IT 行业的就业状况雪上加霜 面对愈加激烈的求职竞争 作为程序员 应该掌握哪些面试技巧 本文邀请了 2
  • Internet的路由选择协议(RIP、OSPF)

    有关路由选择协议的几个概念 1 理想的路由算法 路由选择协议的核心就是路由算法 即路由器通过算法来获得路由 一个理想的路由算法应该具有以下的特点 算法必须是正确和完整的 算法在计算上应简单 算法应能适应通信量和网络拓扑的变化 算法应具有稳定
  • OSG仿真案例(9)——JY61陀螺仪控制飞机姿态

    前言 在调试osg中模型运动姿态时 总觉得直观性不够强 所以有了想买个硬件陀螺仪 当时并不知道这个硬件应该叫什么名字 在淘宝搜索角度传感器的 几个驱动 1 CH340驱动 这个驱动在自带资源包里面 但是不可以用 只能自己在网上找 发现是型号
  • 数据库JDBC --- Java Database Connectivity

    数据库JDBC Java Database Connectivity 关于JDBC 什么是JDBC JDBC的组成 JDBC API JDBC的数据类型 创建JDBC的步骤 常用属性 Result Set ResultSetMetaData
  • Oracle使用IN 不能超过1000问题

    1 美图 2 背景 是写代码的是遇到问题 ORA 01795 列表中的最大表达式数为 1000 虽然使用了 批量处理解决了问题 但是因为是使用了myIbatis spring boot oracle 我不太想 直接改代码 想通过修改myIb
  • 25行jQuery代码实现轮播图

    对于刚刚学习前端的同学来说 做一个轮播图是非常不容易的 今天我就将自己的心得跟和大家分享一下 实现轮播图有很多方法 今天我们就讲其中一种方法 让图片显示在一行内 然后让图片有规律的向左移动 大家可以先看看效果http www shareko
  • sqli-labs (less-24)

    sqli labs less 24 进入24关 输入用户名和密码 登入后会显示你的用户名 下面的输入框就是改密码 我在输入用户名和密码的位置试了很多次 发现用户名和密码的位置是没有注入点的 这里我们先点击右下角的 New User clic
  • Flutter-设置分割线Divider

    Divider height 1 0 indent 0 0 color MyColors color gray 150
  • PowerBI开发 第十八篇:行级安全(RLS)

    PowerBI可以通过RLS Row level security 限制用户对数据的访问 过滤器在行级别限制数据的访问 用户可以在角色中定义过滤器 通过角色来限制数据的访问 在PowerBI Service中 workspace中的memb
  • uniapp getUserProfile:fail invalid session

    uniapp uni getUserProflie 部分安卓手机调不起来弹窗 错误原因 应该在uni getUserProflie之前调用uni login 但是直接在uni login的成功回调里面调用uni getUserProflie
  • 九、Linux系统中的文件传输

    九 Linux系统中的文件传输 实验准备 两台可以通信的主机 systemctl disable firewalld systemctl stop firewalld 9 1 scp命令 上传 scp 本地文件 远程主机用户 远程主机ip
  • SDUT 2023 summer team contest(for 22) - 14

    A Amanda Lounges 题意 有n个机场 m条边 对于每个机场可能需要等候室也可能不需要 如果输入2 代表路线连接的两个机场都需要建立 输入1 代表路线连接的其中一个机场建立 必须 输入0代表路线连接的两个机场都不可以建立 问你最
  • 关于https页面使用ifream嵌套http页面问题解决

    之前公司项目 部署的时候协议用的http 然后前几天把协议换成了https的 当时也没仔细测试 觉得没什么问题 然后 昨天发现其中的某个播放视频的页面显示不出来了 报错信息 接着上这个页面的部分代码 就是这个页面用ifram嵌套了另一个项目
  • MyBatisPlus-黑马-笔记

    MyBatisPlus 目录 入门案例 标准数据层开发 标准CRUD使用 分页 DQL编程控制 条件查询 null判定 查询投影 查询条件 等值查询 范围查询 模糊查询 映射匹配兼容性 DML编程控制 id生成策略控制 多记录操作 逻辑删除