Java最全MyBatis-Plus学习使用(Springboot整合MyBatis-Plus),java后端面试问题

总结

虽然我个人也经常自嘲,十年之后要去成为外卖专员,但实际上依靠自身的努力,是能够减少三十五岁之后的焦虑的,毕竟好的架构师并不多。

架构师,是我们大部分技术人的职业目标,一名好的架构师来源于机遇(公司)、个人努力(吃得苦、肯钻研)、天分(真的热爱)的三者协作的结果,实践+机遇+努力才能助你成为优秀的架构师。

如果你也想成为一名好的架构师,那或许这份Java成长笔记你需要阅读阅读,希望能够对你的职业发展有所帮助。

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • entity包:用来放实体类

  • mapper包:用来放持久层接口

这里还需要让springboot扫描到mapper接口,在MybatisplusdemoApplication类中添加注解@MapperScan(“com.star.mapper”)

@SpringBootApplication

@MapperScan(“com.star.mapper”) //扫描到mapper接口

public class MybatisplusdemoApplication {…}

1.3.1 编写User实体类

package com.star.entity;

import lombok.Data;

/**

  • @Description: User实体类

  • @Date: Created in 11:54 2020/7/28

  • @Author: ONESTAR

  • @QQ群: 530311074

  • @URL: https://onestar.newstar.net.cn/

*/

@Data //可以简化实体类

public class User {

@TableId(type = IdType.AUTO)

private Long id;

private String name;

private Integer age;

private String email;

}

分析:

  • @Data注解:用于简化实体类,可以不用写get、set等方法
  • @TableId(type = IdType.AUTO)注解:这是主键策略注解
*   AUTO:表示自动增长策略
*   INPUT:表示需要自己设置ID,需要输入
*   NONE:表示没有策略,需要输入
*   UUID:随机生成唯一的值
*   ID\_WORKER:mybatisplus自带策略,生成19位的值,数字类型使用该策略
*   ID\_WORKER\_STR:mybatisplus自带策略,生成19位的值,字符串类型使用该策略

1.3.2 编写UserMapper接口

  • @Repository注解:可有可无,可以消去依赖注入的报错信息

package com.star.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import com.star.entity.User;

import org.springframework.stereotype.Repository;

/**

  • @Description: UserMapper接口

  • @Date: Created in 11:57 2020/7/28

  • @Author: ONESTAR

  • @QQ群: 530311074

  • @URL: https://onestar.newstar.net.cn/

*/

@Repository

public interface UserMapper extends BaseMapper {

}

1.3.3 编写测试类(简单增删改查)

编写好以上代码后,框架基本就搭建好了,可以在测试类中进行测试了,在test中添加测试,代码如下:

  • 注入mapper

@Autowired

private UserMapper userMapper;

  • 简单增删改查

//查询User

@Test

void findUser() {

//查询列表

List user = userMapper.selectList(null);

System.out.println(“user:” + user);

//根据ID查询

User user1 = userMapper.selectById(1L);

System.out.println(“user1:” + user1);

//通过多个ID批量查询

List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));

users.forEach(System.out::println);

//简单的条件查询

HashMap<String, Object> map = new HashMap<>();

map.put(“name”, “onestar”);

map.put(“age”, 18);

List users2 = userMapper.selectByMap(map);

users2.forEach(System.out::println);

}

//添加User

@Test

void addUser(){

User user = new User();

user.setName(“sixstar”);

user.setAge(18);

user.setEmail(“sixstar@136.com”);

int insert = userMapper.insert(user);

System.out.println(insert);

}

//修改User

@Test

void updateUser(){

User user = new User();

user.setId(1L);

user.setAge(12);

int result = userMapper.updateById(user);

System.out.println(result);

}

//删除User

@Test

void deleteUser(){

//根据ID删除

int result = userMapper.deleteById(5L);

System.out.println(result);

//批量删除

int result2 = userMapper.deleteBatchIds(Arrays.asList(1,2,3));

System.out.println(result2);

//简单的条件删除

HashMap<String,Object> map = new HashMap<>();

map.put(“name”,“fourstar”);

map.put(“age”,18);

int result3 = userMapper.deleteByMap(map);

System.out.println(result3);

}

分析:

这里基本上都是直接调用mybatisplus封装好了的方法,有一些基本的方法:

  • 查询列表:selectList
  • 根据ID查询:selectById
  • 根据ID批量查询:selectBatchIds
  • 条件查询:selectByMap
  • 添加:insert
  • 根据ID修改:updateById
  • 根据ID删除:deleteById
  • 根据ID批量删除:deleteBatchIds
  • 条件删除:deleteByMap

2. 提升案例


进阶案例主要讲以下几个知识点:

  • 分页查询

  • 自动填充

  • mybatisplus实现乐观锁

  • 逻辑删除

  • 性能分析

  • 复杂条件查询

2.1 分页查询

Mybatis-Plus是自带了分页查询功能的,直接使用自集成的插件进行分页查询,在使用之前要配置插件,可以专门创建一个配置类来配置插件

2.1.1 配置插件

在com.star包下创建config包,创建MpConfig配置类,添加分页插件

package com.star.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

  • @Description: 配置类

  • @Date: Created in 10:26 2020/7/29

  • @Author: ONESTAR

  • @QQ群: 530311074

  • @URL: https://onestar.newstar.net.cn/

*/

@Configuration

public class MpConfig {

/**

  • 分页插件

*/

@Bean

public PaginationInterceptor paginationInterceptor() {

return new PaginationInterceptor();

}

}

2.1.2 测试分页

//分页查询

@Test

