MyBatisPlus 之三:BaseMapper 详解和 CRUD 案例详解

2024-03-18 16:04

本文主要是介绍MyBatisPlus 之三:BaseMapper 详解和 CRUD 案例详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

BaseMapper详解

1. SQL 日志开启

为了更好更快学习 MyBatisPlus ,需要配置 SQL 日志,这样方便我们能随时看到执行过程中使用的 SQL 语句,有助于理解执行原理及方便 SQL 错误调试

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImplmybatis-plus.configuration.map-underscore-to-camel-case=false 

2. BaseMapper API

BaseMapper 是 MyBatis Plus 提供的一个通用接口,它定义了一套基础的 CRUD(Create, Read, Update, Delete)操作方法。通过继承 BaseMapper,开发者可以直接在自定义的 Mapper 接口中获得这些基本的数据操作功能,而无需手动编写 SQL 语句或 XML 映射文件。

public interface BaseMapper<T> extends Mapper<T> {int insert(T entity);int deleteById(Serializable id);int deleteByMap(@Param("cm") Map<String, Object> columnMap);int delete(@Param("ew") Wrapper<T> queryWrapper);int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);int updateById(@Param("et") T entity);int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);T selectById(Serializable id);List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);T selectOne(@Param("ew") Wrapper<T> queryWrapper);Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);
}

3 . 基本CRUD

1) 插入数据:
int insert(T entity);
/*** 1. 如果属性使用的是驼峰命名法时,生成SQL时,转为带下划线的列名。例如:bookName--book_name*   解决办法:*   a. 给属性添加注解 @TableField("bookName")*   b. 在配置文件中,关闭驼峰名和下划线的转换*/
@Test
void save(){Book book = new Book();book.setPrice(34f);book.setAuthor("王超");book.setBookName("JSP开发技术");book.setPubDate(new Date());System.out.println(book);bookDao.insert(book);System.out.println(book);   //执行前 后 观察变化。主键
}

注意:

  1. 如果属性使用的是驼峰命名法时,生成SQL时,转为带下划线的列名。例如:bookName--book_name

    解决办法:

    a. 给属性添加注解 @TableField("bookName")

    b. 在配置文件中,关闭驼峰名和下划线的转换

    mybatis-plus.configuration.map-underscore-to-camel-case=false
  2. 如果指定了主键 @TableId 后,默认情况下(没有指定主键生成策略),主键会使用雪花算法生成应用于分布式系统的主键

    解决办法:

    a. 给主键指定生成策略 @TableId(value = "bookid",type = IdType.AUTO)

    b. IdType.AUTO : 主键生成有数据库端来完成,一般适用于数据库自动增长

type = IdType.INPUT :程序自己指定主键
type = IdType.ASSIGN_ID :由框架自动生成指定的主键,使用的是雪花算法
type = IdType.ASSIGN_UUID :有框架自动生成给定主键,使用算法 UUID 算法

除了AUTO 之外,都是程序指定的主键,又区分程序员自己指定还是框架自动生成。

2) 查询:
T selectById(Serializable id);//根据指定的主键列表查询
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
//根据map中的key-value 作为条件等值条件查询
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
//根据构建的条件查询唯一一条记录对象
T selectOne(@Param("ew") Wrapper<T> queryWrapper);//根据构建的条件 查询记录数
Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);
//根据构建的条件 查询多条记录
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);

如果直接使用 selectById() 查询,结果下面语句:

/*** 注意:给实体类中指定主键,否则出现下面 null=?* SELECT bookId,bookName,author,pubdate,price FROM book WHERE null=?*/

查不出结果的原因:不知道哪一个列是主键。所以使用了 null = ? 作为条件了

解决办法:

给属性指定主键:@TableId

@TableField 可以设置忽略 exist=true

@Data
public class Book {@TableIdprivate Integer bookId;@TableField("bookName")private String bookName;private Float price;@TableField("pubdate")private Date pubDate;private String author;
}
selectBatchIds() 用法:
//SELECT bookid,bookName,price,pubdate,author FROM book WHERE bookid IN ( ? , ? , ? , ? , ? )
List<Integer> ids = Arrays.asList(2,3,4,26,27);
bookDao.selectBatchIds(ids);
selectByMap() 用法:
//SELECT bookid,bookName,price,pubdate,author FROM book WHERE price = ? AND bookname = ?
Map<String,Object> cond = new HashMap<>();
cond.put("price",34f);
cond.put("bookname","Java开发技术");bookDao.selectByMap(cond);
Wrapper 用法

下面方法用法:Wrapper 用法

//根据构建的条件 查询记录数
Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);
//根据构建的条件 查询多条记录
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

下面使用方式:

QueryWrapper 可以用于构建查询的列、条件、排序、分组等要素。

    void queryByWrapper(){QueryWrapper<Book> queryWrapper = new QueryWrapper<>();queryWrapper.select("bookname","price","author");     //指定要求查询的列queryWrapper.gt("price",20);                            // where price > 20queryWrapper.le("price",80);                            // and  price <= 80queryWrapper.eq("bookname","Java开发实战");             // and bookname= 'Java开发实战'queryWrapper.between("bookid",10,50);                // and bookid between 10,50 bookDao.selectList(queryWrapper);//       bookDao.selectCount(null); //无条件查询,没有where
//        bookDao.selectCount(queryWrapper); //按条件查询}

queryWrapper 支持链式编程方式:

queryWrapper.select("bookname","price","author")
.gt("price",20)
.le("price",80)
.eq("bookname","Java开发实战")
.between("bookid",10,50);
bookDao.selectList(queryWrapper);
selectOne()

注意:返回值只能小于等于一条才可以,否则异常。

@Test
void queryOne(){QueryWrapper<Book> queryWrapper = new QueryWrapper<>();queryWrapper.eq("bookname", "Java实战开发1").eq("author","周瑜");Book book = bookDao.selectOne(queryWrapper);System.out.println(book);
}
selectMaps()

返回结果为List ,元素为Map封装的记录对象。

@Test
void queryMap(){List<Map<String, Object>> maps = bookDao.selectMaps(null);maps.forEach(System.out::println);
}
or 和 orderby
/*** where author='周瑜' or author='诸葛亮'** or 和 order by*/
@Test
public void or(){QueryWrapper<Book> queryWrapper = new QueryWrapper<>();queryWrapper.eq("author","周瑜").or().eq("author","诸葛亮").or().gt("price",30f).le("price",60f); // 默认为and 关系queryWrapper.orderByAsc("price").orderByDesc("bookid");bookDao.selectList(queryWrapper);
}
分页

分页需要考虑的要素:每页行数、总记录数、总页数、当前页号、当前页要显示记录

不同数据库分页 SQL 不同。

mysql : limit start, count;

sqlserver : top ---not in

oracle : rownum

MyBatisPlus 会根据 “方言” 配置,自动生成对应数据库的 SQL 语句去执行。

代码如下:

@Test
void page(){Page<Book> page = new Page<>();page.setSize(5);    //每页显示的记录数page.setCurrent(3); //设置当前页       // limit startindex ,countpage//(curPage-1)*size Page<Book> page1 = bookDao.selectPage(page, null);//当前的要显示的记录List<Book> records = page1.getRecords();System.out.println(page1==page);records.forEach(System.out::println);
}

注意:直接运行后,发现并没有实现分页。

原因:没有安装分页插件。

解决办法:去官网,查看分页插件使用方法。复制代码到项目中即可

https://mp.baomidou.com/guide/page.html

//Spring boot方式
@Configuration
//@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {// 旧版
//    @Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false// paginationInterceptor.setOverflow(false);// 设置最大单页限制数量,默认 500 条,-1 不受限制// paginationInterceptor.setLimit(500);// 开启 count 的 join 优化,只针对部分 left joinpaginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));return paginationInterceptor;}// 最新版@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); //数据库方言return interceptor;}}

2023最新版本的分页插件:

package com.wdzl.plus.config;import com.baomidou.mybatisplus.annotation.DbType;
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 {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

注意:

  1. 修改数据库方言(类型)

  2. 使用新版。注释掉旧版,不能同时使用。

  3. 类名和方法名可以自定义

另外:上面测试代码中

可以看到 page1==page 的输出结果为 true,说明两个是同一个对象。可以直接使用page 即可,简化后:

@Test
void page(){Page<Book> page = new Page<>();page.setSize(5);    //每页显示的记录数page.setCurrent(3); //设置当前页       // limit startindex ,countpagebookDao.selectPage(page, null);//当前的要显示的记录List<Book> records = page.getRecords();records.forEach(System.out::println);
}
3)修改
    //update book set price=99 where bookid=?int updateById(@Param("et") T entity);//update book set price=99 where bookname=? and price<?int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
    @Testpublic void update(){
//        Book book = bookDao.selectById(27);
//        book.setPrice(88f);
//        bookDao.updateById(book); //按主键修改//下面是按条件修改QueryWrapper<Book> queryWrapper = new QueryWrapper<>();queryWrapper.eq("price",88);//注意 :book参数 ,是作为修改后的目标数据。把符合条件的所有记录都修改为book相同的值。Book book1 = new Book();book1.setPrice(100f);bookDao.update(book1,queryWrapper);//update 和 updateById() 在修改时,只修改属性不为null的列。}

注意:

  1. 单个对象修改,一般是先查询数据,再修改个别列。
  2. 对应null 的属性,不会被修改,不会执行SQL ,只会把有值的属性生成到SQL中。
4)删除
    //按主键删除 自注释int deleteById(Serializable id);//按map中的key-value 等值条件 删除int deleteByMap(@Param("cm") Map<String, Object> columnMap);// 根据构建条件删除int delete(@Param("ew") Wrapper<T> queryWrapper);// 根据集合中主键列表删除int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
    @Testvoid delete(){Map<String,Object> map = new HashMap<>();map.put("price",44f);map.put("bookname","java开发");
//        bookDao.deleteByMap(map);//WHERE bookid IN ( ? , ? , ? , ? , ? , ? )List<Integer> ids = Arrays.asList(3,4,5,22,34,55);
//        bookDao.deleteBatchIds(ids);QueryWrapper<Book> queryWrapper = new QueryWrapper<>();queryWrapper.lt("price",30);bookDao.delete(queryWrapper);

这篇关于MyBatisPlus 之三:BaseMapper 详解和 CRUD 案例详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/822875

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP