MyBatis-Plus 学习笔记

学习官网: https://mp.baomidou.com/guide/

一、快速入门

1.简介

  • MyBatis的增强工具,在Mybatis的基础上只做增强功能,兼容MyBatis

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

2.快速开始

2.1 官方提供的数据库的表

创建表:

DROP TABLE IF EXISTS user;CREATE TABLE user
(id BIGINT(20) NOT NULL COMMENT '主键ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年龄',email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (id)
);

插入数据:

DELETE FROM user;INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

表:

2.2 创建spring boot项目

2.3 引入依赖

除了创建项目引入的那些常用的依赖外,还需要引入mybatis-plus和mysql驱动的依赖

        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency>

2.4 配置

yml配置

spring:datasource:url: jdbc:mysql://localhost:3306/bookstoredriver-class-name: com.mysql.jdbc.Driverusername: rootpassword: '073838'

2.5 编写bean和mapper

User:

@Data
public class User {private Long id;private String name;private Integer age;private String email;
}

UserMapper:

@Mapper//也可以在springboot主类上标@MapperScan注解
public interface UserMapper extends BaseMapper<User> {}

2.6 开始使用

使用测试类进行测试:

@SpringBootTest
class MpApplicationTests {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelect() {System.out.println(("----- selectAll method test ------"));List<User> userList = userMapper.selectList(null);for (User user: userList){System.out.println(user);}}}

运行结果:

3.常用注解

@TableName

描述:表名注解,标在实体类中

常用属性:

  • value:表名
  • schema:对应的schema
  • resultMap:sql映射文件中 resultMap 的 id

使用:

@Data
@TableName(value = "user", schema = "bookstore", resultMap = "book")
public class User {private Long id;private String name;private Integer age;private String email;
}

注意:resultMap 若使用,需要编写相应的sql映射文件来映射,否则会报错

@TableId

描述:主键注解

属性:

IdType:设置自动生成主键值的策略

@TableField

描述:字段注解(非主键)

属性:详见https://mp.baomidou.com/guide/annotation.html#tablefield

  • value:数据库字段名
  • el:映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
  • exist:是否为数据库表字段。若为false,该属性不会映射到数据库表的字段

示例:

@TableName(value = "user", schema = "bookstore")
public class User {@TableId(value = "id")private Long id;@TableField(exist = true, value = "email")private String name;private Integer age;private String email;
}

运行结果:

@Version注解

描述:乐观锁注解、标记,标记@Version在字段上

@EnumValue

  • 描述:通枚举类注解(注解在枚举字段上)

二、CRUD接口

1.Service CRUD接口

IService提供了给service层进行CRUD的接口,需要配合Mapper层的接口一起使用。主要有save、remove、update、getOne、list等。示例:

@SpringBootTest
public class CRUDTest {@AutowiredUserService userService;@Testpublic void saveTest(){User user = new User();user.setAge(18);user.setEmail("aaaa@126.com");user.setName("anpu");List<User> list = new ArrayList<>();for(int i = 0; i < 15; i++){list.add(user);}userService.save(user);userService.saveBatch(list);}@Testpublic void getTest(){User user = userService.getById("1");List<User> users = userService.list();System.out.println("one:" + user);System.out.println("--------------------");users.forEach(System.out::println);}@Testpublic void updateTest(){User user = userService.getById(6);user.setAge(3);user.setName("deserts");userService.updateById(user);}@Testpublic void deleteTest(){userService.removeById(6);Map<String, Object> map = new HashMap<>();map.put("name", "anpu");userService.removeByMap(map);}@Testpublic void saveOrUpdateTest(){User user = userService.getById(3);user.setName("lala");user.setId(6L);userService.saveOrUpdate(user);}@Testpublic void countTest(){System.out.println(userService.count());}}

2.Mapper CRUD层接口

BaseMapper提供了Mapper层进行CRUD的接口。主要有delete、select、update、Insert接口。

3.两层CRUD接口的使用

1.Mapper层接口继承BaseMapper接口

@Mapper
public interface UserMapper extends BaseMapper<User> {}

2.Service层创建接口去继承IService接口

public  interface UserService extends IService<User> {}

3.创建service实现类去继承ServiceImpl,实现service接口,妻子ServiceImpl是Iservice的实现类,避免重写很多方法

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}

三、条件构造器

说明:

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类
用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为

