学习了MyBatis-Plus你还会用MyBatis嘛,2024年最新jdk1.8面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 步骤1:配置JavaBean

  • 步骤2:编写dao

  • 步骤3:编写启动类

  • 步骤4:编写测试类

  • 步骤1:配置JavaBean

  • @TableName 表名注解,value属性设置表名

package com.czxy.domain;

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.Data;

import java.util.List;

@Data

@TableName(“tmp_customer”)

public class Customer {

@TableId(type = IdType.AUTO)

private Integer cid;

private String cname;

private String password;

private String telephone;

private String money;

private Integer version;

@TableField(exist = false)

private List ids;

}

  • 步骤2:编写dao

package com.czxy.mp.mapper;

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

import com.czxy.mp.domain.Customer;

import org.apache.ibatis.annotations.Mapper;

/**

  • Created by liangtong.

*/

@Mapper

public interface CustomerMapper extends BaseMapper {

}

  • 步骤3:编写启动类

package com.czxy.mp;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

  • Created by liangtong.

*/

@SpringBootApplication

public class MybatisPlusApplication {

public static void main(String[] args) {

SpringApplication.run(MybatisPlusApplication.class, args);

}

}

  • 步骤4:编写测试类

package com.czxy;

import com.czxy.mp.MybatisPlusApplication;

import com.czxy.mp.domain.Customer;

import com.czxy.mp.mapper.CustomerMapper;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

import java.util.List;

/**

  • Created by liangtong.

*/

@RunWith(SpringRunner.class)

@SpringBootTest(classes = MybatisPlusApplication.class)

public class TestDemo01 {

@Resource

private CustomerMapper customerMapper;

@Test

public void testFindAll() {

List list = customerMapper.selectList(null);

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

}

}

基本操作

====

常见API


BaseMapper 封装CRUD操作,泛型 T 为任意实体对象

  • 增删改

| 方法名 | 描述 |

| — | — |

| int insert(T entity) | 插入一条记录,entity 为 实体对象 |

| int delete(Wrapper wrapper) | 根据 entity 条件,删除记录,wrapper 可以为 null |

| int deleteBatchIds(Collection idList) | 根据ID 批量删除 |

| int deleteById(Serializable id) | 根据 ID 删除 |

| int deleteByMap(Map<String, Object> map) | 根据 columnMap 条件,删除记录 |

| int update(T entity, Wrapper updateWrapper) | 根据 whereEntity 条件,更新记录 |

| int updateById(T entity); | 根据 ID 修改 |

  • 查询

| 方法名 | 描述 |

| — | — |

| T selectById(Serializable id) | 根据 ID 查询 |

| T selectOne(Wrapper queryWrapper) | 根据 entity 条件,查询一条记录 |

| List selectBatchIds(Collection idList) | 根据ID 批量查询 |

| List selectList(Wrapper queryWrapper) | 根据 entity 条件,查询全部记录 |

| List selectByMap(Map<String, Object> columnMap) | 根据 columnMap 条件 |

| List<Map<String, Object>> selectMaps(Wrapper queryWrapper) | 根据 Wrapper 条件,查询全部记录 |

| List selectObjs( Wrapper queryWrapper) | 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值 |

| IPage selectPage(IPage page, Wrapper queryWrapper) | 根据 entity 条件,查询全部记录(并翻页) |

| IPage<Map<String, Object>> selectMapsPage(IPage page, Wrapper queryWrapper) | 根据 Wrapper 条件,查询全部记录(并翻页) |

| Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper) | 根据 Wrapper 条件,查询总记录数 |

添加


@Test

public void testInsert() {

Customer customer = new Customer();

customer.setCname(“测试”);

customerMapper.insert(customer);

}

获得自动增长列信息

@Test

public void testInsert() {

Customer customer = new Customer();

customer.setCname(“测试”);

customerMapper.insert(customer);

System.out.println(customer);

}

更新


  • 通过id更新

@Test

public void testUpdate() {

Customer customer = new Customer();

customer.setCid(15);

customer.setCname(“测试777”);

customer.setPassword(“777”);

// 需要给Customer设置@TableId

customerMapper.updateById(customer);

}

  • 更新所有

@Test

public void testUpdate2() {

Customer customer = new Customer();

customer.setCname(“测试777”);

customer.setPassword(“777”);

// 更新所有

customerMapper.update(customer,null);

}

删除


  • 根据id进行删除

@Test

public void testDelete() {

// 需要给Customer设置@TableId

int i = customerMapper.deleteById(11);

System.out.println(i);

}

  • 批量删除

@Test

public void testBatchDelete() {

// 需要给Customer设置@TableId

int i = customerMapper.deleteBatchIds(Arrays.asList(9,10));

System.out.println(i);

}

查询

==

Map条件


@Test

public void testMap(){

Map map = new HashMap();

map.put(“cname”,“测试”);

map.put(“password”,“123456”);

List list = customerMapper.selectByMap(map);

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

}

QueryWrapper


wrapper介绍

  • Wrapper : 条件构造抽象类,最顶端父类

  • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

  • QueryWrapper : Entity 对象封装操作类,不是用lambda语法

  • UpdateWrapper : Update 条件封装,用于Entity对象更新操作

  • AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。

  • LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper

  • LambdaUpdateWrapper : Lambda 更新封装Wrapper

  • 如果想进行复杂条件查询,那么需要使用条件构造器 Wapper,涉及到如下方法

| 方法名 | 描述 |

| — | — |

| selectOne | |

| selectCount | |

| selectList | |

| selectMaps | |

| selectObjs | |

| update | |

| delete | |

  • 拼凑条件相关关键字

| 查询方式 | 说明 |

| — | — |

| 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”) |

条件查询

  • 基本多条件查询

@Test

public void testWrapper(){

// 拼凑条件

QueryWrapper queryWrapper = new QueryWrapper();

// 1)模糊查询

queryWrapper.like(“cname”,“测试”);

// 2)等值查询

queryWrapper.eq(“password”,“777”);

// 3)批量查询

queryWrapper.in(“cid”,1,2,3,4);

// 查询

List list = customerMapper.selectList(queryWrapper);

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

}

  • 条件判断

@Test

public void findCondition2() {

Customer customer = new Customer();

customer.setPassword(“777”);

customer.setCname(“888”);

customer.setIdList(Arrays.asList(2,3,4));

customer.setCid(3);

//条件查询

QueryWrapper queryWrapper = new QueryWrapper<>();

// 1) 等值查询

queryWrapper.eq( customer.getPassword()!=null ,“password”, customer.getPassword());

// 2) 模糊查询

queryWrapper.like(customer.getCname() != null , “cname”,customer.getCname());

// 3) in语句

queryWrapper.in(customer.getIdList() != null , “cid”,customer.getIdList());

// 4) 大于等于

queryWrapper.ge(customer.getCid() != null , “cid” , customer.getCid());

//查询

List list = customerMapper.selectList(queryWrapper);

//list.forEach(customer-> System.out.println(customer));

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

}

条件更新

  • 基本更新

@Test

public void testWrapperUpdate(){

// 数据

Customer customer = new Customer();

customer.setCname(“测试888”);

// 拼凑条件

QueryWrapper queryWrapper = new QueryWrapper();

queryWrapper.in(“cid”,1,2,3,4);

// 更新

int result = customerMapper.update(customer, queryWrapper);

System.out.println(result);

}

分页


内置插件

  • 主体插件: MybatisPlusInterceptor,该插件内部插件集:

  • 分页插件: PaginationInnerInterceptor

  • 多租户插件: TenantLineInnerInterceptor

  • 动态表名插件: DynamicTableNameInnerInterceptor

  • 乐观锁插件: OptimisticLockerInnerInterceptor

  • sql性能规范插件: IllegalSQLInnerInterceptor

  • 防止全表更新与删除插件: BlockAttackInnerInterceptor

配置类

package com.czxy.mp.config;

import com.baomidou.mybatisplus.annotation.DbType;

import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;

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

import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class MybatisPlusConfig {

/**

  • 配置插件

  • @return

*/

@Bean

public MybatisPlusInterceptor mybatisPlusInterceptor(){

MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();

// 分页插件

mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

return mybatisPlusInterceptor;

}

/**

  • 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)

  • @return

*/

@Bean

public ConfigurationCustomizer configurationCustomizer() {

return configuration -> configuration.setUseDeprecatedExecutor(false);

}

}

分页

@Test

public void testPage(){

// 分页数据

int pageNum = 1;

int pageSize = 3;

Page page = new Page<>(pageNum , pageSize);

page.setSearchCount(true);

// 查询

customerMapper.selectPage(page, null);

// 分页数据

System.err.println(“当前页码:” + page.getCurrent());

System.err.println(“每页显示记录数:” + page.getSize());

System.err.println(“总页数:” + page.getPages());

System.err.println(“总记录数:” + page.getTotal());

System.err.println(“是否有下一页:” + page.hasNext());

System.err.println(“是否有上一页:” + page.hasPrevious());

// 分页数据列表

page.getRecords().forEach(System.err::println);

}

