5、SpringBoot整合之SpringBoot整合MybatisPlus
SpringBoot整合MybatisPlus
目录(可点击直接跳转,但还是建议按照顺序观看,四部分具有一定的关联性):
首先给出四部分完整的项目结构

一、实现基础的增删改查功能
1.创建项目、选择依赖
选择Spring Web、JDBC API、MyBatis Framework、MySQL Driver




2.在pom文件中引入相关依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- 修改jdbc版本 -->
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!-- 引入MybatisPlus的启动器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!-- 引入lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 引入druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<!-- 引入log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3.建库、建表、插入数据
CREATE DATABASE db_mybatisplus;
USE db_mybatisplus;
CREATE TABLE tab_teacher(
pk_teacher_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '老师主键id,起始为1',
teacher_name VARCHAR(10) COMMENT '老师姓名',
teacher_sex CHAR(1) COMMENT '老师性别',
teacher_salary DOUBLE(6,1) COMMENT '老师工资'
);
-- 反复执行多次,随机插入多条数据
INSERT INTO tab_teacher VALUES(
NULL,
SUBSTR(MD5(RAND()), 1, 5),
IF(RAND()>0.5, '男', '女'),
RAND()*10000+1000
);
SELECT * FROM tab_teacher;

4.配置核心配置文件
# 配置连接数据库的四大参数
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.133.139/db_mybatisplus?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
# 指定连接池的类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 显示SQL语句
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
5.创建实体类
package cn.byuan.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@NoArgsConstructor// 创建无参的构造方法
@AllArgsConstructor// 创建满参的构造方法
@Accessors(chain = true)// 使用链式方法
@Data// 重写toString方法等方法
@TableName("tab_teacher")// 对应表名
public class Teacher implements Serializable {
@TableId(value = "pk_teacher_id", type = IdType.AUTO)// 主键必须有TableId注解
private Integer teacherId;
@TableField("teacher_name")
private String teacherName;
@TableField("teacher_sex")
private String teacherSex;
@TableField("teacher_salary")
private Double teacherSalary;
}
6.创建Teacher类的dao接口,继承BaseMapper接口,使用BaseMapper接口的方法
这里我省去了mapper层,直接让dao层接口继承BaseMapper
这里要牢记一个原则:在启动类对继承BaseMapper的类进行扫描,谁继承BaseMapper类就对它进行扫描
package cn.byuan.dao;
import cn.byuan.entity.Teacher;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface TeacherDao extends BaseMapper<Teacher> {
}
7.创建service接口及实现类
接口:
import cn.byuan.entity.Teacher;
import java.util.List;
public interface TeacherService {
// 添加一位老师
Integer addOneTeacher(Teacher teacher);
// 根据id删除一位老师
Integer deleteOneTeacherByTeacherId(Integer teacherId);
// 修改一位老师的信息
Integer updateOneTeacher(Teacher teacher);
// 根据id查询一位老师
Teacher getOneTeacherByTeacherId(Integer teacherId);
// 获取所有老师
List<Teacher> getAllTeacher();
}
实现类:
package cn.byuan.service;
import cn.byuan.dao.TeacherDao;
import cn.byuan.entity.Teacher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TeacherServiceImp implements TeacherService{
@Autowired
private TeacherDao teacherDao;
// 添加一位老师
public Integer addOneTeacher(Teacher teacher){
return teacherDao.insert(teacher);
}
// 根据id删除一位老师
public Integer deleteOneTeacherByTeacherId(Integer teacherId){
return teacherDao.deleteById(teacherId);
}
// 修改一位老师的信息
public Integer updateOneTeacher(Teacher teacher){
return teacherDao.updateById(teacher);
}
// 根据id查询一位老师
public Teacher getOneTeacherByTeacherId(Integer teacherId){
return teacherDao.selectById(teacherId);
}
// 获取所有老师
public List<Teacher> getAllTeacher(){
return teacherDao.selectList(null);
}
}
8.在启动类对继承BaseMapper的类配置扫描
谁继承了BaseMapper就对谁进行扫描,因为之前我省去了mapper层,直接让dao层接口继承BaseMapper,因此这里扫描的是dao包
package cn.byuan;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("cn.byuan.dao")// 那一层继承了BaseMapper就对那一层进行扫描
public class Test005SpringbootMybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(Test005SpringbootMybatisplusApplication.class, args);
}
}
9.在测试类进行测试
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoOneTests {
@Autowired
private TeacherService teacherService;
@Test
void addOneTeacherTest(){
Teacher teacher = new Teacher()
.setTeacherName("test2")
.setTeacherSex("女")
.setTeacherSalary(9876.5);
teacherService.addOneTeacher(teacher);
}
@Test
void deleteOneTeacherByTeacherIdTest(){
teacherService.deleteOneTeacherByTeacherId(2);
}
@Test
void updateOneTeacher(){
Teacher teacher = new Teacher()
.setTeacherId(1)
.setTeacherName("qwe12")
.setTeacherSex("女")
.setTeacherSalary(1234.5);
teacherService.updateOneTeacher(teacher);
}
@Test
void getOneTeacherByTeacherId(){
teacherService.getOneTeacherByTeacherId(1);
}
@Test
void getAllTeacher(){
teacherService.getAllTeacher();
}
}
测试结果:

