Mybatis-Plus笔记

news2025/3/18 3:15:39

1.MP基础

1.1 MP常见注解

  • @TableName(“指定表明”)
@TableName("tb_user") // 指定表名
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    private Long id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}
  • @TableId(value=“表中主键名称”,type=“主键生成策略”)
生成策略应用场景特点
IdType.AUTO数据库主键自增(确保数据库设置了 主键自增 否则无效)1.使用数据库自带的主键自增值; 2.数据库自增的主键值会回填到实体类中; 3.数据库服务端生成的;
IdType.ASSIGN_ID主键类型为number类型或数字类型String1.MP客户端生成的主键值; 2.生成的主键值是数字形式的字符串 3.主键对应的类型可以是数字类型或者数字类型的字符串 4.底层基于雪花算法,让数据库的唯一标识也参与id的生成运算,保证id在分布式环境下,全局唯一(避免id的主键冲突问题);
IdType.ASSIGN_UUID主键类型为 string(包含数字和字母组成)1.生成的主键值包含数字和字母组成的字符串; 2.注意事项:如果数据库中主键值是number类型的,可不可用

例子:

//指定表中的主键名 以及 指定主键自增的生成策略
@TableId(value = "user_id",type = IdType.AUTO)
private Integet userId;
  • @TableField

    • 指定表中普通字段与实体类属性之间的映射关系;
    • 忽略实体类中多余属性与表中字段的映射关系(@TableField(exist = false))

    例子:

    @TableName("tb_user")
    @Data
    public class User {
        //设置id生成策略:AUTO 数据库自增
        @TableId(type = IdType.AUTO)
        private Long id;
        @TableField("user_name")
        private String userName;
        //增删改查操作时,忽略该属性
        @TableField(exist = false)
        private String address;
    }
    

1.2 MP基本使用流程

  1. 引入MyBatis-Plus依赖
  2. 使用MP注解修饰pojo实体类
  3. 编写Mapper接口继承BaseMapper<实体类>接口
  4. 使用LambdaQueryWrapper保存条件信息
  5. 通过mapper接口调用BaseMapper自带的增删改查方法(可以输入分页条信息以及条件信息)

1.3 MP实现分页查询

  • 配置分页拦截器

    @Configuration
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
            // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
            // paginationInterceptor.setOverflow(false);
            // 设置最大单页限制数量,-1不受限制
            paginationInterceptor.setMaxLimit(-1L);
            interceptor.addInnerInterceptor(paginationInterceptor);
            return interceptor;
        } 
    }
    
  • 实现分页查询

    其中selectPage方法需要传入两个参数,第一个是分页对象,第二个是条件对象

    获取分页查询后数据的方法:page.getRecords()

    获取总页数:page.getPages()

    获取总记录数:page.getTotal()

    /**
      * 分页查询:
      *  1. 当前页码:currentPage
      *  2. 每页显示条数:size
      *  注意:使用mp的分页要设置一个拦截器!!!
    */
    @Test
    public void testSelectPage() {
      int current = 1;//当前页码
      int size = 2;//每页显示条数
      IPage<User> page = new Page(current,size);
      userMapper.selectPage(page,null);
      List<User> records = page.getRecords();//当前页的数据
      long pages = page.getPages();//总页数 2
      long total = page.getTotal();//总记录数 4
      System.out.println(records);
      System.out.println(pages);
      System.out.println(total);
    }
    

