MyBatisPlus:MyBatisPlus入门

MyBatisPlus

Mybatis-Plus是一个MyBatis的增强工具,在mybatis的基础上只做增强不做改变

简化开发,提高效率

MP的特性

无侵入

只做增强不做改变

损耗小

启动时自动注入基本CRUD,性能几乎无循环

强大的CRUD操作

内置通用Mapper和Service实现大部分单表操作

支持Lambda形式调用

通过Lambda表达式编写各类的查询条件

支持主键自动生成

支持4种主键策略(自增,雪花算法,UUID等)

支持ActiveRecord模式

实体类继承Model即可进行CRUD操作

支持自定义全局通用操作

全局通用方法注入

内置代码生成器

可快速生成各层代码

内置分页插件

基于MyBatis进行物理分页

分页插件支持多种数据库
内置性能分析插件
内置全局拦截插件

MyBatisPlus配置

依赖注入

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version>
</dependency>

配置Datasource

//控制台打印sql配置
#mybatis-plus配置控制台打印完整带参数SQL语句
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

定义实体类

package com.cfjg.pojo;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 实体类基于注解与表进行映射*/
@Data
@Builder
// 指定表名
@TableName("tb_user") 
@NoArgsConstructor
@AllArgsConstructor
public class User {//主键字段注解//设置主键自动生成方法//AUTO(0),increment自增//NONE(1),跟随全局//INPUT(2),自定义主键,自己输入//ASSIGN_ID(3),雪花算法//雪花算法生成的id为19为数字,由时间戳/数据中心/机器标识/序列号四个部分组成//ASSIGN_UUID(4);UUID@TableId(value = "id",type = IdType.AUTO)private Long id;private String userName;private String password;private String name;private Integer age;private String email;//忽略该属性和数据库表中的映射关系@TableField(exist = false)private String ignore
}

MyBatisPlus实现数据库操作

在Mapper层继承BaseMapper

//泛型内写表对应的实体类类型
UserMapper extends BaseMapper<User>    
普通单表操作都在接口中进行定义
直接调用接口方法即可
注:MP的更新操作不会将属性的空值覆盖原本的值
 @Testpublic void testUserInsert(){User user = User.builder().age(19).build();userMapper.insert(user);}

分页查询