二、实现自动填充功能
自动填充功能一般可以用作记录操作发生时间,如某列的最后修改时间等,本部分代码基于第一部分:实现基础的增删改查、
1.修改数据库中的表结构
-- 修改数据库中表结构
ALTER TABLE tab_teacher ADD create_time TIMESTAMP COMMENT '记录插入时间';
ALTER TABLE tab_teacher ADD update_time TIMESTAMP COMMENT '记录修改时间';
-- 更新所有表中数据
UPDATE tab_teacher SET create_time=NOW();
UPDATE tab_teacher SET update_time=NOW();
SELECT * FROM tab_teacher;

2.修改实体类
这一步简单来说就是将增加的两列添加进Teacher类的属性中,其余与第一部分保持一致;
为实现自动填充还应在新加入的两个属性的TableField中增加"fill"属性
package cn.byuan.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor// 创建无参的构造方法
@AllArgsConstructor// 创建满参的构造方法
@Accessors(chain = true)// 使用链式方法
@Data// 重写toString方法等方法
@TableName("tab_teacher")// 对应表名
public class Teacher implements Serializable {
@TableId(value = "pk_teacher_id", type = IdType.AUTO)// 主键必须有TableId注解
private Integer teacherId;
@TableField("teacher_name")
private String teacherName;
@TableField("teacher_sex")
private String teacherSex;
@TableField("teacher_salary")
private Double teacherSalary;
// 增加的两列属性
@TableField(value = "create_time", fill = FieldFill.INSERT)// 插入时自动填充
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)// 插入和修改时自动填充
private Date updateTime;
}
3.创建handler层,实现MetaObjectHandler接口,重写insertFill与updateFill方法,指定填充的字段及属性值
package cn.byuan.handler;
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 TeacherHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
4.进行测试
这里我们只测试增加和修改两个方法
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoTwoTests {
@Autowired
private TeacherService teacherService;
@Test
void addOneTeacherTest(){
Teacher teacher = new Teacher()
.setTeacherName("test2")
.setTeacherSex("女")
.setTeacherSalary(9876.5);
teacherService.addOneTeacher(teacher);
}
@Test
void updateOneTeacher(){
Teacher teacher = new Teacher()
.setTeacherId(1)
.setTeacherName("wer23")
.setTeacherSex("女")
.setTeacherSalary(1234.5);
teacherService.updateOneTeacher(teacher);
}
}
从SQL语句可以看出,在执行update方法时,已自动为我们填充字段

数据库中新插入数据也没有问题

三、实现逻辑删除功能
数据是无价的,因此一般而言我们不会直接删除数据。对于"删除"我们一般的做法是定义一个字段来记录本行数据的可见性
1.修改数据库中的表结构
添加一个字段作为标记
-- 修改数据库中表结构, 添加一个字段作为标记
ALTER TABLE tab_teacher ADD visibility TINYINT COMMENT "0表示未删除,1表示删除";
-- 更新表中所有数据, 全部设置为未删除
UPDATE tab_teacher SET visibility=0;
2.在实体类中添加字段,并添加TableField和TableLogic两个注解
package cn.byuan.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor// 创建无参的构造方法
@AllArgsConstructor// 创建满参的构造方法
@Accessors(chain = true)// 使用链式方法
@Data// 重写toString方法等方法
@TableName("tab_teacher")// 对应表名
public class Teacher implements Serializable {
@TableId(value = "pk_teacher_id", type = IdType.AUTO)// 主键必须有TableId注解
private Integer teacherId;
@TableField("teacher_name")
private String teacherName;
@TableField("teacher_sex")
private String teacherSex;
@TableField("teacher_salary")
private Double teacherSalary;
@TableField(value = "create_time", fill = FieldFill.INSERT)// 插入时自动填充
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)// 插入和修改时自动填充
private Date updateTime;
// 新添加进来的字段
@TableField(value = "visibility", fill = FieldFill.INSERT)
@TableLogic(value = "0", delval = "1")// 指定次字段为逻辑删除字段, 默认0是未删除, 1是已删除
private Integer visibility;
}
3.在TeacherHandler中指定visibility字段的初始值
package cn.byuan.handler;
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 TeacherHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
// 新添加的字段
this.strictInsertFill(metaObject, "visibility", Integer.class, 0);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
4.进行测试
这里只测试两个方法,一个是删除指定id值的老师,一个是根据被删除的老师id查询该老师是否可以被查询
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoThreeTests {
@Autowired
private TeacherService teacherService;
@Test
void deleteOneTeacherByTeacherIdTest(){
// 删除id为1的老师
teacherService.deleteOneTeacherByTeacherId(1);
}
@Test
void getOneTeacherByTeacherId(){
// 查询id为1的老师
teacherService.getOneTeacherByTeacherId(1);
}
}
可以看到,当我们执行delete方法时,实际上执行的是update方法
而查询语句并没有查询到该老师