1.4 配置条件对象LambdaQueryWrapper

  • 常用API

    eq( ) :  等于 =
    ne( ) :  不等于 <> 或者 !=
    gt( ) :  大于 >
    ge( ) :  大于等于  >=
    lt( ) :  小于 <
    le( ) :  小于等于 <=
    between ( ) :  BETWEEN 值1 AND 值2 
    notBetween ( ) :  NOT BETWEEN 值1 AND 值2 
    in( ) :  in
    notIn( ) :not in
    
  • 为什么不使用QuertWrapper?

    1. 使用QueryWrapper查询数据时需要手写对应表的列名信息,及其容易写错,开发体验不好;
    2. 使用QueryWrapper查询数据时,表的列名硬编码书写,后期一旦表结构更改,则会带来很大的修改工作量,维护性较差;
  • 代码实现

    @Test
    public void testWrapper4() throws Exception{
      // LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
      LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
    
      //        wrapper.like("user_name", "%伤%")
      //                .eq("password","123456")
      //                .ge("age", 28)
      //                .between("age",29 , 39);  // 包含边界值
      wrapper.like(User::getUserName, "%伤%")  //模糊查询
        .eq(User::getPassword, "123456")  
        .ge(User::getAge, 28)
        .between(User::getAge, 29, 39)
        .orderByDesc(User::getAge)  //排序查询
        .select(User::getId, User::getUserName);   //限定字段查询
      List<User> users = userMapper.selectList(wrapper);
      System.out.println(users);
    }
    

1.5 增删改查 基础方法

  • 查询方法

    • List users = userMapper.selectList(wrapper);
  • 插入方法

    • int insert = userMapper.insert(user);
  • 删除方法

    • 根据id删除: int count = userMapper.deleteById(8L);

    • 根据id集合删除:

       List ids = new ArrayList();
              ids.add(6);
              ids.add(7);
      userMapper.deleteBatchIds(ids);
      
    • 根据map构造条件删除:

      Map<String, Object> map = new HashMap<>();
      
      //delete from tb_user where user_name = ? and age = ?
      map.put("user_name","itcast");
      map.put("age","18");
      
      userMapper.deleteByMap(map);
      
    • 根据条件删除

      int i = userMapper.delete(wrapper);
      
  • 更新方法

    • 条件更新 方式一

        /**
           * UPDATE tb_user SET t_name=? WHERE (id = ?)
           */
        // 参数1: 最新的值
        User user = new User();
        user.setUserName("张三丰");
      
        // 参数2:更新时条件
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
        wrapper.eq(User::getId, 15);
      
        int update = userMapper.update(user, wrapper);
      
    • 条件更新 方式二

        /**
           * UPDATE tb_user SET t_name=?, user_name=? WHERE (id = ?)
        */
        // 参数1: 最新的值
        // 参数2:更新时条件
        LambdaUpdateWrapper<User> wrapper = Wrappers.<User>lambdaUpdate();
        wrapper.eq(User::getId, 15)
          .set(User::getUserName, "张三丰666")
          .set(User::getName,"zsf666");
      
        int update = userMapper.update(null, wrapper);
      

1.6 自定义查询接口(例子实现分页查询)

  • 自定义Mapper接口方法传入Page对象

    //@Mapper
    public interface UserMapper extends BaseMapper<User> {
        /**
         * 查询大于指定id的用户信息,并分页查询实现
         * @param page
         * @param id
         * @return
         */
        IPage<User> findGtIdByPage(IPage<User> page, @Param("id") Long id);
    }
    
  • 定义xml映射文件

    <?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.itheima.mapper.UserMapper">
    
        <select id="findGtIdByPage" resultType="com.itheima.pojo.User">
            select * from tb_user where id > #{id}
        </select>
    </mapper>
    
  • 业务实现

    /**
         * @Description 自定义sql分页查询实现
         */
    @Test
    public void test(){
        IPage<User> page=new Page<>(2,3);
        IPage<User> users = userMapper.findGtIdByPage(page, 3l);
        System.out.println(users.getRecords());
        System.out.println(user.getPages());
        System.out.println(user.getTotal());
    }
    

2.MP实现Service封装

2.1 基本流程

  • 定义Service接口继承IService<实体类>接口

    //在公共接口的基础上扩展
    public interface UserService extends IService<User> {
    }
    
  • 定义Service实现类 同时继承ServiceImpl<mapper接口,实体类>

    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    }
    
  • 在ServiceImpl业务类直接调用方法实现持久层操作