需要先配置分页拦截器
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false// paginationInterceptor.setOverflow(false);// 设置最大单页限制数量,-1不受限制paginationInterceptor.setMaxLimit(-1L);interceptor.addInnerInterceptor(paginationInterceptor);return interceptor;} 
}
进行分页查询
 	@Testpublic void testSelectPage() {//创建分页对象,查询完成数据会回填到page对象中Page<User> page = new Page<>(1,2);//构建条件对象QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("age","19");userMapper.selectPage(page, wrapper);System.out.println(page.getRecords());System.out.println(page.getTotal());System.out.println(page.getPages());}

条件查询

使用wrapper接口实现条件查询和更新

//查询接口
QueryWrapper
//更新接口
UpdateWrapper

QueryWrapper常用API

//equal
eq( ) :  等于 =
//not equal
ne( ) :  不等于 <> 或者 !=
//greater than
gt( ) :  大于 >
//greater equal
ge( ) :  大于等于  >=
//less than
lt( ) :  小于 <
//less equal
le( ) :  小于等于 <=
or():或
between ( ) :  BETWEEN1 AND2 
notBetween ( ) :  NOT BETWEEN1 AND2 
in( ) :  in
notIn( ) :not in
like(): like模糊查询%xxx%
likeLeft():左侧模糊查询%xxx
likeRight():右侧模糊查询xxx%
orderByAsc()
orderByDesc()
条件查询操作
	@Testpublic void testCondition(){QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("age",19).or().lt("age",30);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}
限定字段查询

通过wrapper限定select查询的字段

 wrapper.eq("age",19).or().lt("age",30).select("age");

LambdaQueryWrapper查询

避免使用普通wrapper时出现的硬编码列名问题,通过传入对应属性值的get方法解析出这个属性对应的字段

	@Testpublic void testLambdaSelect(){LambdaQueryWrapper<User> eq = Wrappers.<User>lambdaQuery().eq(User::getAge, 19);userMapper.selectList(eq);Wrappers.<User>lambdaUpdate().eq(User::getAge,19);}
LambdaQueryWrapper删除
	@Testpublic void testDelete(){LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery().gt(User::getAge, 19);userMapper.delete(wrapper);}
LambdaQueryWrapper更新
	@Testpublic void testUpdate(){LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery().eq(User::getUserName,null);User user = new User();user.setName("a");user.setAge(11);user.setUserName("b");userMapper.update(user,wrapper);}

定义查询接口实现分页查询

对自定义SQL语句进行分页查询

	@Testpublic void sqlTest(){Page<User> page = new Page<>(1,2);userMapper.findGtIdByPage(page,1);page.getRecords().forEach(System.out::println);}

mybatisplus对应的xml文件在resource下的/mapper/**/*.xml读取

sql:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.UserMapper"><select id="findGtIdByPage" resultType="com.itheima.pojo.User">select * from tb_user where id > #{id}</select>
</mapper>
通过${ew.}实现条件构造器复用
Wrapper ew//传入构造器替换select后的内容
${ew.sqlSelect}//传入构造器替换sql中的条件,放在where后面
{ew.customSqlSegment}

MP实现Service封装

继承公共接口
//service接口继承Iservice接口
public interface UserService extends IService<User>//service实现类继承ServiceImpl接口
//泛型内写Mapper对象和实体类对象
public class UserServiceImpl extends ServiceImpl<UserMapper, User>

MP封装Service实现CRUD操作

大体和持久层一致

先构造条件构造器

再传入条件构造器实现条件查询

    @Testpublic void UserTest(){LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery().eq(User::getUserName,"test");System.out.println(userService.list(wrapper));}

MP代码生成器

自动生成控制层业务层mapper层和xml代码

只需指定数据库和生成的表名即可

导入依赖
<!--mp 代码生成器-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.5</version>
</dependency>
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version>
</dependency>
代码生成器
package com.itheima;import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.sql.Types;
import java.util.Collections;public class CodeGenerator {public static void main(String[] args) {String url = "jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";String username = "root";String password = "root";FastAutoGenerator.create(url, username, password).globalConfig(builder -> {builder.author("itheima") // 设置作者.enableSwagger() // 开启 swagger 模式.outputDir("F:\\code\\mp"); // 指定输出目录}).dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {int typeCode = metaInfo.getJdbcType().TYPE_CODE;if (typeCode == Types.SMALLINT) {// 自定义类型转换return DbColumnType.INTEGER;}return typeRegistry.getColumnType(metaInfo);})).packageConfig(builder -> {builder.parent("com.itheima") // 设置父包名.moduleName("user") // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "F:\\code\\mp")); // 设置mapperXml生成路径}).strategyConfig(builder -> { //策略配置builder.addInclude("tb_user")  // 设置需要生成的表名.addTablePrefix("tb_") // 设置过滤表前缀.entityBuilder() //设置实体构建器,设置属性.enableFileOverride() //文件覆盖.enableLombok() //开启lombok.controllerBuilder().enableRestStyle() //启用RestController.enableFileOverride() //文件覆盖.mapperBuilder().enableBaseResultMap() //开启生成 resultMap 结果映射.enableFileOverride() //文件覆盖;}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}
}

MybatisPlus逻辑删除

即在数据库中添加一个is_delete字段用来表示数据是否被删除

而非真的将数据删除,只是对数据进行标注

用这种方法删除的数据是可逆的,可以恢复

mybatisplus配置逻辑删除
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)
实体类字段加@TableLogic注释
@TableLogic
private Integer is_deleted;

开启逻辑删除功能后,mp在删除查询和更新时会自动加上逻辑删除字段为未删除的条件

MybatisPlus乐观锁

相对于悲观锁而言,乐观锁假设数据在一般情况下不会发生冲突

只有在数据进行提交和更新时才会正式对数据的冲突与否进行检测

如果冲突,则返回错误的信息让用户决定后续操作

相比于悲观锁,并发下的程序吞吐量更大

乐观锁的实现方式

版本号控制

通过数据量增加一个version版本字段,判断每次读取的version版本和数据库记录的是否一致,如果不一致则过期

//通过对实体类字段添加@version注解来标记锁
@version
private Integer version
注册配置类

需要先注册乐观锁插件(乐观锁拦截器)

//扫描我们的repository文件夹
@MapperScan("com.trainingl.repository")
@EnableTransactionManagement
@Configuration  //配置类
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//注册乐观锁插件mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}}

MybatisPlus自动填充

对于创建时间create_time,更新时间update_time这些每次对数据修改时都要设置的字段,如果在代码中进行手动设置会显得冗余且容易出错

mp提供了自动填充的功能

实现过程

通过给实体类添加@TableField注解来进行指定填充的时间

FieldFill字段枚举类四种自动填充处理策略,分别是Default (默认不处理)、Insert (插入时填充)、Update (更新时填充)、Insert_Update (插入和更新时填充)

	@TableField(fill = FieldFill.INSERT)private LocalDateTime creatTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;

再通过实现MetaObjectHandler接口对填充策略进行设计

/*** mybatis-plus自动填充策略设置*/
@Slf4j
@Component
public class DatetimeMetaObjectHandler implements MetaObjectHandler {//进行插入时填充策略@Overridepublic void insertFill(MetaObject metaObject) {log.info("mybatis-plus 开始在你插入的时候 字段填充字段......");this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);}//进行修改操作时填充策略@Overridepublic void updateFill(MetaObject metaObject) {log.info("mybatis-plus 开始在你修改的时候 字段填充字段......");this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);}
}

MybatisPlus通用枚举

实现数据库存入时指定值保存,读取时指定值展示

通过继承IEnum,@EnumValue实现

读取数据时可以通过使用@JsonValue执行显示的值

@AllArgsConstructor
public enum SexEnum implements IEnum<Integer> {boy(0, "男孩"),girl(1, "女孩");private final Integer code;// 序列化枚举值为 接口出参;接口入参(RequestBody),反序列化为枚举值@JsonValueprivate final String name;@Overridepublic Integer getValue() {return code;}
}

@AllArgsConstructor
public enum SexEnum {boy(0, "男孩"),girl(1, "女孩");@EnumValueprivate final Integer code;@JsonValueprivate final String name;}

MybatisPlus拦截器插件

防全表更新和删除插件

全表更新时会抛出异常

@Configuration
public class MybatisPlusConfig {//拦截器@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//注册分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//注册防全表更新与删除插件interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());return interceptor;}
}

MybatisPlus流式查询

流式查询:查询成功后不是返回一个集合而是返回一个迭代器,每次从迭代器取出一条结果进行查询

可以有效的降低内存使用

执行流式查询时,框架不负责对数据库连接进行关闭,需要在取完数据之后进行关闭

Mybatis的流式查询

提供了一个Cursor接口用于流式查询

继承了 java.io.Closeable 和 java.lang.Iterable 接口

所以流式查询的过程是可关闭和可遍历的

提供了三个方法

//用于在取数据之前判断 Cursor 对象是否是打开状态。只有当打开时 Cursor 才能取数据
isOpen()
//用于判断查询结果是否全部取完
isConsumed()
//返回已经获取了多少条数据
getCurrentIndex()
MyBatisPlus实现流式查询

需要自定义接口实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/30937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ai】tx2-nx:安装深度学习环境及4.6对应pytorch

参考:https://www.waveshare.net/wiki/Jetson_TX2_NX#AI.E5.85.A5.E9.97.A8 英伟达2021年发布的的tritionserver 2.17 版本中,backend 有tensorflow1 和 onnxruntime ,他们都是做什么用的,作为backend 对于 triton 推理server意义是什么,是否应该有pytorch? Triton Infer…

PS给logo加白色描边

步骤1&#xff1a;打开你的Logo文件 步骤2&#xff1a;选择Logo层 在“图层”面板中找到你的Logo所在的图层。如果你的Logo是在背景图层上&#xff0c;可以将它转换为普通图层&#xff08;右键点击背景图层&#xff0c;选择“从背景图层转换”&#xff09;&#xff08;此处也…

五大数据防泄漏系统排名|高效实用的防泄漏软件有哪些

在数字化时代&#xff0c;数据泄露已成为企业面临的重要安全挑战之一。为了有效应对这一挑战&#xff0c;企业需要借助先进的数据泄露防护系统来保护其敏感信息免受非法访问、使用和泄露。以下是五大备受推崇的数据泄露防护系统&#xff0c;它们各具特色&#xff0c;功能强大&a…

查看nginx安装/配置路径,一个服务器启动两个nginx

查看nginx安装/配置路径 查看nginx的pid&#xff1a; ps -ef | grep nginx查看pid对应服务的启动路径 ll /proc/2320/exe使用检查配置文件命令&#xff0c;查看配置文件位置 /usr/local/nginx/sbin/nginx -t一个服务启动两个nginx 拷贝一份程序&#xff0c;cpbin是我自己创…

阿里云服务器提醒漏洞要不要打补丁?

我们自己用的电脑一旦发现漏洞&#xff0c;往往是第一时间进行打补丁重启等等&#xff0c;但是作为服务器而言&#xff0c;往往没有这个习惯&#xff0c;为什么&#xff1f;因为害怕服务器打补丁以后&#xff0c;重启后出现打不开的情况&#xff0c;毕竟稳定的运行似乎在这种情…

java.io.eofexception:ssl peer shut down incorrectly

可能是因为 1)https设置 2&#xff09;超时设置 FeignConfig.java package zwf.service;import java.io.IOException; import java.io.InputStream; import java.security.KeyStore;import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory;import org.apac…

广告变现小游戏对接广告平台开发 源码搭建

对接广告平台以实现小游戏广告变现&#xff0c;并搭建相应的源码&#xff0c;是一个包含多个技术环节的过程。这涉及到游戏开发、广告SDK集成、后端服务配置等多个方面。以下是一个大致的开发与搭建流程&#xff1a; 一、游戏开发 需求分析&#xff1a;首先明确小游戏的定位、…

北斗短报文终端在应急消防通信场景中的应用

在应对自然灾害和紧急情况时&#xff0c;北斗三号短报文终端以其全球覆盖、实时通信和精准定位的能力&#xff0c;成为应急消防通信的得力助手。它不仅能够在地面通信中断的极端条件下保障信息传递的畅通&#xff0c;还能提供精准的位置信息&#xff0c;为救援行动提供有力支持…

Adams 插件Plugin二次开发教程

通过cmd或python开发的Adams程序&#xff0c;可以通过执行cmd&#xff08;python&#xff09;命令的方式直接运行&#xff0c;也可以根据cmd教程中提供的创建菜单和对话框的方式调用这些程序&#xff0c;当然更合适的方式是通过插件的方式对二次开发的程序进行管理&#xff0c;…

Java程序员Python一小时速成

背景 由于最近要开发一些AI LLM&#xff08;Large Language Model 大语言模型&#xff09;应用程序&#xff0c;然后又想使用LangChain&#xff08;LangChain 是一个用于构建和操作大语言模型&#xff08;LLMs&#xff09;的框架&#xff0c;旨在帮助开发者更方便地集成和使用…

Shell脚本、相关命令;重定向、管道符、变量相关命令讲解

目录 Shell脚本 概念 执行命令流程的交互区别 交互式 非交互式 Shell脚本应用场景 Shell的作用 Shell的作用 —— 命令解释器&#xff0c;“翻译官” 列出系统中全部解释器 实验 脚本的基本书写格式和执行命令 在子bash下执行脚本 指定解释器的方式执行脚本 指定…

代码讲解——ssm+jsp+maven项目目录结构说明

1 applicationContext.xml 应用上下文配置 2 db.properties 数据库配置 3 log4j.properties日志配置 4 mybatis-config.xml mybatis配置 5 springmvc.xml springmvc配置

万元主力机型该选什么固态硬盘,佰维NV7200、NV3500 的实用一定要让你知道

固态硬盘&#xff1a;变革存储技术&#xff0c;探索无尽可能 今年的固态市场价格一直是稳中上涨。 固态的价格上涨有技术上的因素&#xff0c;也有人工成本上的因素。好在国产固态技术的崛起&#xff0c;在固态价格上涨之下&#xff0c;依旧能选购到性价比和性能出众的型号。…

Elasticsearch搜索引擎(初级篇)

1.1 初识ElasticSearch | 《ElasticSearch入门到实战》电子书 (chaosopen.cn) 目录 第一章 入门 1.1 ElasticSearch需求背景 1.2 ElasticSearch 和关系型数据库的对比 1.3 基础概念 文档和字段 索引和映射 第二章 索引操作 2.0 Mapping映射属性 2.1 创建索引 DS…

【SEMI-e ·国际半导体深圳展】| 06月26-28日唯创知音语音芯片供应商 邀您来观展

世界聚焦半导体&#xff0c;产业规模空前&#xff01;一场高端产业研学盛会即将如约而至。 SEMI-e 第六届2024国际半导体展深圳站&#xff0c;2024年06月26-28日将在深圳国际会展中心&#xff08;宝安&#xff09;开展&#xff0c;展会展出面积60000平方米&#xff0c;汇聚全国…

如何减少sql出现问题

在编写 SQL 时遇到小问题是很常见的&#xff0c;尤其是当你对 SQL 语言、数据库设计或业务需求不够熟悉时。以下是一些建议&#xff0c;帮助你避免或减少在编写 SQL 时出现的小问题&#xff1a; 理解业务需求&#xff1a; 在开始编写 SQL 之前&#xff0c;确保你完全理解了业务…

鄂州职业大学2024年成人高等继续教育招生简章

鄂州职业大学&#xff0c;作为一所享有盛誉的高等学府&#xff0c;一直以来都致力于为社会培养具备专业技能和良好素养的优秀人才。在成人高等继续教育领域&#xff0c;该校同样表现出色&#xff0c;为广大渴望继续深造、提升自身能力的成年人提供了宝贵的学习机会。 随着社会…

【C语言】12.指针与数组的关系

一、数组名的理解 #include <stdio.h> int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };printf("&arr[0] %p\n", &arr[0]);printf("arr %p\n", arr);return 0; }通过上述代码输出结果我们发现结果相同&#xff0c;因此我们得出结论&a…

李宏毅深度学习03——神经网络训练不起来怎么办

视频链接 如果Optimization失败的时候&#xff0c;怎么把梯度下降做的更好&#xff1f; 只考虑这种情况&#xff0c;不考虑overfitting 局部最小值&#xff08;local minima&#xff09;和鞍点&#xff08;saddle point&#xff09; 为什么Optimization会失败&#xff1f; …

南京邮电大学计算机网络实验一(网络操作系统的安装与配置)

文章目录 一、 实验目的和要求二、 实验环境(实验设备)三、 实验原理和步骤四、 实验小结&#xff08;包括问题和解决方法、心得体会、意见与建议等&#xff09;&#xff08;一&#xff09;问题和解决方法&#xff08;二&#xff09;心得体会&#xff08;三&#xff09;意见与建…