MyBatis-Plus快速入门
1、简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
- 润物无声
只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。 - 效率至上
只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间。 - 丰富功能
热加载、代码生成、分页、性能分析等功能一应俱全。
2、创建并初始化数据库
2.1 创建数据库
- mybatis_plus
2.2 创建 User 表
其对应的数据库 Schema 脚本如下:
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)
);
其对应的数据库 Data 脚本如下:
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');
3、引入依赖
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency><!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
4、编写代码
在 application.properties 配置文件中添加 MySQL 数据库的相关配置:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
注意:
- 1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为8.0版本的jdbc驱动需要添加这个后缀,否则运行测试用例报告如下错误:
java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more - 2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,否则运行测试用例的时候会有 WARN 信息
4.1 启动类
在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹
@SpringBootApplication
@MapperScan("com.atguigu.demomptest.mapper")
public class DemomptestApplication {public static void main(String[] args) {SpringApplication.run(DemomptestApplication.class, args);}}
4.2 添加实体
创建包 entity 编写实体类 User.java(此处使用了 Lombok 简化代码)
@Data
public class User {private Long id;private String name;private Integer age;private String email;
}
4.3 添加mapper
创建包 mapper 编写Mapper 接口: UserMapper.java
@Repository
public interface UserMapper extends BaseMapper<User> {}
此处的BaseMapper父类是由mybatis-plus实现的的基础数据库操作类,User是需要操作的类型
4.4 查看sql输出日志
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
4.5 注意
本教程直接使用mapper操作数据库实现,如需使用service,还需构建以下类
public interface UserService extends IService<User> {}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements HospitalSetService {}
5、主键策略
5.1 添加操作
//添加
@Test
public void testAdd() {User user = new User();user.setName("lucy");user.setAge(20);user.setEmail("1243@qq.com");int insert = userMapper.insert(user);System.out.println(insert);
}
注意:数据库插入id值默认为:全局唯一id
5.2 MP的主键策略
5.3 ASSIGN_ID
MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)
@TableId(type = IdType.ASSIGN_ID)
private String id;
- 雪花算法:分布式ID生成器
- 雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。
- 核心思想:
- 长度共64bit(一个long型)。
- 首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。
- 41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。
- 10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。
- 12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。
优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。
5.4 AUTO 自增策略
需要在创建数据表的时候设置主键自增
实体字段中配置 @TableId(type = IdType.AUTO)
要想影响所有实体的配置,可以设置全局主键配置
#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
5.5 其他策略
6、自动填充和乐观锁
6.1 更新操作
注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?
//修改
@Test
public void testUpdate() {User user = new User();user.setId(1340868235401764865L);user.setName("lucymary");int count = userMapper.updateById(user);System.out.println(count);
}
6.2 自动填充
需求描述:
项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作
- 数据库修改
在User表中添加datetime类型的新的字段 create_time、update_time - 实体类修改
实体上增加字段并添加自动填充注解
@TableField(fill = FieldFill.INSERT)
private Date createTime; //create_time@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; //update_time
- 实现元对象处理器接口
注意:不要忘记添加 @Component 注解
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {//mp执行添加操作,这个方法执行@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}//mp执行修改操作,这个方法执行@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime",new Date(),metaObject);}
}
6.3 乐观锁
- 主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
接下来介绍如何在Mybatis-Plus项目中,使用乐观锁:
6.3.1 乐观锁实现流程
- 修改实体类
添加 @Version 注解
@Version
private Integer version;
- 创建配置文件
创建包config,创建文件MybatisPlusConfig.java
此时可以删除主类中的 @MapperScan 扫描注解
@Configuration
@MapperScan("com.atguigu.demomptest.mapper")
public class MpConfig {/*** 乐观锁插件*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}
}
- 注册乐观锁插件
在 MybatisPlusConfig 中注册 Bean
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();
}
7、查询
7.1 查询
7.1.1通过多个id批量查询
完成了动态sql的foreach的功能
//多个id批量查询
@Test
public void testSelect1() {List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));System.out.println(users);
}
7.1.2简单的条件查询
- 通过map封装查询条件
注意:map中的key对应数据库中的列名。如:数据库user_id,实体类是userId,这时map的key需要填写user_id
//简单条件查询
@Test
public void testSelect2() {Map<String, Object> columnMap = new HashMap<>();columnMap.put("name","Jack");columnMap.put("age",20);List<User> users = userMapper.selectByMap(columnMap);System.out.println(users);
}
7.2 分页
7.2.1 分页插件
MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
7.2.1.1 添加分页插件
配置类中添加@Bean配置
/*** 分页插件*/
@Bean
public PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();
}
7.2.1.2 测试selectPage分页
测试:最终通过page对象获取相关数据
//分页查询
@Test
public void testSelectPage() {Page<User> page = new Page(1,3);Page<User> userPage = userMapper.selectPage(page, null);//返回对象得到分页所有数据long pages = userPage.getPages(); //总页数long current = userPage.getCurrent(); //当前页List<User> records = userPage.getRecords(); //查询数据集合long total = userPage.getTotal(); //总记录数boolean hasNext = userPage.hasNext(); //下一页boolean hasPrevious = userPage.hasPrevious(); //上一页System.out.println(pages);System.out.println(current);System.out.println(records);System.out.println(total);System.out.println(hasNext);System.out.println(hasPrevious);
}
7.2.2测试selectMapsPage分页
- 当指定了特定的查询列时,希望分页结果列表只返回被查询的列,而不是很多null值
测试selectMapsPage分页:结果集是Map
@Test
public void testSelectMapsPage() {//Page不需要泛型
Page<Map<String, Object>> page = newPage<>(1, 5);
Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, null);
List<Map<String, Object>> records = pageParam.getRecords();
records.forEach(System.out::println);
System.out.println(pageParam.getCurrent());
System.out.println(pageParam.getPages());
System.out.println(pageParam.getSize());
System.out.println(pageParam.getTotal());
System.out.println(pageParam.hasNext());
System.out.println(pageParam.hasPrevious());
}
8、删除与逻辑删除
8.1 删除
8.1.1 根据id删除记录
@Test
public void testDeleteById(){int result = userMapper.deleteById(5L);
system.out.println(result);
}
8.1.2 批量删除
@Test
public void testDeleteBatchIds() {int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));
system.out.println(result);
}
简单条件删除
@Test
public void testDeleteByMap() {HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);int result = userMapper.deleteByMap(map);
system.out.println(result);
}
8.2 逻辑删除
8.2.1物理删除和逻辑删除
物理删除
:真实删除
,将对应数据从数据库中删除,之后查询不到此条被删除数据逻辑删除
:假删除
,将对应数据中代表是否被删除字段状态修改为“被删除状态”
,之后在数据库中仍旧能看到此条数据记录逻辑删除的使用场景:
可以进行数据恢复
有关联数据,不便删除
8.2.2 逻辑删除实现流程
8.2.2.1数据库修改
添加 deleted字段
ALTERTABLE user
ADD COLUMN deleted
boolean DEFAULT false
8.2.2.2 实体类修改
- 添加deleted 字段,并加上 @TableLogic 注解
@TableLogic
private Integer deleted;
8.2.2.3 配置(可选)
- application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
8.2.2.4 测试
- 测试后发现,数据并没有被删除,deleted字段的值由0变成了1
- 测试后分析打印的sql语句,是一条update
- 注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作
@Test
public void testLogicDelete() {int result = userMapper.deleteById(1L);
system.out.println(result);
}
8.2.2.5 测试逻辑删除后的查询
MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断
@Test
public void testLogicDeleteSelect() {List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
9、条件构造器和常用接口
9.1 wapper介绍
Wrapper : 条件构造抽象类,最顶端父类
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- QueryWrapper : 查询条件封装
- UpdateWrapper : Update 条件封装
- AbstractLambdaWrapper : 使用Lambda 语法
- LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
@SpringBootTest
publicclassQueryWrapperTests {@Autowired
privateUserMapperuserMapper;
}
9.2 查询方式
查询方式 | 说明 |
---|---|
setSqlSelect | 设置 SELECT 查询字段 |
where | WHERE 语句,拼接 + WHERE 条件 |
and | AND 语句,拼接 + AND 字段=值 |
andNew | AND 语句,拼接 + AND (字段=值) |
or | OR 语句,拼接 + OR 字段=值 |
orNew | OR 语句,拼接 + OR (字段=值) |
eq | 等于= |
allEq | 基于 map 内容等于= |
ne | 不等于<> |
gt | 大于> |
ge | 大于等于>= |
lt | 小于< |
le | 小于等于<= |
like | 模糊查询 LIKE |
notLike | 模糊查询 NOT LIKE |
in | IN 查询 |
notIn | NOT IN 查询 |
isNull | NULL 值查询 |
isNotNull | IS NOT NULL |
groupBy | 分组 GROUP BY |
having | HAVING 关键词 |
orderBy | 排序 ORDER BY |
orderAsc | ASC 排序 ORDER BY |
orderDesc | DESC 排序 ORDER BY |
exists | EXISTS 条件语句 |
notExists | NOT EXISTS 条件语句 |
between | BETWEEN 条件语句 |
notBetween | NOT BETWEEN 条件语句 |
addFilter | 自由拼接 SQL |
last | 拼接在最后,例如:last(“LIMIT 1”) |
9.3 测试用例
9.3.1 ge、gt、le、lt、isNull、isNotNull
@Test
public void testQuery() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.isNull("name").ge("age", 12).isNotNull("email");int result = userMapper.delete(queryWrapper);
System.out.println("delete return count = " + result);
}
9.3.2 eq、ne
注意:seletOne()返回的是一条实体记录,当出现多条时会报错
@Test
public void testSelectOne() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.eq("name", "Tom");
Useruser = userMapper.selectOne(queryWrapper);//只能返回一条记录,多余一条则抛出异常
System.out.println(user);
}
9.3.3 between、notBetween
包含大小边界
@Test
public void testSelectCount() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.between("age", 20, 30);Integer count = userMapper.selectCount(queryWrapper); //返回数据数量
System.out.println(count);
}
9.3.4 like、notLike、likeLeft、likeRight
selectMaps()返回Map集合列表,通常配合select()使用
@Test
public void testSelectMaps() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.select("name", "age").like("name", "e").likeRight("email", "5");
List<Map<String, Object>>maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
maps.forEach(System.out::println);
}
9.3.5 orderBy、orderByDesc、orderByAsc
@Test
public void testSelectListOrderBy() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.orderByDesc("age", "id");
List<User>users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
MyBatis-Plus快速入门相关推荐
- MyBatis之快速入门
MyBatis之快速入门 2017/9/30 首先我要明确告诉大家的是MyBatis是一个java持久层框架,以前我们都是用jdbc来将我们的java程序与数据库相连接,而MyBatis是对jdbc的 ...
- java day53【 Mybatis框架概述 、 Mybatis 框架快速入门、自定义 Mybatis 框架 】
第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种 定义认为,框架是可被应用开发者定 ...
- MyBatis框架快速入门
MyBatis框架快速入门 入门案例 创建一个关于Mybatis项目 首先创建一个空项目,然后新建一个moudle,选择quickstart,接下来把模块放到空项目之下.即可 实现mybatis查询数 ...
- MyBatis 01 快速入门
MyBatis 01 快速入门 文章目录 MyBatis 01 快速入门 一.学习目标 二.为什么需要框架技术 三.框架技术介绍 四.主流框架介绍 五.持久化与ORM 六.MyBatis简介 七.搭建 ...
- Mybatis(day1)快速入门
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法:另一种定义认为,框架是可被应用开发者定制的应用骨架.前者是从应用方面而后者是从目的方面给出的定义. 简 ...
- mybatis的快速入门
说明: 在这个部分,会写个简单的入门案例. 然后,会重新写一个,更加严格的程序案例. 一:案例一 1.最终的目录结构 2.新建一个普通的Java项目,并新建lib 在项目名上右键,不是src. 3.导 ...
- 第一:Java+MyBatis(快速入门)
MyBatis 简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...
- springboot 整合mybatis_SpringBoot整合MyBatis框架快速入门
MyBatis概述: mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动.创建连接.创建statemenet等繁 ...
- MyBatis:快速入门代码实例(maven代码版)
文章目录 1. MyBatis实例 1.1 添加Mybatis依赖 1.2 创建MyBatis配置文件 1.3.创建po类 1.4.创建映射文件 #{}: 表示sql参数,一个占位符. 1.5.测试 ...
- MyBatis从入门到精通(一)—MyBatis基础知识和快速入门
Mybatis简介 原始jdbc操作(查询数据) Connection connection = null;PreparedStatement preparedStatement = null;Res ...
最新文章
- 信号 09 | 信号概念
- java jdbc 增删改封装_JAVA JDBC 常规增删改查简单封装
- 无代码时代来临,程序员如何保住饭碗?赶紧看一看!
- 抽象数据类型和Python类的基础
- 字节跳动高工面试:mysql查询重复数据sql
- 用request.getParameterMap()获得jsp页面元素的集合出现[Ljava.lang.String;@的问题解决
- 给机器人罗宾写一封英语回信_小学英语人教(13版三起点)六年级上册Unit1
- Delphi 跨语言环境 乱码问题
- 本人考研的时间流程图
- 外地父母常住北京-医疗问题-新农合北京就医实时结算
- 蚂蚁区块链第9课 SSL/TLS工作原理及在蚂蚁BAAS中的应用
- 邮箱登录入口,163邮箱个人登录入口,163邮箱注册登录
- iis7无法写入配置文件,更换进入方式解决
- prctl()和pthread_setname_np()函数-设置线程名称
- 噪声种类及Matlab添加噪声
- 全球通史读书笔记上(第六章——古代文明的新起)
- Error 12154 received logging on to the standby
- 令人头秃的cudaTensorCoreGemm详解
- Firefox浏览器浏览自己做的网站需要输入用户名和密码解决
- Robosense速腾激光雷达如何使用多雷达