当前位置: 首页 > 工具软件 > mp-blog > 使用案例 >

MP基础入门

白飞飙
2023-12-01


前言

`Mybatis Plus


一、MybatisPlus简介

【1】MybatisPlus概述

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生(提供了快速使用mybatis的方式)

【2】MP特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

【3】开发MP版本

普通Maven项目下的依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
</dependency>
SpringBoot环境下的MP(项目中使用)
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

二、MP主键生成策略

【1】MP常用主键生成策略

MP提供的常用主键生成策略如下:

生成策略应用场景特点
IdType.AUTO数据库主键自增(确保数据库设置了 主键自增 否则无效)1.使用数据库自带的主键自增值;
2.数据库自增的主键值会回填到实体类中;
3.数据库服务端生成的;
IdType.ASSIGN_ID主键类型为number类型或数字类型String1.MP客户端生成的主键值;
2.生成的主键值是数字形式的字符串
3.主键对应的类型可以是数字类型或者数字类型的字符串
4.底层基于雪花算法,让数据库的唯一标识也参与id的生成运算,保证id在分布式环境下,全局唯一(避免id的主键冲突问题);
IdType.ASSIGN_UUID主键类型为 string(包含数字和字母组成)1.生成的主键值包含数字和字母组成的字符串;
2.注意事项:如果数据库中主键值是number类型的,可不可用
雪花算法

【2】注解@TableId介绍

@TableId注解作用:
	1.标识实体类中主键对应属性;
	2.定义主键生成策略;
@TableId使用:
	添加在实体类的主键对应的成员属性上即可;
@TableField:
	添加在数据库字段对应的实体类属性上
@TableName:
	实体类对应相对的表名

【3】普通列注解-@TableField

注解@TableField作用

​ 1.通过@TableField(“表列名”) 指定映射关系

​ 以下情况可以省略:

  • 名称一样
  • 数据库字段使用_分割,实体类属性名使用驼峰名称(自动开启驼峰映射)

​ 2.忽略某个字段的查询和插入 @TableField(exist = false)

// @TableName: 指定当前对象对应的数据库表
@TableName("tb_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {

    /**
     * @TableId: 指定当前表的主键
     *      value: 建立数据库主键字段与实体字段的对应关系
     *      type: 设置主键生成策略,
     *          IdType.NONE/ASSIGN_ID:默认情况下使用雪花算法
     *          IdType.AUTO:使用数据库的主键自增
     *          ASSIGN_UUID:使用UUID生成一个全局唯一字符串
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    private String userName;
    private String password;
    // 建立数据库字段与实体字段的对应关系 @TableField("与数据库字段名对应")
    @TableField("t_name")
    private String name;
    private Integer age;
    // 忽略此字段
    @TableField(exist = false)
    private String email;
}

【4】自动填充功能

(1)添加@TableField注解

@TableField(fill = FieldFill.INSERT) //插入数据时进行填充(填充时机可以选择(DEFAULT,INSERT,UPDATE, INSERT_UPDATE))
private String password;

(2)编写MyMetaObjectHandler

package cn.itcast.mp.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        Object password = getFieldValByName("password", metaObject);
        if(null == password){
            //字段为空,可以进行填充
            setFieldValByName("password", "123456", metaObject);
        }
    }
    @Override
    public void updateFill(MetaObject metaObject) {
    }
}

三、QueryWrapper常用API

eq( ) :  等于 =
ne( ) :  不等于 <>
gt( ) :  大于 >
ge( ) :  大于等于  >=
lt( ) :  小于 <
le( ) :  小于等于 <=
between ( ) :  BETWEEN 值1 AND 值2 
notBetween ( ) :  NOT BETWEEN 值1 AND 值2 
in( ) :  in
notIn( ) :not in

sql中反向查询eg:not like  != 等等,查询时是不会走索引的;

四、MP通过lambdaQueryWrapper单表的crud

1.插入

代码如下(示例):

 @Test
    public void testInsert(){
        User user = User.builder()
                .userName("qhj")
                .age(23)
                .password("2344")
                .email("1213@qq.com").build();
        int insert = userMapper.insert(user);

        if(insert > 0){
            System.out.println("添加成功!");
        }
        System.out.println(user);
    }

2.删除

代码如下(示例):

@Test
    public void testDeleteById(){
        /**
         * 根据id删除用户
         */
        //userMapper.deleteById(18);
        
        /**
         * 根据id批量删除
         */
       /** List list = new ArrayList<>();
        list.add(1);
	    list.add(19);
        userMapper.deleteBatchIds(list);
        
       */
        /**
         * 根据map删除
         */
        HashMap<String, Object> map = new HashMap<>();
        map.put("password",2344);
        map.put("user_name","qhj");
        userMapper.deleteByMap(map);
    }

3.修改

 @Test
    public void testUpdate(){
        User user = User.builder().userName("ryc").age(23).password("21324565").email("1324@qq.com").build();
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,"15");
        int i = userMapper.update(user,queryWrapper);
        System.out.println(i>0? "修改成功":"改失败");
    }

4.查

 /**
     *  LambdaQueryWrapper查询  并限定字段
     */
    @Test
    public void testLambda(){
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(User::getPassword,"123456")
                .like(User::getUserName,"赵")
                .in(User::getAge,26,28,29)
                .orderByDesc(User::getAge)
                .select("user_name","password","age","email");
        List<User> list = userMapper.selectList(queryWrapper);
        System.out.println(list);

    }

MP通过QueryWrapper实现分页查询操作

 /**
     * 分页查询
     */
    @Test
    public void testPage(){
        //创建分页对象
        IPage<User> page= new Page<>(1,3);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("age");
        IPage<User> userIPage= userMapper.selectPage(page,queryWrapper);

        //获取分页数据信息
        List<User> list = userIPage.getRecords();
        for(User user: list){
            System.out.println(user);
        }

        long current = page.getCurrent();
        System.out.println(current);
        long pages = page.getPages();
        System.out.println(pages);
        long size = page.getSize();
        System.out.println(size);
        long total = page.getTotal();
        System.out.println(total);

    }

五、MP实现Service封装


【1】说明


MybatisPlus为了开发更加快捷,对业务层也进行了封装,直接提供了相关的接口和实现类;
我们在进行业务层开发时,可以继承它提供的接口和实现类,使得编码更加高效;

【2】实现流程

1.定义一个服务扩展接口,该接口继承公共接口IService;

//在公共接口的基础上扩展
public interface UserService extends IService<User> {
}

2.定义一个服务实现类,该类继承ServiceImpl<Mapper,Entity>,并实现自定义的扩展接口;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
 类似资料: