Mybatis-Plus笔记

1.MP基础

1.1 MP常见注解

  • @TableName("指定表明")
java 复制代码
@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类型或数字类型String 1.MP客户端生成的主键值; 2.生成的主键值是数字形式的字符串 3.主键对应的类型可以是数字类型或者数字类型的字符串 4.底层基于雪花算法,让数据库的唯一标识也参与id的生成运算,保证id在分布式环境下,全局唯一(避免id的主键冲突问题);
IdType.ASSIGN_UUID 主键类型为 string(包含数字和字母组成) 1.生成的主键值包含数字和字母组成的字符串; 2.注意事项:如果数据库中主键值是number类型的,可不可用

例子:

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

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

    例子:

    java 复制代码
    @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实现分页查询

  • 配置分页拦截器

    java 复制代码
    @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()

    java 复制代码
    /**
      * 分页查询:
      *  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

    text 复制代码
    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查询数据时,表的列名硬编码书写,后期一旦表结构更改,则会带来很大的修改工作量,维护性较差;
  • 代码实现

    java 复制代码
    @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集合删除:

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

      java 复制代码
      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);
    • 根据条件删除

      java 复制代码
      int i = userMapper.delete(wrapper);
  • 更新方法

    • 条件更新 方式一

      java 复制代码
        /**
           * 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);
    • 条件更新 方式二

      java 复制代码
        /**
           * 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对象

    java 复制代码
    //@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 复制代码
    <?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>
  • 业务实现

    java 复制代码
    /**
         * @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<实体类>接口

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

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

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

  • getOne 查询一条数据

    java 复制代码
        @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 根据条件批量查询

    java 复制代码
        @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 根据条件批量查询并分页

    java 复制代码
        @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 保存单条操作

    java 复制代码
        @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 批量保存

    java 复制代码
        @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删除操作

    java 复制代码
        @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更新数据

    java 复制代码
        @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 批量更新

    java 复制代码
        @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)

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

相关推荐
我爱挣钱我也要早睡!2 小时前
Java 复习笔记
java·开发语言·笔记
汇能感知6 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun7 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao7 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾7 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT8 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
ST.J8 小时前
前端笔记2025
前端·javascript·css·vue.js·笔记
Suckerbin8 小时前
LAMPSecurity: CTF5靶场渗透
笔记·安全·web安全·网络安全
小憩-9 小时前
【机器学习】吴恩达机器学习笔记
人工智能·笔记·机器学习
UQI-LIUWJ9 小时前
unsloth笔记:运行&微调 gemma
人工智能·笔记·深度学习