数据库中id为1的老师信息依然存在

四、实现分页功能
1.创建一个配置类,通过方法返回一个PaginationInterceptor
package cn.byuan.conf;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("cn.byuan.dao")
public class PageConfig {
@Bean
public PaginationInterceptor PaginationInterceptor(){
return new PaginationInterceptor();
}
}
2.在service中根据selectPage方法进行分页
这里展示两种分页方式,对表中所有数据进行分页以及根据条件进行分页
接口:
package cn.byuan.service;
import cn.byuan.entity.Teacher;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
public interface TeacherService {
// 添加一位老师
Integer addOneTeacher(Teacher teacher);
// 根据id删除一位老师
Integer deleteOneTeacherByTeacherId(Integer teacherId);
// 修改一位老师的信息
Integer updateOneTeacher(Teacher teacher);
// 根据id查询一位老师
Teacher getOneTeacherByTeacherId(Integer teacherId);
// 获取所有老师
List<Teacher> getAllTeacher();
// 该部分增加的方法
// 对表中所有信息进行分页, 传入参数为要查询的页数
Page<Teacher> getAllTeacherPage(Integer pageNumber);
// 按条件(性别)进行分页
Page<Teacher> getAllTeacherByTeacherSexPage(Integer pageNumber, String teacherSex);
}
实现类:
package cn.byuan.service;
import cn.byuan.dao.TeacherDao;
import cn.byuan.entity.Teacher;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TeacherServiceImp implements TeacherService{
@Autowired
private TeacherDao teacherDao;
// 添加一位老师
public Integer addOneTeacher(Teacher teacher){
return teacherDao.insert(teacher);
}
// 根据id删除一位老师
public Integer deleteOneTeacherByTeacherId(Integer teacherId){
return teacherDao.deleteById(teacherId);
}
// 修改一位老师的信息
public Integer updateOneTeacher(Teacher teacher){
return teacherDao.updateById(teacher);
}
// 根据id查询一位老师
public Teacher getOneTeacherByTeacherId(Integer teacherId){
return teacherDao.selectById(teacherId);
}
// 获取所有老师
public List<Teacher> getAllTeacher(){
return teacherDao.selectList(null);
}
// 该部分增加的方法
// 对表中所有信息进行分页, 传入参数为要查询的页数
public Page<Teacher> getAllTeacherPage(Integer pageNumber){
QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
Page<Teacher> teacherPage = new Page<>(pageNumber, 5);// 每页大小为5
teacherDao.selectPage(teacherPage, teacherQueryWrapper);
return teacherPage;
}
// 按条件(性别)进行分页
public Page<Teacher> getAllTeacherByTeacherSexPage(Integer pageNumber, String teacherSex){
QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
teacherQueryWrapper.eq("teacher_sex", teacherSex);// 根据条件进行分页, 这里填写的是表中的列名
Page<Teacher> teacherPage = new Page<>(pageNumber, 5);
teacherDao.selectPage(teacherPage, teacherQueryWrapper);
return teacherPage;
}
}
3.进行测试
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoFourTests {
@Autowired
private TeacherService teacherService;
@Test
void getAllTeacherPageTest(){
// 查看第三页
Page<Teacher> teacherPage = teacherService.getAllTeacherPage(3);
teacherPage.getRecords().forEach(System.out::println);
}
@Test
void getAllTeacherByTeacherSexPageTest(){
// 查询男生第1页的内容
Page<Teacher> teacherPage = teacherService.getAllTeacherByTeacherSexPage(1, "男");
teacherPage.getRecords().forEach(System.out::println);
}
}
测试结果

