Mybatis Plus使用教程
Mybatis-Plus
快速开始
- 创建数据库和表
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) );
- 向数据库中添加数据
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项目并添加依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>Latest Version</version> </dependency>
- 配置数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # mysql 8 需要配置时区,不然会出现启动报错的情况 serverTimezone=GMT%2B8 spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&useSSL=true&useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=233031
- 编写实体类
/*用户实体类*/ public class User { private Long id; private String name; private Integer age; private String email; //构造方法 //GET、Set方法 }
- 编写UserMapper
/*在对应的Mapper上面继承基本的类 BaseMapper*/ @Repository public interface UserMapper extends BaseMapper<User> { /*所有的CRUD已经编写完成*/ } //写@Repository注解,需要在主类添加MapperScan扫描mapper包 //写@Mapper则不需要
配置日志
在启动@Test需要显示Sql的细节需要配置日志
#配置日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
CRUD扩展
插入操作(insert)
//测试插入 @Test public void testInsert(){ User user = new User(); user.setName("派大星学Java"); user.setAge(16); user.setEmail("none-j@qq.com"); int insert = userMapper.insert(user);//帮我们自动生成id System.out.println(insert);//受影响的行数 System.out.println(user);//发现,id会自动回填 }
数据库插入的id的默认值为:全局的唯一id
主键生成策略
默认 ID_WORKER 全局唯一
- 雪花算法:snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID),最后有一个符号,永远是0。可以保证几乎是全球唯一!
主键自增
我们需要配置主键自增:
- 实体类字段上
@TableId(type = IdType.AUTO)
- 数据库字段一定要是自增!
其他主键策略
IdType.AUTO //数据库id自增 IdType.NONE //未设置主键 IdType.INPUT //手动输入,一旦手动输入id之后,就需要自己设置id了 IdType.ASSIGN_ID //分布式ID策略,生成的主键是32位的字符串,不能排序 IdType.ASSIGN_UUID //分布式ID策略,生成的是Long类型的数字,可排序,跟服务器时间有关系,类似雪花算法。 IdType.ID_WORKER //默认的全局唯一id IdType.UUID //全局唯一id UUID IdType.ID_WORKER_STR //ID_WORKER 字符串表示法
简化配置
如果要在项目中的每一个模型类上都需要使用相同的生成策略,稍微比较繁琐,我们可以在配置文件中添加内容来使用统一的配置:
mybatis-plus: global-config: db-config: id-type: assign_id
配置完成之后,每个模型的注解ID策略都将成为assign_id
数据库表与模型关系的映射关系
MP会默认将模型类的类名首字母小写作为表名使用,假如数据库名称都以tbl_开头,那么我们就需要将所有的模型类上添加@TableName,配置起来还是比较繁琐,简化方式可以在配置文件中配置如下内容:
mybatis-plus: global-config: db-config: table-prefix: tbl_
设置前缀的内容,这样MP就会拿tbl_加上模型类的首字母小写,就刚好组装成数据库的表名。
更新操作(update)
//更新操作 @Test public void updateTest(){ User user = new User(); user.setId(5L); user.setName("我想创建公众号"); user.setAge(16); int i = userMapper.updateById(user); System.out.println(i); }
自动填充
创建时间、修改时间!这些个操作一遍都是自动化完成的,我们 不希望手动更新!
阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化!
方式一:数据库级别(工作中不允许更改数据库)
给时间字段增加默认值,
方式二:代码级别
- 删除数据库中的默认值、更新操作!
- 实体类字段属性需要增加注解
//字段添加填充内容 @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
- 编写处理器来处理这个注解即可!
@Component public class MyDateObjectHandler implements MetaObjectHandler { //插入时的填充策略 @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } //更新时的填充策略 @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime",new Date(),metaObject); } }
乐观锁
乐观锁:故名思议十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出了问题,再次更新值测试
悲观锁:故名思议十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
--A update user set name = "wumao",version = version + 1 where id = 2 and version = 1 --B 线程抢先完成,这个时候 version = 2,会导致A修改失败 update user set name = "wumao",version = version + 1 where id = 2 and version = 1
MP的乐观锁插件
- 给数据库中加入version字段
- 给实体类加上对应的字段
@Version //乐观锁Version的注解 private Integer version;
- 注册组件
@MapperScan("com.pdx.mapper") //扫描mapper文件夹 @EnableTransactionManagement @Configuration //配置类 public class MyBatisPlusConfig { @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
- 测试乐观锁
//测试乐观锁 //成功案例 @Test public void versionTest(){ User user = userMapper.selectById(1L); user.setName("派大星"); user.setEmail("admin@qq.com"); userMapper.updateById(user); } //乐观锁失败案例----多线程 @Test public void OptimisticLockerTest(){ User user = userMapper.selectById(1L); user.setName("派大星111"); user.setEmail("admin@qq.com"); //模拟另外一个线程执行了插队操作 User user2 = userMapper.selectById(1L); user.setName("派大星222"); user.setEmail("admin@qq.com"); userMapper.updateById(user2); userMapper.updateById(user); }
查询操作
//查询操作 @Test public void testSelect(){ User user = userMapper.selectById(1L); System.out.println(user); } //批量查询 @Test public void testBatchList(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println); } //按条件查询 map操作 @Test public void testSelectMap(){ HashMap<String, Object> map = new HashMap<>(); map.put("name","派大星"); map.put("age",16); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }
分页查询
- 原始的limit 进行分页
- pageHelper 第三方插件
- MP内置了分页插件
使用
- 配置拦截器
//分页插件 @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
- 分页查询
//分页查询 @Test public void PageTest(){ //参数一:当前页 //参数二:页的大小 //使用了分页插件之后,所有的分页操作也变得简单! Page<User> page = new Page<>(1,5); IPage<User> pages = userMapper.selectPage(page, null); pages.getRecords().forEach(System.out::println); }
删除操作
//删除操作 @Test public void deletTest(){ userMapper.deleteById(1398260764485095426L); } //批量删除 @Test public void deletBatchTest(){ userMapper.deleteBatchIds(Arrays.asList(1398201429172178946L,5)); } @Test public void deletByMap(){ HashMap<String, Object> map = new HashMap<>(); map.put("name","我想创建公众号"); userMapper.deleteByMap(map); }
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量让他无效!delete = 0 —> delete = 1
MP中的逻辑删除配置
- 在数据库中增加一个deleted字段
- 在pojo中增加新的属性
@TableLogic //逻辑删除 private Integer deleted;
- 配置
@Bean //逻辑删除组件 public ISqlInjector sqlInjector(){ return new LogicSqlInjector(); }
#配置逻辑删除 1 删除 0 未删除 mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
- 测试
//逻辑删操作 @Test public void deleteLogic(){ int i = userMapper.deleteById(1L); System.out.println(i); }
性能分析插件
我们在平时的开发中,会遇到一些慢SQL,测试!Druid…
作用:性能分析拦截器,用于输出每条SQL语句及其执行时间
MP也提供了性能分析插件,如果超过这个时间就停止运行!
- 导入插件
/* * SQL执行效率插件 * */ @Bean @Profile({"dev","test"})//设置dev test 环境开启,保证我们的效率 public PerformanceInterceptor performanceInterceptor(){ PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); performanceInterceptor.setMaxTime(100);//ms 设置SQL执行的最大时间,如果超过了则不执行 performanceInterceptor.setFormat(true);//是否格式化代码 return performanceInterceptor; }
记住,要在SpringBoot中配置环境为dev或者test环境
- 测试
@Test void contextLoads() { List<User> users = userMapper.selectList(null); for (User user : users) { System.out.println(user); } }
条件构造器(十分重要)
构造器分很多种,有Wrapper、QueryWrapper、LambdaQueryWrapper等
Demo1:
@Test public void wapperTest(){ //查询name不为空的用户,并且邮箱不为空的用户,年龄大于12 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.isNotNull("name").isNotNull("email").ge("age", 12); userMapper.selectList(wrapper).forEach(System.out::println); }
Demo2:
@Test void test2(){ //查询名字为五毛 LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getName, "派大星"); User user = userMapper.selectOne(wrapper); System.out.println(user); }
不列举太多,其他请参考下图
select 设置需要查询的字段
例: 指定查询主键,名字,年龄字段
select("id", "name", "age")
例: 查询以test开头的属性
select(i ‐> i.getProperty().startsWith("test"))
例:查询User对象中出除manager_id和create_time外其它所有字段的数据
select(User.class, info ‐> !info.getColumn().equals("manager_id") && !info.getColumn().equals("create_time"))
本文作者:Mr·Shi
本文链接:https://www.cnblogs.com/shijiangtao/p/17124654.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步