mybatis-plus (3.4.2)使用
快速入门
官方文档快速入门案例
配置日志
# 配置日志mybatis-plus:configuration:# 配置 mybatis-plus执行的日志类型(可以看到执行过程) 下面是使用了控制台输出 sl4j log4j 等等都可以log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
效果
CRUD扩展
数据库中未指定id自增方式 我们可以通过mybatis-plus 来生成
插入一条数据
User user = new User();
user.setAge(3);
user.setName("xiuyuan");
user.setEmail("155645xxxx@qq.com");userMapper.insert(user);System.out.println(user);
你会发现,我们虽然没有指定id,但是他会自动给我们生成id,并赋给了user
数据库插入的id的默认值为:全局的唯一id
主键生成策略
分布式系统唯一Id生成方案汇总
Twitter的snowflake(雪花)算法
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。
mybatis-plus 默认主键生成方案 ID_WORKER
我们可以通过 @TableId 指定主键生成方式
public class User {@TableId(type = IdType.ID_WORKER)private Long id;private String name;private Integer age;private String email;
IdType
public enum IdType {AUTO(0), // 数据库id自增NONE(1), // 未设置主键INPUT(2), //手动输入ID_WORKER(3), // 默认的全局唯一idUUID(4), // 全局唯一id uuidID_WORKER_STR(5); // ID_WORKER 字符串表示法private int key;private IdType(int key) {this.key = key;}public int getKey() {return this.key;}
}
更新操作
@Testvoid update(){User user = new User();user.setId(2L);user.setAge(20);// 自动支持 动态sql(会自动判断 属性是否为''或null)int i = userMapper.updateById(user);}
从更新操作中 你会发现它是支持动态sql判断的(填充动态sql)。
自动填充
创建时间和修改时间!这些操作一般都是自动化完成的,我们不希望手动更新!
方式一 数据库级别(工作中不推荐)
方式二 代码级别
自动填充功能入门
1、实体类上添加填充注解
// 字段添加填充内容@TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;
2、编写一个处理器来处理注解
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {// 插入时填充的操作@Overridepublic void insertFill(MetaObject metaObject) {// 方法签名 MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}// 更新时填充的操作@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime",new Date(),metaObject);}
}
测试一下
乐观锁
mybaits-plus乐观锁官方文档
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
1、给数据库中增加version字段
2、我们的实体类同步字段
// mybatis-plus 的乐观锁 Version注解
@Version
private Integer version;
@Version 说明:
支持的数据类型只有:
int,Integer,long,Long,Date,Timestamp,LocalDateTime
整数类型下newVersion = oldVersion + 1
newVersion 会回写到 entity 中
仅支持 updateById(id) 与 update(entity, wrapper) 方法
在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
3、配置乐观锁插件(新版本已失效)
新版本已失效
@MapperScan("com.zlf.mapper")
@Configuration
public class mybatisPlusConfig {@Beanpublic OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor(){return new OptimisticLockerInnerInterceptor();}
}
新版本
@MapperScan("com.zlf.mapper")
@Configuration
public class mybatisPlusConfig {/*** 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 配置 乐观锁拦截器OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);return interceptor;}@Beanpublic ConfigurationCustomizer configurationCustomizer() {return configuration -> configuration.setUseDeprecatedExecutor(false);}
}
测试
/*** 测试乐观锁失败(模拟多线程)*/@Testvoid testLock2(){// 1、查询用户信息User user = userMapper.selectById(1L);// 2、修改用户信息user.setEmail("cccc@abc");user.setAge(18);User user2 = userMapper.selectById(1L);user.setName("小白");// 插队修改userMapper.updateById(user2);userMapper.updateById(user);}
查询操作
基础查询
/*** 测试查询*/@Testvoid testSelect(){// 查询一个User user = userMapper.selectById(1L);// 查询多个 方法签名 List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);List<User> users = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));// 条件查询之一 selectByMapHashMap<String, Object> map = new HashMap<>();map.put("name","小白"); // key 是列名 value 是要查询的值map.put("age",18); // 多个条件之间是 andList<User> users1 = userMapper.selectByMap(map);}
分页查询
1、配置分页拦截器
/*** 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//分页拦截器interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 配置 乐观锁拦截器OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);return interceptor;}
2、直接使用Page对象
@Testvoid testPage(){// 参数一:当前页,参数二:显示条数Page<User> page = new Page<>(1,5);// 分页查询Page<User> userPage = userMapper.selectPage(page, null);// 获取记录 getRecords()userPage.getRecords().forEach(System.out::println);}
测试结果
删除操作
@Testvoid testDelete(){// 通过id删除一条记录userMapper.deleteById(1L);// 通过id集合删除整个集合对应记录userMapper.deleteBatchIds(Arrays.asList(2L,3L));// 通过条件删除 条件之间为 andMap<String, Object> map = new HashMap<>();map.put("name","小黑");map.put("age",18);userMapper.deleteByMap(map);}
逻辑删除
逻辑删除官方文档
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效!
类似管理员查看被删除的记录。防止数据的丢失,类似于回收站!
1、在数据表中添加一个字段deleted
2、在实体类中添加属性
@TableLogic //逻辑删除注解private Integer deleted;
3、配置
mybatis-plus:global-config:db-config:# 配置逻辑删除logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略@TableLogic)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
测试
@Testvoid testDelete(){// 通过id删除一条记录userMapper.deleteById(2L);}
你会发现 删除变成了更新deleted 的值了
数据库中
我们再来查询一下
@Testvoid testLock(){// 1、查询用户信息User user = userMapper.selectById(2L);System.out.println(user);}
已经查不到了 sql中会过滤 deleted=0 的
性能分析插件
旧版本就不说了。
新版本在 执行 SQL 分析打印官方文档
条件构造器
条件构造器官方文档
代码自动生成器
这边使用的版本是3.4.1
<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>
代码生成器官方文档
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;@SpringBootTest
class MallApplicationTests {@Testvoid contextLoads() {}@Testpublic void run() {// 1、创建代码生成器AutoGenerator mpg = new AutoGenerator();// 2、全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");gc.setOutputDir(projectPath + "/src/main/java");gc.setAuthor("zlf");gc.setOpen(false); //生成后是否打开资源管理器gc.setFileOverride(false); //重新生成时文件是否覆盖gc.setServiceName("%sService"); //去掉Service接口的首字母Igc.setIdType(IdType.ID_WORKER); //主键策略gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型gc.setSwagger2(true);//开启Swagger2模式mpg.setGlobalConfig(gc);// 3、数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/数据库名");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("xxxx");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);// 4、包配置PackageConfig pc = new PackageConfig();pc.setModuleName("mall"); //模块名pc.setParent("com");// com.zlf.edu.controllerpc.setController("controller");pc.setEntity("entity");pc.setService("service");pc.setMapper("mapper");mpg.setPackageInfo(pc);// 5、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setInclude("表名");strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作strategy.setRestControllerStyle(true); //restful api风格控制器strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符strategy.setLogicDeleteFieldName("is_deleted");// 自动填充配置TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);TableFill gmtModified = new TableFill("gmt_modified",FieldFill.INSERT_UPDATE);ArrayList<TableFill> tableFills = new ArrayList<>();tableFills.add(gmtCreate);tableFills.add(gmtModified);strategy.setTableFillList(tableFills);mpg.setStrategy(strategy);// 6、执行mpg.execute();}}
推荐B站Up狂神
良心up主,强烈推荐!!
mybatis-plus (3.4.2)使用相关推荐
- mybatis查询报错:com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string
mybatis查询报错: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from strin ...
- MyBatis的插入后获得主键的方式
需求: 使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法: 在mapper中指定keyProperty属性,示例如下: <insert id=" ...
- mybatis使用注解开发
mybatis使用注解开发 面向接口编程 在之前我们是通过面向对象编程,但是在真正开发的时候我们会选择面向接口编程. 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的 ...
- mybatis ResultMap
ResultMap 解决属性名和字段的名称不一致的问题. 查询为null的问题 创建java实体类: public class User {private int id; //idprivate St ...
- mybatis配置文件解析
mybatis配置文件解析 mybatis核心配置文件`mybatis-config.xml文件. mybatis的配置文件包含了会深深影响mybatis行为的设置和属性信息. 能配置的内容: con ...
- mybatis CRUD操作
mybatis CRUD操作 select select标签是mybatis最常用的标签之一. select语句有很多属性可以详细的配置每一天sql语句. id 命名空间唯一的标识. 接口中的方法名与 ...
- java mybatis基础
java mybatis基础 1.1 什么是mybatis? mybatis是一个优秀的持久层框架. 避免几乎所有的JDBC代码和手动设置参数以及获取结果集的过程. 可以使用简单的xml或者注解来配置 ...
- mybatis的资源过滤错误及xml文件编码错误
mybatis 解决maven项目内资源过滤的问题 写的配置文件无法被导出或者生效的问题. 解决方案: <build><resources><resource>&l ...
- Mybatis传递多个参数的4种方式
现在大多项目都是使用Mybatis了,但也有些公司使用Hibernate.使用Mybatis最大的特性就是sql需要自己写,而写sql就需要传递多个参数.面对各种复杂的业务场景,传递参数也是一种学问. ...
- SpringBoot (五) :SpringBoot整合mybatis
说在前面 mybatis刚开始使用的时候比较麻烦,需要各种配置文件.实体类.dao层映射关联.还有一大推其它配置.初期开发了generator可以根据表结果自动生产实体类.配置文件和dao层代码,可以 ...
最新文章
- 听说又有兄弟因为用YYYY-MM-dd 被锤了...
- 面对 iPad,Surface 的键盘是必杀技
- 华北电力大学保定校区计算机专业,华北电力大学保定校区本科计算机科学与技术_华北电力大学保定校区本科计算机科学与技术简介-查字典学校网...
- JDBC连接MySQL
- Android中对手机文件进行读写
- 发布 ASP.NET Core 应用
- Nginx 500错误总结
- MATLAB二次规划和整数规划
- 认识网络、几种常用的网络拓扑图
- java实现表白动图
- 密码重置用HTML怎么弄,win10密码重置盘怎么弄-win10创建密码重置盘的方法 - 河东软件园...
- Unity3d游戏中实现阿拉伯语文字正常显示
- Nginx编译安装及配置文件详解
- SELECT连表查询重复字段
- 测试的职责是什么,就是不当背锅侠
- CISCO内网客户端软件anyconnect-win安装下载
- 网页导出Excel文件并下载
- S5PV210(TQ210)裸机编程
- 1. MySQL练习题
- 计算机图形学学习笔记——Whitted-Style Ray Tracing(GAMES101作业5讲解)