MyBatisPlus详解

一、快速入门

1.入门案例

2.常见注解

(1)@TableName:用来指定表名

(2)@TableId:用来指定表中的主键字段信息

  • @TableId注解中有一个属性叫做type,它是一个枚举类型(AUTO、INPUT、ASSIGN_ID)

(3)@TableField:用来指定表中的普通字段信息

  • 注1:上面三个注解主要用于当数据库表中的表名、id名、普通字段不一致时进行使用
  • 注2:如果属性值和数据库表中字段名字能够对应,但是该字段是is开头且是布尔类型的,也要用注解指明对应的字段(底层是基于反射的,会将is去掉作为变量名,导致字段不一致问题)
  • 注3:当出现实体类的字段与数据库中的关键字重复的时候,也要加上@TableField,例如order
  • 注4:如果实体类中的字段在表中没有对应,那么应该加上@TableField(exist = false)标记该字段不存在
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@TableName("user")
public class User {

    /**
     * 用户id
     */
    @TableId
    private Long id;

    /**
     * 用户名
     */
    @TableField(value = "username")
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 注册手机号
     */
    private String phone;

    /**
     * 详细信息
     */
    private String info;

    /**
     * 使用状态(1正常 2冻结)
     */
    private Integer status;

    /**
     * 账户余额
     */
    private Integer balance;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}

3.常见配置

二、核心功能

1.条件构造器

(1)继承关系

(2)AbstractWrapper:抽象类,用于构建复杂的 SQL 查询条件,它提供了一系列方法来方便地拼接、组合查询条件,如等于、不等于、大于、小于、模糊查询、范围查询等,使得开发者可以更加灵活地编写数据库查询逻辑,而无需手动编写大量的 SQL 条件语句

(3)UpdateWrapper:对更新操作进行了扩展(可以用set自定义sql)

  • 需求:更新id为1,2,4的用户的余额,扣200
  • 实现SQL:UPDATE user SET balance = balance -200 WHERE id in(1, 2, 4)
  •     @Test
        void testUpdateWrapper() {
            List<Long> ids = List.of(1L, 2L, 4L);
            UpdateWrapper<User> wrapper = new UpdateWrapper<>();
            wrapper.setSql("balance = balance - 200");
            wrapper.in("id", ids);
            userMapper.update(null, wrapper);
        }

(4)QueryWrapper:对查询相关条件进行了扩展

(5)LambdaUpdateWrapper 以及 LambdaQueryWrapper 功能和UpdateWrapper 、 QueryWrapper功能是一样,它增加了Lambda表达式的使用

  • 需求:更新id为1,2,4的用户的余额,扣200
  • 实现SQL:UPDATE user SET balance = balance -200 WHERE id in(1, 2, 4)
    @Test
    void testLambdaUpdateWrapper(){
        List<Long> ids = List.of(1L, 2L, 4L);
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql("balance = balance - 200");
        wrapper.in(User::getId, ids);
        userMapper.update(null, wrapper);
    }

(7)条件构造器的用法

  • QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的wher条件部分
  • UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
  • 尽量使用LambdaQueryWrapper和LambdaUpdateWrapper避免硬编码

2.自定义SQL

  • 我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。  
  • 在上面介绍的方法中,我们一部分sql其实是在service中写的,为了规范,service应该是处理业务的,数据库相关不应该写到里面,那么我们可以利用自定义SQL去解决这种问题

(1)需求:更新id为1,2,4的用户的余额,扣200

(2)实现SQL:UPDATE user SET balance = balance -200 WHERE id in(1, 2, 4)

(3)service

    @Test
    void testCustomSQL(){
        List<Long> ids = List.of(1L, 2L, 4L);
        int account = 200;
        // 1.构建条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().in(User::getId, ids);
        // 2.自定义SQL方法的调用
        userMapper.updateByCustomSQL(account, wrapper);
    }

(3)mapper:在mapper方法参数中用Param注解声明wrapper变量必须是ew

public interface UserMapper extends BaseMapper<User> {

    /**
     * 
     * @param account
     * @param wrapper
     */
    void updateByCustomSQL(@Param("account") int account, @Param("ew") LambdaQueryWrapper<User> wrapper);
}
  • 也可以使用mp自带的常量

(4)mapper.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.mp.mapper.UserMapper">
    <update id="updateByCustomSQL">
        update user set balance = balance + #{account} ${ew.customSqlSegment}
    </update>
</mapper>

 3.IService接口

  • 功能相比于之前我们继承的BaseMapper更加的强大

(1)基本用法

  • 自定义接口继承Iservice接口
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;

