MyBatisPlus详解
mybatisplus详解
官网链接:
简介
mybatis-plus(简称 mp)是一个 mybatis 的增强工具,在 mybatis
的基础上只做增强不做改变,为简化开发、提高效率而生。
mybatis 最好的搭档,就像 魂斗罗 中的 1p、2p,基友搭配,效率翻倍。
为什么要学习它呢?
mybatisplus可以节省我们大量工作时间,所有的crud代码它都可以自动化完成!
特性
支持数据库
架构
快速开始
- 创建user表
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');
- 创建springboot项目,导入依赖
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.2.6.release</version> <relativepath/> </parent> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <optional>true</optional> </dependency> <dependency> <groupid>com.baomidou</groupid> <artifactid>mybatis-plus-boot-starter</artifactid> <version>3.3.1.tmp</version> </dependency> <dependency> <groupid>com.h2database</groupid> <artifactid>h2</artifactid> <scope>runtime</scope> </dependency> </dependencies>
3. 配置 连接数据库
spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/mybatis_plus?useunicode=true&characterencoding=utf-8&servertimezone=utc&usessl=false driver-class-name: com.mysql.cj.jdbc.driver
- 编写实体类
@data public class user { private long id; private string name; private integer age; private string email; }
- 编写mapper类
public interface usermapper extends basemapper<user> { }
- 创建启动类
@springbootapplication @mapperscan("com.mybatisplus.mybatisplus.mapper") public class mybatisplusapplication { public static void main(string[] args) { springapplication.run(mybatisplusapplication.class, args); } }
- 测试
查询全部用户
@springboottest class mybatisplusapplicationtests { @autowired usermapper mapper; @test void contextloads() { list<user> users = mapper.selectlist(null); users.foreach(system.out::println);//打印输出 } }
通过以上几个简单的步骤,我们就实现了 user 表的 crud 功能,甚至连 xml 文件都不用编写!
从以上步骤中,我们可以看到集成mybatis-plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。
但 mybatis-plus 的强大远不止这些功能,想要详细了解 mybatis-plus 的强大功能?那就继续往下看吧!(官网原话)
配置日志
所以的sql不可见,我们需要观看sql是怎么执行的
#mybatis日志配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.stdoutimpl
crud拓展
insert插入
@test public void testinsert(){ user u=new user(); u.setname("joker_dj"); u.setage(18); u.setemail("2332810801@qq.com"); mapper.insert(u); }
id会自动生成
常见的id生成有
id生成策略
博客:
雪花算法
自增id:对于数据敏感场景不宜使用,且不适合于分布式场景。
guid:采用无意义字符串,数据量增大时造成访问过慢,且不宜排序。
最高位是符号位,始终为0,不可用。
41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。
10位的机器标识,10位的长度最多支持部署1024个节点。
12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个id序号,12位的计数序列号支持每个节点每毫秒产生4096个id序号。
原文:
测试不同的主键自增策略
自增策略
public enum idtype { auto(0),//主键自增 none(1),//不使用 input(2),//手动输入 id_worker(3),//默认全局唯一id uuid(4),//全局唯一id uuid id_worker_str(5);//字符串表示法 }
update更新
自动填充
创建时间、修改时间、这些操作是自动化完成的,我们不希望手动更新
阿里巴巴手册:所有数据表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化!
方式一:数据库级别
- 在表中新增字段 create_time, update_time
再次测试,同步实体类
运行测试
方式二:代码级别
- 删除数据库的默认值
- 实体类上增加注解
- 编写handler策略
@slf4j @component public class mymetaobjecthandler implements metaobjecthandler { /*插入时的填充策略*/ @override public void insertfill(metaobject metaobject) { log.info("填充....");//setfieldvalbyname(string fieldname, object fieldval, metaobject metaobject) this.setfieldvalbyname("createtime",new date(),metaobject); this.setfieldvalbyname("updatetime",new date(),metaobject); } /*更新时的填充策略*/ @override public void updatefill(metaobject metaobject) { log.info("更新...."); this.setfieldvalbyname("updatetime",new date(),metaobject); } }
乐观锁
在面试过程中,我们经常会被问道乐观锁,悲观锁!这个其实非常简单!
乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题, 再次更新值测试
悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newversion where version = oldversion
如果version不对,就更新失败
测试mybatisplus的乐观锁
添加字段 默认值为1
同步实体类
配置乐观锁
@enabletransactionmanagement @configuration public class config { @bean public optimisticlockerinterceptor optimisticlockerinterceptor() { return new optimisticlockerinterceptor(); } }
测试乐观锁成功案例
会发现更新操作时默认带上version
失败案例
第二次修改并没有成功
select查询操作
@test public void testselect01(){//查询单个用户 user user = mapper.selectbyid(1l); system.out.println(user); } @test public void testselect02(){//查询多个用户 批量查询 list<user> users = mapper.selectbatchids(arrays.aslist(1, 2, 3)); users.foreach(system.out::println); } //条件查询 map方式 @test public void testselect03(){ hashmap<string, object> map = new hashmap<>(); map.put("name","joker_dj2");//查询字段name为joker_dj2的结果 map.put("age",18);//查询字段age为18的值 //... list<user> users = mapper.selectbymap(map); system.out.println(users); }
分页查询
分页插件有很多
- 原始的limit进行1分页
- pagehelper第三方插件
- mybatisplus内置插件
如何使用
配置config
//分页插件 @bean public paginationinterceptor paginationinterceptor() { return new paginationinterceptor(); }
直接使用即可
//分页插件 @test public void testpage(){ //参数一:当前页 //参数二:页面大小 page<user> objectpage = new page<>(1, 5);//第1页,5行数据 mapper.selectpage(objectpage, null);//分页查询 条件为null objectpage.gettotal();//获取总记录数 objectpage.getrecords();//获取数据 objectpage.getrecords().foreach(system.out::println);//打印输出 }
删除操作
//删除操作 根据id删除 单个 @test public void testdelete(){ mapper.deletebyid(5l); } @test//批量删除 public void testdelete02(){ mapper.deletebatchids(arrays.aslist(1,2,3));//删除id为1 2 3 的用户 } //通过map操作 @test public void testmapdelete(){ hashmap<string, object> map = new hashmap<>(); map.put("name","joker_dj2");//删除name为joker_dj2的用户 mapper.deletebymap(map); }
逻辑删除
- 物理删除:从数据库直接移除
- 逻辑移除:在数据库中没有直接删除,而是通过一个变量让他失效
场景:
管理员可以查看被删除的数据,防止数据丢失,类似于回收站
使用:
3. 在数据库中增加一个delete字段 默认值为0
- 实体类同步
- 配置逻辑删除
测试删除
可以看到,测试的是删除操作,实际上走的是更新操作,并不是删除操作
测试查询 会跟上where deleted=0的sql 非管理员
性能分析插件
我们在平时的开发中,会遇到一些慢sql。测试! druid,,,,,
作用:性能分析拦截器,用于输出每条 sql 语句及其执行时间
mybatisplus也提供性能分析插件,如果超过这个时间就停止运行!
使用
-
导入插件
-
配置项目为测试环境
条件构造器
wrapper十分重要
复杂的sql就靠它
使用
- 判断空
//查询name不为空,并且邮箱不为空的用户,年龄大于18的用户 @test public void testwrapper(){ querywrapper<user> wrapper = new querywrapper<>(); wrapper .isnotnull("name")//查询不为空的用户 .isnotnull("email")//箱不为空 .ge("age",19);//年龄大于18的用户 19>18 ; mapper.selectlist(wrapper); }
2. 等于,模糊查询
@test public void test01(){//查询一个name等于joker_dj的用户 querywrapper<user> wrapper = new querywrapper<>(); wrapper.eq("name","joker_dj"); mapper.selectone(wrapper); } @test public void test02(){//查询年龄在18-21的用户个数 querywrapper<user> wrapper = new querywrapper<>(); wrapper.between("age",18,21); integer integer = mapper.selectcount(wrapper); system.out.println(integer); } @test public void test03(){//模糊查询 querywrapper<user> wrapper = new querywrapper<>(); wrapper .notlike("name","j")//查询姓名不包含j的用户 .likeright("email","t") //左和右likeleft '%t' likeright 't%' ; list<map<string, object>> maps = mapper.selectmaps(wrapper); maps.foreach(system.out::println); }
- 子查询
- 排序
代码生成器
dao、pojo、service、controller都给我自己去编写完成!
autogenerator 是 mybatis-plus 的代码生成器,通过 autogenerator 可以快速生成 entity、
mapper、mapper xml、service、controller 等各个模块的代码,极大的提升了开发效率。
- 导入依赖
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.2.6.release</version> <relativepath/> </parent> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <optional>true</optional> </dependency> <!--mybatis和mybatisplus最好只导入其中一个--> <dependency> <groupid>com.baomidou</groupid> <artifactid>mybatis-plus-boot-starter</artifactid> <version>3.0.5</version> </dependency> <dependency> <groupid>com.baomidou</groupid> <artifactid>mybatis-plus-generator</artifactid> <version>3.2.0</version> </dependency> <dependency> <groupid>org.apache.velocity</groupid> <artifactid>velocity-engine-core</artifactid> <version>2.1</version> </dependency> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>8.0.19</version> </dependency> </dependencies>
- 编写生成器代码
public static void main(string[] args) { // 需要构建一个 代码自动生成器 对象 autogenerator mpg = new autogenerator(); // 配置策略 // 1、全局配置 globalconfig gc = new globalconfig(); string projectpath = system.getproperty("user.dir");//获取目录 gc.setoutputdir(projectpath + "/src/main/java");//输出目录 gc.setauthor("joker_dj");//设置作者 gc.setopen(false);//是否打开资源管理器 gc.setfileoverride(false); // 是否覆盖 gc.setservicename("%sservice"); // 去service的i前缀 gc.setidtype(idtype.auto);//设置主键的算法 //对应数据的主键(uuid,自增id,雪花算法,redis,zookeeper) gc.setdatetype(datetype.only_date);//日期类型 gc.setswagger2(true);//是否配置swagger2 mpg.setglobalconfig(gc); //2、设置数据源 datasourceconfig dsc = new datasourceconfig(); dsc.seturl("jdbc:mysql://localhost:3306/mybatis_plus?usessl=false&useunicode=true&characterencoding=utf-8&servertimezone=gmt%2b8"); dsc.setdrivername("com.mysql.cj.jdbc.driver"); dsc.setusername("root"); dsc.setpassword("123456"); dsc.setdbtype(dbtype.mysql);//配置数据库类型 mysql mpg.setdatasource(dsc); //3、包的配置 packageconfig pc = new packageconfig(); pc.setmodulename("codegeneration");//模块名称 pc.setparent("com.dj");//配置工程包名称 pc.setentity("entity");//配置entity的包名 pc.setmapper("mapper");//配置mapper的包名 pc.setservice("service");//配置service的包名 pc.setcontroller("controller");//配置controller的包名 mpg.setpackageinfo(pc);//配置包 //4、策略配置 strategyconfig strategy = new strategyconfig(); strategy.setinclude("user"); ////设置映射的表名 多个表strategyconfig.setinclude("user","cloud","..."); strategy.setnaming(namingstrategy.underline_to_camel); strategy.setcolumnnaming(namingstrategy.underline_to_camel);//字段名转驼峰命名 strategy.setentitylombokmodel(true); // 自动lombok; strategy.setlogicdeletefieldname("deleted");//逻辑删除的字段名称 // 自动填充配置 tablefill create_time = new tablefill("create_time", fieldfill.insert);//自动填充更新的字段 tablefill update_time = new tablefill("update_time", fieldfill.insert_update);//自动更新的字段 arraylist<tablefill> tablefills = new arraylist<>(); tablefills.add(create_time);//创建的策略 tablefills.add(update_time);//更新的策略 strategy.settablefilllist(tablefills); // 乐观锁 strategy.setversionfieldname("version"); strategy.setrestcontrollerstyle(true); strategy.setcontrollermappinghyphenstyle(true); mpg.setstrategy(strategy); mpg.execute(); //执行 }