2.2 MP封装Servie实现各种操作演示

  • getOne 查询一条数据

        @Test
        public void test2(){
            LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
            wrapper.gt(User::getAge,20);
            User one = userService.getOne(wrapper);
            System.out.println(one);
        }
    
  • list 根据条件批量查询

        @Test
        public void test3(){
            LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
            wrapper.gt(User::getAge,20);
            List<User> list = userService.list(wrapper);
            System.out.println(list);
        }
    
  • page 根据条件批量查询并分页

        @Test
        public void test4(){
            LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
            wrapper.gt(User::getAge,20);
            //构建分页对象
            IPage<User> page=new Page<>(2,3);
            userService.page(page,wrapper);
            System.out.println(page.getRecords());
        }
    
  • save 保存单条操作

        @Test
        public void test5(){
            User user1 = User.builder().name("wangwu").userName("laowang4").
                    email("444@163.com").age(20).password("333").build();
            boolean isSuccess = userService.save(user1);
            System.out.println(isSuccess?"保存成功":"保存失败");
        }
    
  • saveBatch 批量保存

        @Test
        public void test6(){
            User user2 = User.builder().name("wangwu2").userName("laowang2").
                    email("444@163.com").age(20).password("333").build();
            User user3 = User.builder().name("wangwu3").userName("laowang3").
                    email("444@163.com").age(20).password("333").build();
            boolean isSuccess = userService.saveBatch(Arrays.asList(user2, user3));
            System.out.println(isSuccess?"保存成功":"保存失败");
        }
    
  • removeById 根据id删除操作

        @Test
        public void test8(){
            LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
            wrapper.gt(User::getId,12)
                    .gt(User::getAge,20);
            boolean remove = userService.remove(wrapper);
            System.out.println(remove);
        }
    
  • updateById 根据id更新数据

        @Test
        public void test9(){
            //UPDATE tb_user SET password=?, t_name=? WHERE id=?
            User user2 = User.builder().name("wangwu2").password("333").id(3l).build();
            boolean success = userService.updateById(user2);
            System.out.println(success);
        }
    
  • update 批量更新

        @Test
        public void test10(){
            LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(User.class);
            //UPDATE tb_user SET age=? WHERE (id IN (?,?,?))
            wrapper.in(User::getId,Arrays.asList(1l,3l,5l)).set(User::getAge,40);
            boolean update = userService.update(wrapper);
            System.out.println(userService);
        }
    

3.MP代码生成器

3.1 开发现状

开发中当有一个新的业务要实现时,通常我们需要构建一下信息:

  • 定义PO类

    数据库表和实体类的映射 Java Bean,打各种mp的注解。

  • 定义DAO层

    需要编写接口 Mapper ,接口 Mapper 需要去继承 MP 中的 BaseMapper 接口。

  • 定义Service层

    编写 Service 层接口和实现类。

    业务接口需要去继承 MP 中的 IService,业务实现类需要继承 MP 中的 ServiceImpl 和 实现业务接口。

  • 定义Controller层

    编写 Controller 并标注 Spring MVC 中的相关注解。

    显然上述存在固定的流程,且存在大量重复操作,you now 代码价值低且没效率!

针对目前开发的现状,MP的代码生成器就可以一展身手了;

通过MP代码生成器可以生成模板性的代码,减少手工操作的繁琐,使开发人员聚焦于业务开发之上,提升开发效率;

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

3.2 代码生成

gitee开源链接:https://gitee.com/jitheima/mp_generator.git

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

l 和 实现业务接口。

  • 定义Controller层

    编写 Controller 并标注 Spring MVC 中的相关注解。

    显然上述存在固定的流程,且存在大量重复操作,you now 代码价值低且没效率!

针对目前开发的现状,MP的代码生成器就可以一展身手了;

通过MP代码生成器可以生成模板性的代码,减少手工操作的繁琐,使开发人员聚焦于业务开发之上,提升开发效率;

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

3.2 代码生成

gitee开源链接:https://gitee.com/jitheima/mp_generator.git

[外链图片转存中…(img-UvoABTz7-1716631588708)]

说明:以后在项目中使用时,先在本工程生成,然后就可以把代码拷贝到对应的项目目录中使用了;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1694608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

输入一串字符串,前中后都有*号,去掉字符串中间和后面的*号,保留前面的*号和字母

#include <stdio.h> void fun(char* a) {//***df**fr*fg***int i 0, j 0,n0,m0;char* p;p a;while (p[i] ! \0){i;//i是一共的字符的个数}printf("%d\n",i);while (a[n] *){n;//计算字母前的*的个数}printf("%d\n", n);m n;for (j n; j < …

【排序算法】快速排序(四个版本以及两种优化)含动图)

制作不易&#xff0c;三连支持一下吧&#xff01;&#xff01;&#xff01; 文章目录 前言一.快速排序Hoare版本实现二.快速排序挖坑法版本实现三.快速排序前后指针版本实现四.快速排序的非递归版本实现五.两种优化总结 前言 前两篇博客介绍了插入和选择排序&#xff0c;这篇博…

nuxt: generate打包后访问资源404问题

现象 使用Nuxt.js开发的个人页面&#xff0c;部署到nginx服务器中&#xff0c;/_nuxt/*.js、/_nuxt/*.css等静态问题不能访问&#xff0c;提示404错误。 而我们的这些资源文件是存在的。 解决方法 加上此处代码进行上下文配置 baseURL: /nuxt/ 此时在nginx配置 /nuxt 代理 lo…

使用 Django Admin 进行高效的后台管理

文章目录 创建超级用户注册模型到 Admin 后台自定义 Admin 后台界面定制 Admin Actions结语 当使用 Django Admin 进行后台管理时&#xff0c;开发者可以通过简单的配置和定制来满足项目的需求。可以根据不同的模型和数据结构&#xff0c;轻松地创建和管理数据条目、进行搜索和…

微信小程序--微信开发者工具使用小技巧(3)

一、微信开发者工具使用小技巧 1、快速创建小程序页面 在app.json中的pages配置项&#xff0c;把需要创建的页面填写上去 2、快捷键使用 进入方式 1&#xff1a; 文件–>首选项–> keyboard shortcuts 进入快捷键查看与设置 进入方式 2&#xff1a; 设置–>快捷键…

C#应用的用户配置窗体方案 - 开源研究系列文章

这次继续整理以前的代码。本着软件模块化的原理&#xff0c;这次笔者对软件中的用户配置窗体进行剥离出来&#xff0c;单独的放在一个Dll类库里进行操作&#xff0c;这样在其它应用程序里也能够快速的复用该类库&#xff0c;达到了快速开发软件的效果。 笔者其它模块化应用的例…

AcW木棒-XMUOJ恢复破碎的符咒木牌-DFS与剪枝

题目 思路 话不多说&#xff0c;直接上代码 代码 /* AcW木棒-XMUOJ恢复破碎的符咒木牌 搜索顺序&#xff1a;从小到大枚举最终的长度 len从前往后依次拼每根长度为len的木棍 优化&#xff1a; 1.优化搜索顺序&#xff1a;优先选择深度短的来搜索&#xff0c;故从大到小去枚…

java —— 封装、继承、接口和多态

一、封装 封装是将数据和操作这些数据的方法整合成一个类。在这个类中&#xff0c;用 private 修饰符将某些数据隐藏起来&#xff0c;只通过特定的方法实现这些数据的访问和修改&#xff0c;以此实现数据的完整和安全性。 封装的步骤&#xff1a; 二、继承 继承是指把子类共有…

深度学习之基于Matlab编写BP神经网络汉字识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着信息技术的快速发展&#xff0c;文本识别和处理技术在各个领域中扮演着越来越重要的角色。…

helloworld 可执行程序得到的过程