AbstractWrapper

AbstractWrapper是抽象类,封装了基本的条件方法,提供给QueryWrapper和UpdateWrapper继承使用。

提供的条件方法:

  • allEq, eq, ne:等于(map),等于(单个),不等于
  • gt,ge,lt,le: 大于,大于等于,小于,小于等于
  • between,notBetween: 在A和B之间,不在A和B之间
  • like: 模糊查询。示例: like(“name”, “王”)--->name like ‘%王%’
  • notLike: 模糊查询。示例: notLike(“name”, “王”)--->name not like ‘%王%’
  • likeLeft: 模糊查询。示例:likeLeft(“name”, “王”)--->name like ‘%王’
  • likeRight: 模糊查询。示例:likeRight(“name”, “王”)--->name like ‘王%’
  • isNull, isNotNUll: 是否为空
  • in,notIn: 取值范围
  • inSql, notInSql: 子查询。示例:inSql(“id”, “select id from table where id < 3”)--->id in (select id from table where id < 3)
  • groupBy: 分组查询。示例: groupBy(“id”, “name”)--->group by id,name
  • orederByAsc,orederByDsc,orederBy: 按字段升降序排序查找
  • having: 示例:having(“sum(age) > 10”)--->having sum(age) > 10
  • or,and: 条件嵌套。示例:eq(“id”,1).or().eq(“name”,“老王”)--->id = 1 or name = ‘老王’
  • exists,notExists: 子查询。示例:exists(“select id from table where age = 1”)--->exists (select id from table where age = 1)

conditonal参数

如:notExists(boolean condition, String notExistsSql);默认为true,若为false,表示该条件失效。

QueryWrapper

QueryWrapper继承AbstractWrapper。除了AbstractWrapper外,还有select()用于设置查询字段:

select(String... sqlSelect)
select(Predicate<TableFieldInfo> predicate)
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)

说明:

以上方法分为两类.
第二类方法为:过滤查询字段(主键除外),入参不包含 class 的调用前需要wrapper内的entity属性有值! 这两类方法重复调用以最后一次为准

  • 例: select("id", "name", "age")
  • 例: select(i -> i.getProperty().startsWith("test"))

UpdateWrapper

说明:

继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件
LambdaUpdateWrapper, 可以通过 new UpdateWrapper().lambda() 方法获取!

set

为某个字段的所以值设置为一个值,如set(“name”, null)--->数据库字段值变为null

set(String column, Object val)
set(boolean condition, String column, Object val)

setSql

  • 设置 SET 部分 SQL
  • 例: setSql("name = '老李头'")

四、分页功能

1.加入分页插件

@Configuration
public class MyBatisConfiguration {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认falsepaginationInnerInterceptor.setOverflow(true);// 设置最大单页限制数量,默认 500 条,-1 不受限制paginationInnerInterceptor.setMaxLimit(100L);mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);return mybatisPlusInterceptor;}
}

2.使用service层的接口实现分页

    @Testpublic void pageTest(){Page<User> page = new Page<>(1, 5);QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("name", "anpu");Page<User> userPage = userService.page(page, wrapper);List<User> records = userPage.getRecords();System.out.println("---------" + userPage);System.out.println("-------->" + userPage.getTotal());System.out.println("-------->" + userPage.getSize());records.forEach(System.out::println);}

控制台输出:

---------com.baomidou.mybatisplus.extension.plugins.pagination.Page@44114b9f
-------->16
-------->5
User(id=15, name=anpu, age=18, email=aaaa@126.com)
User(id=16, name=anpu, age=18, email=aaaa@126.com)
User(id=17, name=anpu, age=18, email=aaaa@126.com)
User(id=18, name=anpu, age=18, email=aaaa@126.com)
User(id=19, name=anpu, age=18, email=aaaa@126.com)

五、乐观锁插件

MybatisPlusInterceptor

该插件是核心插件,目前代理了 Executor#queryExecutor#updateStatementHandler#prepare 方法

目前已有的功能:

  • 自动分页: PaginationInnerInterceptor
  • 多租户: TenantLineInnerInterceptor
  • 动态表名: DynamicTableNameInnerInterceptor
  • 乐观锁: OptimisticLockerInnerInterceptor
  • sql性能规范: IllegalSQLInnerInterceptor
  • 防止全表更新与删除: BlockAttackInnerInterceptor

使用顺序:

使用多个功能需要注意顺序关系,建议使用如下顺序

  • 多租户,动态表名
  • 分页,乐观锁
  • sql性能规范,防止全表更新与删除

总结: 对sql进行单次改造的优先放入,不对sql进行改造的最后放入

乐观锁实现

什么是乐观锁?当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁的实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

使用方法:

1.数据库表添加字段version

2.实体类使用@version标注

@Data
@TableName(value = "user", schema = "bookstore")
public class User {@TableId(value = "id", type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;@Versionprivate Long version;
}
  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!

3.配置类加入乐观锁插件,乐观锁生效

@Configuration
public class MyBatisConfiguration {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//分页插件PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认falsepaginationInnerInterceptor.setOverflow(true);// 设置最大单页限制数量,默认 500 条,-1 不受限制paginationInnerInterceptor.setMaxLimit(100L);//乐观锁插件OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);mybatisPlusInterceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);return mybatisPlusInterceptor;}
}

六、扩展功能

1.代码生成器

添加依赖:MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:

        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency>

编写代码:

 @Testpublic void test(){//创建代码生成器AutoGenerator mpg = new AutoGenerator();// 全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");gc.setOutputDir(projectPath + "/src/main/java");gc.setEntityName("bean");gc.setMapperName("mapper");gc.setServiceName("service");gc.setControllerName("controller");//是否覆盖之前的文件gc.setFileOverride(true);gc.setAuthor("deserts");gc.setOpen(false);//实体属性 Swagger2 注解gc.setSwagger2(true);mpg.setGlobalConfig(gc);// 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/bookstore?useUnicode=true&useSSL=false&characterEncoding=utf8");dsc.setDriverName("com.mysql.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("073838");mpg.setDataSource(dsc);// 包配置PackageConfig pc = new PackageConfig();pc.setModuleName("auto");pc.setParent("com.deserts");mpg.setPackageInfo(pc);// 策略配置StrategyConfig strategy = new StrategyConfig();strategy.setNaming(NamingStrategy.underline_to_camel);strategy.setColumnNaming(NamingStrategy.underline_to_camel);strategy.setEntityLombokModel(true);strategy.setRestControllerStyle(true);//包含的表名strategy.setInclude("user");//设置逻辑删除字段strategy.setLogicDeleteFieldName("deleted");//设置自动填充字段TableFill gmt_create = new TableFill("gmt_create", FieldFill.INSERT);TableFill gmt_update = new TableFill("gmt_update", FieldFill.INSERT_UPDATE);strategy.setTableFillList(Arrays.asList(gmt_create, gmt_update));//设置乐观锁version字段strategy.setVersionFieldName("version");mpg.setStrategy(strategy);//执行mpg.execute();}

2.逻辑删除

1.数据库表中增加一个逻辑删除的字段:

2.配置yml

mybatis-plus:global-config:db-config:logic-delete-field: flag  # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

3.实体类中指定逻辑删除字段:

@TableLogic
private Integer deleted;

4.测试

    @Testpublic void deletedTest(){userService.removeById(1);}

5.实际执行的语句

UPDATE bookstore.user SET deleted=1 WHERE id=? AND deleted=0

6.加上逻辑删除后执行查找:

    @Testpublic void select(){User user = userService.getById(1);System.out.println(user);}

此时执行的sql:

SELECT id,name,age,email,version,deleted FROM bookstore.user WHERE id=? AND deleted=0

3.自动填充功能

实现数据库表的更新有记录:gmt_create,gmt_modified

方式一:基于数据库表

创建时间不需要勾选根据时间戳更新:

效果:

执行更新操作后:

方式二:代码中设置

表中创建两个字段:

实体类注解填充字段:

    @TableField(fill = FieldFill.INSERT)private Date cmtCreate;@TableField(fill = FieldFill.INSERT_UPDATE)private Date cmtModified;

自定义实现类MyMetaObjectHandler:

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill ....");this.setFieldValByName("cmtCreate", new Date(), metaObject);this.setFieldValByName("cmtModified", new Date(), metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {log.info("start update fill ....");this.setFieldValByName("cmtModified", new Date(), metaObject);}
}

更新操作后:

4.日志分析

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

MyBatis-Plus 学习笔记相关推荐

  1. mybatis框架--学习笔记(下)