附:Page对象的一些常用方法
Page<Object> page = new Page<>(1, 6);// 指定当前页, 每页记录数
page.getCurrent();// 获取当前页
page.getTotal();// 获取总记录数
page.getSize();// 获取每页的记录数
page.getRecords();// 获取当前页数据的集合
page.getPages();// 获取总页数
page.hasNext();// 是否存在下一页
page.hasPrevious();// 是否存在上一页
源码地址:https://github.com/byuan98/springboot-integration/tree/master/test005_springboot_mybatisplus
5、SpringBoot整合之SpringBoot整合MybatisPlus的更多相关文章
- springboot+jpa+mysql+swagger整合
Springboot+jpa+MySQL+swagger整合 创建一个springboot web项目 <dependencies> <dependency> < ...
- java框架之SpringBoot(12)-消息及整合RabbitMQ
前言 概述 大多数应用中,可通过消息服务中间件来提升系统异步通信.扩展解耦的能力. 消息服务中两个重要概念:消息代理(message broker)和目的地(destination).当消息发送者发送 ...
- java框架之SpringBoot(13)-检索及整合Elasticsearch
ElasticSearch介绍 简介 我们的应用经常需要使用检索功能,开源的 Elasticsearch 是目前全文搜索引擎的首选.它可以快速的存储.搜索和分析海量数据.SpringBoot 通过整合 ...
- Springboot 2.0.4 整合Mybatis出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
在使用Springboot 2.0.4 整合Mybatis的时候出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are require ...
- SpringBoot Druid整合,SpringBoot 集成Druid
SpringBoot Druid整合,SpringBoot 集成Druid ================================ ©Copyright 蕃薯耀 2018年4月8日 http ...
- SpringBoot+SpringMVC+MyBatis快速整合搭建
作为开发人员,大家都知道,SpringBoot是基于Spring4.0设计的,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程.另外Spr ...
- SpringBoot:4.SpringBoot整合Mybatis实现数据库访问
在公司项目开发中,使用Mybatis居多.在 SpringBoot:3.SpringBoot使用Spring-data-jpa实现数据库访问 中,这种jpa风格的把sql语句和java代码放到一起,总 ...
- SpringBoot与PageHelper的整合示例详解
SpringBoot与PageHelper的整合示例详解 1.PageHelper简介 PageHelper官网地址: https://pagehelper.github.io/ 摘要: com.gi ...
- SpringBoot学习- 4、整合JWT
SpringBoot学习足迹 1.Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于 ...
- SpringBoot学习- 3、整合MyBatis
SpringBoot学习足迹 1.下载安装一个Mysql数据库及管理工具,同类工具很多,随便找一个都可以,我在windows下做测试项目习惯使用的是haosql 它内部集成了MySql-Front管理 ...
随机推荐
- CentOS 8.2远程连接vncserver升级后1.10.1无法启动解决记录
CentOS 8.2远程连接vncserver升级后1.10.1无法启动解决记录 问题起源:手贱yum upgrade,重启服务器后无法使用vnc viewer远程连接 查看状态 # system ...
- Zookeeper——Docker下安装部署
单节点安装 一. 环境说明 docker: 18.09.9-ce zookeeper: 3.5.6 二. 拉取 zookeeper 镜像 拉取镜像 docker pull zookeeper 默认是摘 ...
- 克隆并编译otter
源码编译: git clone 项目到本地,用IDEA打开,等待Maven下载完jar包,打开命令行,进入当前项目的lib目录 执行install.bat命令,该批处理文件会将缺失的jar包安装到你本 ...
- 如何像如何像 NASA 顶级程序员一样编程 — 10 条重要原则
https://www.oschina.net/news/90499/nasa-programmer-rule?from=20171112#0-qzone-1-7898-d020d2d2a4e8d1a ...
- keil 中的incompatible错误
http://blog.csdn.net/kobesdu/article/details/42268065
- Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]] 错误(Day_25)
错误: 在maven项目,web启动的时候报这个错误 Failed to start component [StandardEngine[Tomcat].StandardHost[localho ...
- kylin聚合组的使用案例
在使用kylin聚合组进行优化的时候,往往不知道怎么使用. 这里有2个小案例可以参考. 1. 需要对某个维度进行隔离. 如果有些维度,你不想要它和其他维度一起出现,你就可以单独给它建一个聚合组,并且在 ...
- 大作!webpack详细配置
webpack学习之旅 好好学习 天天向上!遇到bug,不要慌! 文章目录 webpack学习之旅 大一统的模块化规范--ES6模块化 1.node.js中通过babel体验ES6模块化 2.ES6模 ...
- unity给子物体添加Shader
分享两个自制Shader:http://pan.baidu.com/s/1nuRcF2L Shader存放路径:\Assets\Resources\Shader\ 定义Shader类型: public ...
- MySQL 三万字精华总结
写在之前:不建议那种上来就是各种面试题罗列,然后背书式的去记忆,对技术的提升帮助很小,对正经面试也没什么帮助,有点东西的面试官深挖下就懵逼了. 个人建议把面试题看作是费曼学习法中的回顾.简化的环节 ...