// -E 预处理 开发过程中可以确定某个宏 // -c 把预处理 编译 汇编 都做了,但是不链接 // -o 指定输出文件 // -I 指定头文件目录 // -L 指定链接库文件目录 // -l 指定链接哪一个库文件 #include <stdio.h> #include <stdlib.h> #include <string.h>int mai…

Java代码审计-XSS审计

一、漏洞简介 XSS是Cross Site Scripting的缩写&#xff0c;意为"跨站脚本攻击"&#xff0c;为了避免与层叠样式表(Cascading Style Sheet&#xff0c;CSS)的缩写混淆&#xff0c;故将跨站脚本攻击缩写为XSS。XSS是一种针对网站应用程序的安全漏洞攻击技术&#xff…

SPI通信(STM32)

一、SPI通信 &#xff11;、SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线 &#xff12;、四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff09;、MOSI&#xff08;Master Output Slave Input&#xff09;、MIS…

5.18 TCP机械臂模拟

#include <netinet/tcp.h>//包含TCP选项的头文件 #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/input.h>//读取输入事件 #include <sys/types.h> #include <sys/stat.h&…

截图工具PixPin(比Snipaste更强大)

PixPin官网链接&#xff1a;https://pixpinapp.com/ 最近新出的一款截图工具PixPin&#xff0c;比Snipaste功能多一些。在Snipaste功能基础上&#xff0c;还支持长截图&#xff0c;截动图&#xff0c;文本识别。

第一篇【传奇开心果系列】Python的跨平台开发工具beeware技术点案例示例:使用beeware实现跨平台开发,从hello world开始

传奇开心果博文系列 系列博文目录Python的跨平台开发工具beeware技术点案例示例系列 博文目录前言一、BeeWare套件主要功能介绍二、Toga相对于其他Python UI库具有的优势介绍三、使用toga开发安卓手机应用hello world步骤和示例代码四、使用toga写一个iOS 苹果手机应用hello wo…

探索 Vue 3 的动态布局解决方案:Grid Layout Plus

探索 Vue 3 的动态布局解决方案&#xff1a;Grid Layout Plus 文章目录 探索 Vue 3 的动态布局解决方案&#xff1a;Grid Layout PlusGrid Layout Plus 概览0、元信息1、核心特性可拖拽部件可缩放部件静态部件边界检查避免重建栅格可序列化和还原的布局自动化 RTL 支持响应式设…

插件:NGUI

一、版本 安装完毕后重启一下即可&#xff0c;否则可能创建的UI元素不生效 二、使用 Label文字 1、创建Canvs 2、只有根节点的这些脚本全部展开才能鼠标右键创建UI元素 3、选择字体 Sprite图片 1、选择图集 2、选择图集中的精灵 Panel容器 用来装UI的容器&#xff0c;一般UI…

【c语言】了解指针,爱上指针(5)

了解指针&#xff0c;爱上指针&#xff08;5&#xff09; 回调函数qsort函数冒泡排序模拟实现qsort函数 回调函数 回调函数&#xff1a;就是一个通过函数指针调用的函数。 把函数的指针作为参数传给另一个函数&#xff0c;当这个指针被用来调用指向的函数时&#xff0c;此时被…

K8s的常用命令以及yaml文件的创建

目录 一、声明式管理方法&#xff1a;YAML文件 1、yaml文件简介 2、yaml和json的主要区别&#xff1a; 3、YAML的语法格式 4、yaml文件组成部分 ①控制器定义 5、查看api资源版本标签 6、编写nginx-deployment.yaml资源配置清单 6.1创建资源对象 6.2查看创建的pod资源…

vue3 使用css实现一个弧形选中角标样式

文章目录 1. 实现效果2. 实现demo 在前端开发中&#xff0c;ui同学经常会设计这样的样式&#xff0c;用于区分选中的状态 下面抽空简单些了一下&#xff0c;记录下&#xff0c;后面直接复制用 1. 实现效果 实现一个菜单切换&#xff0c;右下角有个角标的样式 2. 实现demo 主要…