    上篇:mybatis框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81034021 8.高级映射: (1)一对一查询: ①使 ...

  2. mybatis框架--学习笔记(上)

    使用JDBC操作数据库的问题总结: (1)数据库连接,使用时创建,不使用时立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接. (2) ...

  3. [Spring+SpringMVC+Mybatis]框架学习笔记(四):Spring实现AOP

    上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC 下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(五):SpringA ...

  4. 2021年3月8日:MyBatis框架学习笔记02:利用MyBatis实现CRUD操作

    MyBatis框架学习笔记02:利用MyBatis实现CRUD操作 在第一节课中我们在UserMapper.xml里定义了两个查询语句:findById和findAll,对应的在UserMapper接 ...

  5. 【Mybatis】学习笔记01:连接数据库,实现增删改

    需要数据库SQL的请跳转到文末 哔哩哔哩 萌狼蓝天[转载资料][尚硅谷][MyBatis]2022版Mybatis配套MD文档[Mybatis]学习笔记01:连接数据库,实现增删改[Mybatis]学 ...

  6. MyBatis框架学习笔记(3)——B站动力节点

    文章目录 (0)介绍 (1)返回主键的标签 (2)UUID的概念 (3)update时< set >标签的使用 (4)表与表的关联关系 一对多关联 多对一关联 一对一关联 多对多关联 (5 ...

  7. Mybatis的学习笔记

    MyBatis Mybatis是一款非常优秀的持久层框架,学习的目的是要掌握精通. 那么今天我们就来学习一下这个优秀的框架知识! 此外,由于博主的水平的原因,文章的质量可能不会太高,请酌情观看.如果大 ...

  8. 【自用】Mybatis的学习笔记(第一天)

    捋一下啊 记录一下我总结的经验 我的笔记记录的层次很烂 所以我要在xmind上把层次记录下来 然后按着xmind 层次去敲代码 哪里出了问题,直接去ctrl+f 好了,他妈的开始学习了 ORM 框架 ...

  9. 1 (SSM) springMVC + spring + Mybatis(MySQL)学习笔记 ------ 阶段成果笔记

    学习了一段时间spring,springMVC和Mybatis,从开始学到现在熬了好多夜晚,好几个深夜和bug作战,真是难受. 打算写系列学习笔记,第一篇从一个小的成果说起吧,刚刚学的看这篇可能有点吃 ...

  10. Mybatis 3学习笔记(一)

    主要内容: What is MyBatis? Why MyBatis? Installing and configuring MyBatis Sample domain model What is M ...

最新文章

  1. mysql中取出的时间日期多个.0
  2. yum 安装指定版本php,怎样通过yum安装指定版本的php
  3. Python初探---2x版本与3x版本的区别
  4. .net 内嵌 GeckoWebBrowser (firefox) 核心浏览器
  5. QTP、LoadRunner、QC工具下载地址
  6. 滤波器开发之五:基于算术平均的限幅滤波器
  7. 记事本可以编辑html语言吗,笔记本win7系统使用记事本编辑和运行html代码的方法...
  8. 如何在Windows 10中启用关闭事件跟踪程序
  9. 华为交换机通用配置方式方法
  10. RNA 6. 差异基因表达之-- 火山图 (volcano)
  11. c语言三角形的周长和面积公式,计算三角形的周长和面积
  12. win11安装Pandoc
  13. Leetcode1278
  14. linux 服务器 安装网卡驱动,Linux系统下安装Intel千兆网卡驱动
  15. 微信小程序开发之——仿微信视频录制上传
  16. tf15: 中文语音识别
  17. 3dMax教程网站 文字版
  18. 行人重识别(21)——行人重识别算法性能指标
  19. MAC m1芯片,下载安装natapp
  20. SAP连接电脑串口读数(电子称,磅等数据读取)

热门文章

  1. CentOS:linux开放指定端口命令
  2. Python中的json.dumps()和json.loads()函数
  3. jsp ---- JSTL
  4. 微型计算机字长为4表示,一台微型计算机的字长为4个字节,它表示什么?
  5. springcloud五大组件?注解_spring cloud实现简单的微服务架构
  6. @Component注解的用法
  7. ActiveMQ 认证
  8. oracle删除数据释放表空间流程
  9. mysql 读取oracle_RobotFramework读取mysql和oracle数据库
  10. 如何转换并压缩png格式图片