简介
MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis-Plus 官网: MyBatis-Plus (baomidou.com)
Mybatis-plus特性
1、无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
2、依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
3、损耗小:启动即会自动注入基本CRUD,性能基本无损耗,直接面向对象操作
4、通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
5、多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
6、支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
7、支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
8、内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于写基本List查询
9、内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
10、内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作
快速入门
1. 常见配置
1.1 引入MyBatisPlus相关依赖(因为要操作数据库,所以这里也引入了MySQL依赖)
MybatisPlus提供了starter,实现了自动Mybatis以及MybatisPlus的自动装配功能,坐标如下:
<!--MybatisPlus依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency> <!--数据库依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency>
1.2 创一个application.yaml,进行配置
实体类+全局id类型
mybatis-plus: type-aliases-package: com.itheima.mp.domain.po # 实体类包所在路径 global-config: db-config: id-type: auto # 全局id类型为自增长
数据源
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root
1.3 扫描Mapper包 加在启动类上
2. 定义Mapper层
为了简化单表增删查改,MybatisPlus提供了一个BaseMapper基础的接口,其中已经实现了单表的增删查改
在Mapper接口上继承BaseMapper,这样就使用它里面所有的方法了
方法的使用:
增删改方法
delete(Wrapper<T>): int
:根据条件删除记录,返回受影响的行数。deleteBatchIds(Collection<? extends Serializable>): int
:根据主键集合批量删除记录,返回受影响的行数。deleteById(Serializable): int
:根据主键删除单条记录,返回受影响的行数。deleteByMap(Map<String, Object>): int
:根据 Map 中的条件删除记录,返回受影响的行数。insert(T): int
:插入一条记录,返回受影响的行数。update(T, Wrapper<T>): int
:根据条件更新记录,返回受影响的行数。updateById(T): int
:根据主键更新记录,返回受影响的行数。查询方法
selectBatchIds(Collection<? extends Serializable>): List<T>
:根据主键集合批量查询记录,返回记录列表。selectById(Serializable): T
:根据主键查询单条记录,返回记录对象。selectByMap(Map<String, Object>): List<T>
:根据 Map 中的条件查询记录,返回记录列表。selectCount(Wrapper<T>): Long
:根据条件查询记录数量,返回记录数量。selectList(Wrapper<T>): List<T>
:根据条件查询记录列表,返回记录列表。selectMaps(Wrapper<T>): List<Map<String, Object>>
:根据条件查询记录,返回 Map 列表,每个 Map 代表一条记录。selectMapsPage(P, Wrapper<T>): P
:分页查询记录,返回 Map 列表,每个 Map 代表一条记录。selectObjs(Wrapper<T>): List<Object>
:根据条件查询记录,返回对象列表。selectOne(Wrapper<T>): T
:根据条件查询单条记录,返回记录对象。selectPage(P, Wrapper<T>): P
:分页查询记录,返回记录列表- 测试
package com.itheima.mp.service; import com.itheima.mp.domain.po.User; import com.itheima.mp.domain.po.UserInfo; import com.itheima.mp.mapper.UserMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @SpringBootTest public class IUserMapperTest { @Autowired UserMapper iUserMapper; // 新增 @Test public void testSaveUser() { User user = new User(); //user.setId(5L); user.setUsername("如柴3号"); user.setPassword("123"); user.setPhone("18688990022"); user.setBalance(200); user.setInfo(UserInfo.of(24, "英文老师", "female")); user.setCreateTime(LocalDateTime.now()); user.setUpdateTime(LocalDateTime.now()); iUserMapper.insert(user); } // 批量查询 @Test void tesQuery() { Collection<User> userList = iUserMapper.selectBatchIds(List.of(1L, 2L, 4L)); userList.forEach(System.out::println); } // 修改 @Test void testUpdateById() { User user = new User(); user.setId(5L); user.setBalance(20000); iUserMapper.updateById(user); } // 删除 @Test void testDelete() { iUserMapper.deleteById(5L); } }
3. 定义Service层和ServiceImpl实现类
MybatisPlus不仅提供了BaseMapper,还提供了通用的Service接口及默认实现,封装了一些常用的service模板方法。 通用接口为
IService
,默认实现为ServiceImpl
,其中封装的方法可以分为以下几类:
save
:新增
remove
:删除
update
:更新
get
:查询单个结果
list
:查询集合结果
count
:计数
page
:分页查询由于Service中经常需要定义与业务有关的自定义方法,因此我们不能直接使用
IService
,而是自定义Service
接口,然后继承IService
以拓展方法。同时,让自定义的Service实现类
继承ServiceImpl
,这样就不用自己实现IService
中的接口了Service层
package com.itheima.mp.service; import com.baomidou.mybatisplus.extension.service.IService; import com.itheima.mp.domain.po.User; public interface IUserService extends IService<User> { }
ServiceImpl层
package com.itheima.mp.service.impl; 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 IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService { }
方法的使用:
save
是新增单个元素
saveBatch
是批量新增
saveOrUpdate
是根据id判断,如果数据存在就更新,不存在则新增
saveOrUpdateBatch
是批量的新增或修改
removeById
:根据id删除
removeByIds
:根据id批量删除
removeByMap
:根据Map中的键值对为条件删除
remove(Wrapper<T>)
:根据Wrapper条件删除
updateById
:根据id修改
update(Wrapper<T>)
:根据UpdateWrapper
修改,Wrapper
中包含set
和where
部分
update(T,Wrapper<T>)
:按照T
内的数据修改与Wrapper
匹配到的数据
updateBatchById
:根据id批量修改
getById
:根据id查询1条数据
getOne(Wrapper<T>)
:根据Wrapper
查询1条数据
getBaseMapper
:获取Service
内的BaseMapper
实现,某些时候需要直接调用Mapper
内的自定义SQL
时可以用这个方法获取到Mapper
listByIds
:根据id批量查询
list(Wrapper<T>)
:根据Wrapper条件查询多条数据
list()
:查询所有
count()
:统计所有数量
count(Wrapper<T>)
:统计符合Wrapper
条件的数据数量测试
package com.itheima.mp.service; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.itheima.mp.domain.po.User; import com.itheima.mp.domain.po.UserInfo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @SpringBootTest public class IUserServiceTest { @Autowired IUserService iUserService; @Test public void testSaveUser() { User user = new User(); //user.setId(5L); user.setUsername("如柴3号"); user.setPassword("123"); user.setPhone("18688990022"); user.setBalance(200); user.setInfo(UserInfo.of(24, "英文老师", "female")); user.setCreateTime(LocalDateTime.now()); user.setUpdateTime(LocalDateTime.now()); iUserService.save(user); } @Test void tesQuery() { Collection<User> userList = iUserService.listByIds(List.of(1L, 2L, 4L)); userList.forEach(System.out::println); } @Test void testPageQuery() { int pageNo = 1, pageSize = 3; Page<User> page = Page.of(pageNo, pageSize); // 排序 先按照金额 升序,再按照id 升序 page.addOrder(new OrderItem("balance", true)); page.addOrder(new OrderItem("id", true)); Page<User> p = iUserService.page(page); long total = p.getTotal(); System.out.println("总记录数:" + total); long pages = p.getPages(); System.out.println("总页数:" + pages); List<User> users = p.getRecords(); users.forEach(System.out::println); } }
4.Controller层
直接将Mapper层或Service层注入即可使用,和Mybatis时没什么区别
package com.itheima.mp.controller;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping(value = "/users")
@Api(tags = "用户管理接口")
public class UserController {
@Autowired
IUserService userService;
@GetMapping("/list")
public List<User> getEricUserList() {
List<User> list = userService.list();
return list;
}
}
5.常用注解
数据表字段带有_的可以自动映射到驼峰式命名的属性上(t_user——>tUser)。
Mapper 接口
- @Mapper
- 作用:表明这是一个 MyBatis 的 Mapper 接口。该接口通常会继承
BaseMapper<User>
,这样就提供了基本的 CRUD(增删改查)操作方法。- @Select
- 作用:用于定义查询方法。通过在接口方法上添加这个注解,并在注解中编写 SQL 查询语句,就可以实现自定义的查询操作。
- @Insert
- 作用:用于定义插入方法。在接口方法上添加此注解并编写 SQL 插入语句,即可实现数据插入操作。
- @Update
- 作用:用于定义更新方法。在接口方法上添加这个注解并编写 SQL 更新语句,能够实现数据更新操作。
- @Delete
- 作用:用于定义删除方法。在接口方法上添加此注解并编写 SQL 删除语句,可实现数据删除操作
实体类注解:
1.数据库名不同,在类上增加@TableName(“mp_address”)
2.主键ID的驼峰一般无法识别,在主键属性上增加@TableId
3.属性与字段名不相同,在属性上增加@TableField(“name”)
- @TableName
("address")
- 作用:指定实体类对应的数据库表名为
address
。当实体类名与表名不一致时,使用这个注解来建立映射关系。- @TableId
(type = IdType.AUTO)
- 作用:指定
id
字段为主键,并且使用自增策略。在向数据库插入数据时,id
字段的值会按照数据库的自增规则自动生成。- @TableFieId
("is_default")
- 作用:指定实体类中的
isDefault
字段对应数据库中的is_default
列。用于建立实体类字段与数据库表列之间的映射关系。