常见注解

====

表名注解:@TableName


| 属性 | 描述 |

| — | — |

| value | 表名 |

| keepGlobalPrefix | 是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值) |

主键注解:@TableId

| 属性 | 描述 |

| — | — |

| value | 主键字段名 |

| type | 主键类型 IdType.ASSIGN_UUID ,分配UUID IdType.ASSIGN_ID ,分配ID(默认使用雪花算法) |

字段注解(非主键):@TableField

| 属性 | 描述 |

| — | — |

| value | 数据库字段名 |

| fill | 字段自动填充策略 FieldFill.INSERT 插入时填充字段 FieldFill.UPDATE 更新时填充字段 FieldFill.INSERT_UPDATE 插入和更新时填充字段 |

常见配置

mybatis-plus:

configuration:

log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #输出日志

map-underscore-to-camel-case: true #驼峰命名

global-config:

db-config:

id-type: auto #全局配置,id自动增强

table-prefix: tmp_ #表名前缀

type-aliases-package: com.czxy.mp.domain #别名包扫描路径

mapper-locations: classpath*:/mapper/**/*.xml #映射文件位置

高级

==

自动填充


项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。

我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作:

原理

  • 实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler,确定填充具体操作

  • 注解填充字段:@TableField(fill = ...) 确定字段填充的时机

  • FieldFill.INSERT:插入填充字段

  • FieldFill.UPDATE:更新填充字段

  • FieldFill.INSERT_UPDATE:插入和更新填充字段

基本操作

  • 步骤一:修改表添加字段

alter table tmp_customer add column create_time date;

alter table tmp_customer add column update_time date;

  • 步骤二:修改JavaBean

package com.czxy.mp.domain;

import com.baomidou.mybatisplus.annotation.*;

import lombok.Data;

import java.util.Date;

/**

  • Created by liangtong.

*/

@Data

@TableName(“tmp_customer”)

public class Customer {

@TableId(type = IdType.AUTO)

private Integer cid;

private String cname;

private String password;

private String telephone;

private String money;

@TableField(value=“create_time”,fill = FieldFill.INSERT)

private Date createTime;

@TableField(value=“update_time”,fill = FieldFill.UPDATE)

private Date updateTime;

}

步骤三:编写处理类

package com.czxy.mp.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 MyMetaObjectHandler implements MetaObjectHandler {

/**

  • 插入填充

  • @param metaObject

*/

@Override

public void insertFill(MetaObject metaObject) {

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

}

/**

  • 更新填充

  • @param metaObject

*/

@Override

public void updateFill(MetaObject metaObject) {

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

}

}

  • 步骤四:测试

@Test

public void testInsert() {

Customer customer = new Customer();

customer.setCname(“测试888”);

customerMapper.insert(customer);

}

@Test

public void testUpdate() {

Customer customer = new Customer();

customer.setCid(11);

customer.setTelephone(“999”);

customerMapper.updateById(customer);

}

乐观锁


什么是乐观锁

  • 当要更新一条记录的时候,希望这条记录没有被别人更新

  • 乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

实现

步骤一:修改表结构,添加version字段

最后

腾讯T3大牛总结的500页MySQL实战笔记意外爆火,P8看了直呼内行

腾讯T3大牛总结的500页MySQL实战笔记意外爆火,P8看了直呼内行

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

etaObject metaObject) {

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

}

/**

  • 更新填充

  • @param metaObject

*/

@Override

public void updateFill(MetaObject metaObject) {

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

}

}

  • 步骤四:测试

@Test

public void testInsert() {

Customer customer = new Customer();

customer.setCname(“测试888”);

customerMapper.insert(customer);

}

@Test

public void testUpdate() {

Customer customer = new Customer();

customer.setCid(11);

customer.setTelephone(“999”);

customerMapper.updateById(customer);

}

乐观锁


什么是乐观锁

  • 当要更新一条记录的时候,希望这条记录没有被别人更新

  • 乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

实现

步骤一:修改表结构,添加version字段

最后

[外链图片转存中…(img-yOXhgnrj-1713700207534)]

[外链图片转存中…(img-eoB4WdpF-1713700207534)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-ndMeC4Aj-1713700207535)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值