void selectPage(){

//创建page对象(1:当前页;3:每页显示记录数)

Page page = new Page<>(1,3);

//调用分页查询方法,将分页所有数据封装到page对象里面

userMapper.selectPage(page,null);

//通过page对象获取分页数据

System.out.println(page.getCurrent()); //当前页

System.out.println(page.getRecords()); //每页数据list集合

System.out.println(page.getPages()); //总页数

System.out.println(page.getSize()); //每页显示记录数

System.out.println(page.getTotal()); //总记录数

System.out.println(page.hasNext()); //是否有下一页

System.out.println(page.hasPrevious()); //是否有上一页

}

分析:

  • 创建page对象:new Page<>(1,3); 参数表示当前页和每页显示记录数
  • 调用分页查询方法,将分页所有数据封装到page对象里面:selectPage(page,null);
  • 通过调用Mybatisplus插件提供的方法实现分页功能
*   page.getCurrent():当前页
*   page.getRecords():每页数据list集合
*   page.getPages():总页数
*   page.getSize():每页显示记录数
*   page.getTotal():总记录数
*   page.hasNext():是否有下一页
*   page.hasPrevious():是否有上一页

2.2 自动填充

在平时开发中,会有些数据需要自动填充,比如创建时间、更新时间等,这就可以使用MybatisPlus的自动填充功能,这里就以创建时间和更新时间为例进行演示

2.2.1 添加字段

User表中添加字段:

  • 创建时间:create_time

  • 更新时间:update_time

实体类添加属性和注解

@TableField(fill = FieldFill.INSERT)

private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)

private Date updateTime;

2.2.2 实现元对象处理器接口

这里专门创建一个hander包来访处理器接口,在com.star包下创建hander包,创建MyMetaObjectHandler接口

package com.star.hander;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;

import org.apache.ibatis.reflection.MetaObject;

import org.springframework.stereotype.Component;

import java.util.Date;

/**

  • @Description: 元对象处理器

  • @Date: Created in 14:03 2020/7/29

  • @Author: ONESTAR

  • @QQ群: 530311074

  • @URL: https://onestar.newstar.net.cn/

*/

@Component //交给spring管理

public class MyMetaObjectHandler implements MetaObjectHandler {

//使用MybatisPlus实现添加操作,执行该方法

@Override

public void insertFill(MetaObject metaObject) {

this.setFieldValByName(“createTime”,new Date(),metaObject);

this.setFieldValByName(“updateTime”,new Date(),metaObject);

}

//使用MybatisPlus实现修改操作,执行该方法

@Override

public void updateFill(MetaObject metaObject) {

this.setFieldValByName(“updateTime”,new Date(),metaObject);

}

}

分析:

  • @Component:将该类交给spring管理
  • metaObject:元数据对象
  • setFieldValByName:根据名称来设置值,这里根据创建时间来设置

配置好后可以再测试类中添加User和修改User进行测试

2.3 mybatisplus实现乐观锁

概念

乐观锁和悲观锁

  • 悲观锁,顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。悲观锁适用于并发竞争很厉害,写比较多的操作。

  • 乐观锁,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁适用于读多写少的应用场景,这样可以提高吞吐量。

这里只讲乐观锁,为了解决写数据时丢失更新问题而出现的一种解决方法。当多个人同时修改同一条记录,最后提交的把之前的提交数据覆盖,这就是丢失更新,为了防止出现这种情况,就可以采用乐观锁,在提交更新的时候会判断一下在此期间别人有没有去更新这个数据,如12306抢票

MybatisPlus实现原理:通过添加version字段来判断是否对数据进行了修改,修改将version加一,比较新的version和原有的version是不是一样,一样的version才进行更新操作,更新完成后,version就会+1,这时候另外一个拿到数据想要更新的人,在比较version那里就会不同从而更新失败。

2.3.1 添加乐观锁版本号字段

  • 添加字段

ALTER TABLE user ADD COLUMN version INT

  • 实体类添加属性和注解

@Version

@TableField(fill = FieldFill.INSERT_UPDATE) //更新时修改

private Integer version;

添加操作初始化version

//使用MybatisPlus实现添加操作,执行该方法

@Override

public void insertFill(MetaObject metaObject) {

this.setFieldValByName(“version”, 1, metaObject);

}

注:

  • 支持的数据类型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity 中
  • 仅支持 updateById(id) 与 update(entity, wrapper) 方法
  • 在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

2.3.2 配置乐观锁插件

在MpConfig配置文件中添加乐观锁配置插件

/**

  • 乐观锁插件

*/

@Bean

public OptimisticLockerInterceptor optimisticLockerInterceptor() {

return new OptimisticLockerInterceptor();

}

2.3.3 测试乐观锁

//乐观锁

@Test

void optimisticLocker(){

//查询

User user = userMapper.selectById(1L);

//修改数据

user.setAge(1);

//修改失败:模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version

//user.setVersion(user.getVersion() - 1);

//执行更新

userMapper.updateById(user);

}

2.4 逻辑删除

删除可以分为两种,一种是物理删除,一种是逻辑删除

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条删除数据

  • 逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍能看到此数据,通过标志位字段来实现

2.4.1 添加字段

  • 添加deleted标志位字段

ALTER TABLE user ADD COLUMN deleted boolean

  • 实体类添加属性和注解

@TableLogic

最后

最后,强调几点:

  • 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
  • 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
  • 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 添加deleted标志位字段

ALTER TABLE user ADD COLUMN deleted boolean

  • 实体类添加属性和注解

@TableLogic

最后

最后,强调几点:

  • 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
  • 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
  • 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

[外链图片转存中…(img-R2BR3umV-1715319877458)]

[外链图片转存中…(img-aPDVraQk-1715319877458)]

[外链图片转存中…(img-tKz0JXe6-1715319877458)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值