public interface IUserService extends IService<User> {
}
  • 自定义Service实现类,实现自定义接口并继承ServiceImpl类

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
  •  service实现类中调用
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    public void add(User user){
        this.save(user);
    }
    public void  list(User user){
        this.listByIds(null);
    }
}
  • 注1:按照上面步骤写完以后,我们就能够直接调用 Service接口 给我们提供的各种各样丰富的方法了

(2)Service接口中lambdaQuery方法:在写sql的时候,我们经常会遇到先判断条件为null的情况,使用lambdaQuery方法就不需要在做这样的判断了

  • 普通写法

  • 使用LambdaQuery

(3)Service接口中lambdaUpdate方法:可以添加条件,直接做更新

(4)批量插入

  • 性能

三、扩展功能

1.代码生成器

(1)安装插件:mybatisplus插件

(2)在idea的工具中填写数据库连接(版本不同位置可能有所不同,我的是23版本)

(3)连接成功,后点击生成代码

(4)查看生成的代码:在我们设置的包下面就可以看到生成的代码了

  • Controller
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author author
 * @since 2024-12-26
 */
@RestController
@RequestMapping("/address")
public class AddressController {

}
  • servece
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2024-12-26
 */
@Service
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements IAddressService {

}
  • entity

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * 
 * </p>
 *
 * @author author
 * @since 2024-12-26
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("address")
public class Address implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 用户ID
     */
    private Long userId;

    /**
     * 省
     */
    private String province;

    /**
     * 市
     */
    private String city;

    /**
     * 县/区
     */
    private String town;

    /**
     * 手机
     */
    private String mobile;

    /**
     * 详细地址
     */
    private String street;

    /**
     * 联系人
     */
    private String contact;

    /**
     * 是否是默认 1默认 0否
     */
    private Boolean isDefault;

    /**
     * 备注
     */
    private String notes;

    /**
     * 逻辑删除
     */
    private Boolean deleted;


}

2.静态工具(最新版本才有)

  • 与IService接口相似,但是它没有泛型,需要我们手动传入class
  • 为什么有IService接口还需要这个静态工具类呢?

        因为在某些连表查询的场景,表1有可能需要用到表2的信息,表2也有可能用到表1的信息,就会形成循环依赖,为了解决这种场景,就可以使用静态工具,我们不指定具体的类去操作

  • 注1:spring可以开启循环依赖:spring.main.allow-circular-references=true
  • 注2:连表查询可使用手写xml

3.逻辑删除

(1)逻辑删除:开发中我们的一些数据删除是伪删除,也就是逻辑删除,即在表中加一个字段,用0 1 表示正常或者删除,当我们查询的时候加上条件为0即可

(2)mybatisplus提供了逻辑删除的功能,无需改变方法的调用方式(我们可以调用本来的方法去进行删除或者查询),只要我们配置了逻辑删除的相关配置,调用原来的方法时,他会自动根据我们配置的字段去删除查询(删除方法变成了更新,查询方法底层增加了对应条件)

  • 注:不推荐使用

4.枚举处理器

(1)枚举映射

  • 在实体类中,某些字段填写的是数字,为了代码的可读性,可以用枚举类去做替换,替换以后其类型和数据库中的类型就对不上了,枚举处理器就是解决这种问题的

  • 上图中,可以将status字段替换为枚举类,用@EnumValue标注真正和数据库中字段对应的值即可
  • 在VO中,给前端返回数据时默认是枚举名(NORMAL、FREEZE),要想给前端返回 0 1,那么我们可以在value上方加上@JsonValue

(2)配置全局枚举处理器

mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

5.JSON处理器

(1)Json和实体类映射

  • JSON处理器是用来解决数据库中json类型和java类型转换的问题

  • 在上图中,数据库中的json字段要映射到实体类中,需要加上注解(没有全局配置,只能一个一个去配):@TableField(typeHandler = JacksonTypeHandler.class)
  • 还需要在@TableName中开启我们复杂结果的映射:autoResultMap = true

四、插件功能

1.Mybatis-Plus分页插件

(1)基本使用

  • 要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件
@Configuration
public class MybatisConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 1.创建分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        paginationInnerInterceptor.setMaxLimit(1000L); // 设置单页最大条数
        // 2.添加分页插件
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        return mybatisPlusInterceptor;
    }
}
  • 使用
    @Test
    void testPage(){
        int pageNumber = 1;
        int pageSize = 2;
        // 准备分页
        Page<User> page = Page.of(pageNumber, pageSize);
        // 添加排序
        page.addOrder(new OrderItem("balance", true));// true是升序
        userService.page(page);

        System.out.println(page.getTotal());
    }
  • 结果

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值