MybatisPlus

发布于:2024-12-22 ⋅ 阅读:(9) ⋅ 点赞:(0)

一、快速入门

1.引入MybatisPlus的起步依赖

mybatisPlus官方提供了starter。其中集成了Mybatis和MybatisPlus的所有功能,对mybatis实现了润物无声,并且实现了自动装配效果。

因此使用了Mybatis的项目,也可以使用MybatisPlus的starter代替Mybatis的starter:

<!-- mybatisplus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

2.定义Mapper

自定义的 Mapper继承MybatisPlus提供的BaseMapper接口:

package com.lql.race.mapper;

import com.lql.race.model.dto.AdminDto;
import com.lql.race.model.po.Admin;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lql.race.model.vo.AdminVo;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author 李大爷
 * @since 2024-10-09
 */
public interface AdminMapper extends BaseMapper<Admin> {

    Admin login(Admin admin);

    @Select("select id from admin where id = #{id} and password = #{password}")
    Admin findPwd(Admin admin);
}

3.常见注解

MybatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。

package com.lql.race.model.po;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * <p>
 * 
 * </p>
 *
 * @author 李大爷
 * @since 2024-10-09
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("admin")
@ApiModel(value="Admin对象", description="")
public class Admin implements Serializable {

    private static final long serialVersionUID = 1L;

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

    private String account;

    private String password;

    private String phone;

    private Integer type;

    private Integer adminid;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date regTime;


}

类名驼峰转下划线作为表名

变量名驼峰转下划线作为表的字段名

自定义配置:

如果不符合MybatisPlus的约定就要使用自定义配置。

        @TableName:用来指定表名

        @TableId:用来指定主键

        @TableField:用来指定表中对应的字段

使用TableField的常见场景:

1)成员变量名与数据库字段名不一致

2)成员变量名以is开头,且是布尔值(经过反射处理,它会将is去掉作为数据库字段名)

3)成员变量名与数据库关键字冲突

4)成员变量名不是数据库字段(数据库中不存在该字段)

4.常用配置

mybatis-plus:
  type-aliases-package: com.lql.race.po
  mapper-locations: classpath:mapper/*Mapper.xml
  global-config:
    db-config:
      id-type: auto
      update-strategy: not_null
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
    map-underscore-to-camel-case: true
    cache-enabled: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

二、核心功能

5.条件构造器

QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的where条件部分

UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用

尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码

6.自定义sql

我们可以利用MybatisPlus的Wrapper来构建复杂的where条件,然后自己定义sql语句中剩下的部分。

7.IService接口

1)IService接口使用流程:

自定义Service接口继承IService并指定实体类泛型

package com.lql.race.service;


import com.lql.race.model.dto.AdminDto;
import com.lql.race.model.po.Admin;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lql.race.model.query.AdminQuery;
import com.lql.race.model.vo.AdminVo;
import com.lql.race.model.vo.Result;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author 李大爷
 * @since 2024-10-09
 *
 * 批处理新增 删除
 *
 * 使用service接口和实现类的目的:
 *      1.解耦
 *      2.多态
 *      3.
 */
public interface IAdminService extends IService<Admin> {
    Result login(Admin admin);

    List<AdminVo> adminList();

    Result findAdminById(Integer id);

    List<AdminVo> adminList1(AdminDto adminDto);

    Result findPwd(AdminDto adminDto);

    void updatee(AdminDto adminDto);

    Admin getAdminByAccount(String account);

    Result adminPage(AdminQuery adminDto);
}

2)Lambda

  IService中还提供了Lambda功能来简化我们的复杂查询及更新功能。

@Override
public List<User> queryUsers(UserQuery userQuery) {
        return lambdaQuery()
                .like(userQuery.getName() != null, User::getUsername, userQuery.getName())
                .eq(userQuery.getStatus() != null, User::getStatus, userQuery.getStatus())
                .ge(userQuery.getMinBalance() != null, User::getBalance, userQuery.getMinBalance())
                .le(userQuery.getMaxBalance() != null, User::getBalance, userQuery.getMaxBalance())
                .list();
}

3)批量新增

用for循环非常慢,需要使用MybatisPlus的批处理:

    @Test
    void testSaveBatch() {
        // 准备10万条数据
        List<User> list = new ArrayList<>(1000);
        long b = System.currentTimeMillis();
        for (int i = 1; i <= 100000; i++) {
            list.add(buildUser(i));
            // 每1000条批量插入一次
            if (i % 1000 == 0) {
                userService.saveBatch(list);
                list.clear();
            }
        }
        long e = System.currentTimeMillis();
        System.out.println("耗时:" + (e - b));
    }

根据MybatisPlus源码显示,MybatisPlus的批处理是基于PrepareStatement的预编译模式,然后批量提交,最终在数据库执行时还是会有多条insert语句,逐条插入数据。而想得到最佳性能,最好是将多条SQL合并为一条。

  MySQL的客户端连接参数中有这样的一个参数:rewriteBatchedStatements。顾名思义,就是重写批处理的statement语句。这个参数的默认值是false,我们需要修改连接参数,将其配置为true。

在配置文件中,在数据库连接配置中在url后面加上 rewriteBatchedStatements=true 的一个参数:

url: jdbc:mysql://192.168.44.128:3306/race?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true

 在ClientPreparedStatementexecuteBatchInternal中,有判断rewriteBatchedStatements值是否为true并重写SQL的功能,这样效率就有了明显的提升。

三、扩展功能

1.代码生成器

(1)安装插件

下载idea插件并apply,帮助实现代码生成

(2) 使用

配置数据库信息

dbUrl的填写直接复制application中的数据库配置中的url即可:

2.Db静态工具

        有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能:

Db静态工具由MybatisPlus提供,直接使用就可以;hutool工具提供的Db我没有用过,这里示例代码使用MybatisPlus提供的Db

@GetMapping(path = "/deleteadmin")
    public Result deleteAdmin(@Param("id") Integer id) {
        adminService.removeById(id);
        Db.lambdaUpdate(AdminMenu.class).eq(AdminMenu::getAdminid, id).remove();
        // adminMenuService.delete(id);//删除该管理员权限
        return new Result(200, "delete success", null);
    }

Db静态工具在Service层和Controller层都可以使用

 @Override
    public void saveAttractionType(Integer[] typeIds, int id) {
        for (Integer typeId : typeIds) {
            AttractionAttractiontype attractionAttractiontype = new AttractionAttractiontype();
            attractionAttractiontype.setAttractionId(id);
            attractionAttractiontype.setAttractionTypeId(typeId);
            Db.save(attractionAttractiontype);
        }
    }


网站公告

今日签到

点亮在社区的每一天
去签到