一、快速入门
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.pomapper-locations: classpath:mapper/*Mapper.xmlglobal-config:db-config:id-type: autoupdate-strategy: not_nullconfiguration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandlermap-underscore-to-camel-case: truecache-enabled: truelog-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的批处理:
@Testvoid 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
在ClientPreparedStatement
的executeBatchInternal
中,有判断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层都可以使用
@Overridepublic void saveAttractionType(Integer[] typeIds, int id) {for (Integer typeId : typeIds) {AttractionAttractiontype attractionAttractiontype = new AttractionAttractiontype();attractionAttractiontype.setAttractionId(id);attractionAttractiontype.setAttractionTypeId(typeId);Db.save(attractionAttractiontype);}}