MybatisPlus学习

文章目录

  • 快速入门
    • 入门案例
    • 常见注解
    • 常见配置
  • 核心功能
    • 条件构造器
    • 自定义SQL
    • IService接口
  • 扩展功能
    • 代码生成器
    • 静态工具
    • 逻辑删除
    • 枚举处理器
    • JSON处理器
  • 插件功能
    • 分页插件
    • 通用分页实体

快速入门

入门案例

初始用户表
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在单表查询时候简化了Mapper接口与XML的配置统统不需要了

//只需继承mybatis-plus提供的接口,指定对应实体类
public interface UserMapper extends BaseMapper<User> {}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mp.mapper.UserMapper"></mapper>

Test类中直接调用Mapper接口继承的方法完成增删改查等操作

package com.itheima.mp.mapper;import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();user.setId(5L);user.setUsername("Lucy");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testQueryByIds() {List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDeleteUser() {userMapper.deleteById(5L);}
}

在这里插入图片描述

常见注解

在这里插入图片描述
在这里插入图片描述

注意is开头且为boolean类型的变量名,经过反射会将is省略

@Data
@TableName("tb_user")
public class User {/*** 用户id*/@TableId(type = IdType.AUTO)private Long id;/*** 用户名*/
//    @TableField("'username'")private String username;

在这里插入图片描述
加上注解,执行testQueryByIds方法可见

10:53:53 DEBUG 21696 --- [           main] c.i.mp.mapper.UserMapper.selectBatchIds  : ==>  
Preparing: SELECT id,'username',phone,info,status,balance,create_time,update_time FROM tb_user WHERE id IN ( ? , ? , ? , ? )

在这里插入图片描述

常见配置

在这里插入图片描述
在这里插入图片描述

核心功能

条件构造器

在这里插入图片描述
在这里插入图片描述
Test测试

    @Testvoid testQueryWrapper() {//1.构建查询条件QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id","username","info","balance").like("username", "o").ge("balance", 1000);//2.查询List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}//输出//User(id=3, username=Hope, password=null, phone=null, //info={"age": 25, "intro": "上进青年", "gender": "male"}, status=null, balance=100000, createTime=null, updateTime=null)

在这里插入图片描述

    @Testvoid testUpdateByQueryWrapper() {//1.要更新的数据User user = new User();user.setBalance(2000);//2、更新的条件QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");//3、执行更新userMapper.update(user, wrapper);}//Preparing: UPDATE tb_user SET balance=? WHERE (username = ?)

在这里插入图片描述
在这里插入图片描述

    @Testvoid testUpdateWrapper() {List<Long> ids = List.of(1L,2L,4L);UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance -200").in("id", ids);//3、执行更新userMapper.update(null, wrapper);}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义SQL

在这里插入图片描述
在这里插入图片描述

    @Testvoid testCustomSqlUpdate() {//1.更新条件List<Long> ids = List.of(1L,2L,4L);int amount = 200;//2.定义条件QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id",ids);//3.调用自定义SQL方法userMapper.updateBalanceByIds(wrapper,amount);}

创建Mapper接口

    void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper, @Param("amount") int amount);

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mp.mapper.UserMapper">
<!--${ew.customSqlSegment}: 这是 MyBatis-Plus 中的动态 SQL 语句的一部分。
它表示在运行时将替换为由QueryWrapper(ew)对象定义的条件部分。
${} 是动态 SQL 中的变量占位符,表示在运行时替换为实际的 SQL 片段。--><update id="updateBalanceByIds">update tb_user set balance = balance - #{amount} ${ew.customSqlSegment}</update>
</mapper>

IService接口

在这里插入图片描述
在这里插入图片描述

创建Service层的接口类和实现类


public interface IUserService extends IService<User> {}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {}

测试

@SpringBootTest
class IUserServiceTest {@Autowiredprivate IUserService userService;@Testvoid testSaveUser() {User user = new User();user.setUsername("zhangshuwen");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);}@Testvoid testQuery() {List<User> users = userService.listByIds(List.of(1L,2L,4L));users.forEach(System.out::println);}
}

在这里插入图片描述
在这里插入图片描述
Controller层


@Api(tags = "用户管理接口")
@RestController
@RequestMapping("/users")
/*** @RequiredArgsConstructor 注解在类上使用时,* Lombok会为类中的每个标有 final 或 @NonNull 注解的字段生成一个构造函数参数,* 然后在编译时自动生成带有这些参数的构造函数。* 这样你就不需要手动编写这个构造函数,Lombok会为你处理。*/
@RequiredArgsConstructor
public class UserController {private final IUserService iUserService;@ApiOperation("新增用户接口")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userFormDTO) {//1.将DTO拷贝到POUser user = BeanUtil.copyProperties(userFormDTO, User.class);//2.新增iUserService.save(user);}@ApiOperation("删除用户接口")@DeleteMapping("/{id}")public void saveUser(@PathVariable Long id) {iUserService.removeById(id);}@ApiOperation("根据id查询用户接口")@GetMapping("/{id}")public UserVO selectUser(@PathVariable Long id) {User user = iUserService.getById(id);return BeanUtil.copyProperties(user, UserVO.class);}@ApiOperation("根据id批量查询用户接口")@GetMappingpublic List<UserVO> queryUserByIds(@RequestParam("ids") List<Long> ids) {List<User> users = iUserService.listByIds(ids);return BeanUtil.copyToList(users, UserVO.class);}@ApiOperation("扣减用户余额")@PutMapping("/{id}/deduction/{money}")public void deductMoneyId(@PathVariable("id") Long id,@PathVariable("money") Integer money) {iUserService.deductBalance(id,money);}}

Service实现类

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic void deductBalance(Long id, Integer money) {//1.查询用户User user = getById(id);//2.校验用户状态if (user == null || user.getStatus() ==2 ){throw new RuntimeException("用户状态异常!");}//3.校验余额是否充足if (user.getBalance() <money ) {throw new RuntimeException("用户余额不足!");}//4.扣减余额baseMapper.deductBalance(id,money);}

Mapper接口

    @Update("update tb_user set balance = balance - #{money} where id = #{id}")void deductBalance(@Param("id") Long id, @Param("money") Integer money);

在这里插入图片描述
在这里插入图片描述
Controller接口

    @ApiOperation("根据复杂条件查询")@GetMapping("/list")public List<UserVO> queryUsers(UserQuery userQuery) {//1.查需要你用户POList<User> users = iUserService.queryUsers(userQuery.getName(),userQuery.getStatus(),userQuery.getMinBalance(),userQuery.getMaxBalance());//2.把PO拷贝到VOreturn BeanUtil.copyToList(users, UserVO.class);}

Service实现类

    /*** lambdaQuery(): 这是 MyBatis-Plus 提供的静态方法,用于创建一个 LambdaQueryWrapper 对象,LambdaQueryWrapper 是 MyBatis-Plus 中的查询条件构造器,允许通过 lambda 表达式动态构建查询条件。** .like(name!=null, User::getUsername, name): 这一行表示如果 name 不为 null,则添加一个模糊查询条件,查询条件是 User 对象的 getUsername 方法返回的字段,且字段值与传入的 name 相匹配。** .eq(status!=null, User::getStatus, status): 这一行表示如果 status 不为 null,则添加一个等于查询条件,查询条件是 User 对象的 getStatus 方法返回的字段,且字段值与传入的 status 相等。** .ge(minBalance!=null, User::getBalance, minBalance): 这一行表示如果 minBalance 不为 null,则添加一个大于等于查询条件,查询条件是 User 对象的 getBalance 方法返回的字段,且字段值大于等于传入的 minBalance。** .le(maxBalance!=null, User::getBalance, maxBalance): 这一行表示如果 maxBalance 不为 null,则添加一个小于等于查询条件,查询条件是 User 对象的 getBalance 方法返回的字段,且字段值小于等于传入的 maxBalance。*/@ApiOperation("根据复杂条件查询")@GetMapping("/list")public List<UserVO> queryUsers(UserQuery userQuery) {//1.查需要你用户POList<User> users = iUserService.queryUsers(userQuery.getName(),userQuery.getStatus(),userQuery.getMinBalance(),userQuery.getMaxBalance());//2.把PO拷贝到VOreturn BeanUtil.copyToList(users, UserVO.class);}

在这里插入图片描述
对Service实现类方法进行修改

    @Overridepublic void deductBalance(Long id, Integer money) {//1.查询用户User user = getById(id);//2.校验用户状态if (user == null || user.getStatus() ==2 ){throw new RuntimeException("用户状态异常!");}//3.校验余额是否充足if (user.getBalance() <money ) {throw new RuntimeException("用户余额不足!");}//4.扣减余额int remainBalance = user.getBalance() - money;lambdaUpdate().set(User::getStatus,remainBalance).set(remainBalance==0, User::getStatus,2).eq(User::getId,id).eq(User::getBalance,user.getBalance())  //乐观锁防止并发错误.update();}

扩展功能

代码生成器

在这里插入图片描述
在idea中通过mybatis-plus插件生成代码
在这里插入图片描述
分别点击两个选项完成配置数据库配置信息
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

静态工具

在这里插入图片描述
在这里插入图片描述
静态工具类(如 MyBatis-Plus 中的 SqlHelper)和 IService 接口在具体开发与实际使用中有一些区别,主要取决于它们的设计目的和使用场景:

设计目的:

静态工具类: 静态工具类的设计目的是提供一些通用的静态方法,用于执行底层的 SQL
操作或其他常见操作。这些方法通常是静态的,无需创建对象实例,用于简化底层操作。 IService 接口: IService 接口及其实现类
ServiceImpl 的设计目的是为了提供一些通用的 CRUD(增删改查)操作,封装常见的业务逻辑,提供了一种面向对象的服务层抽象。

使用场景:

静态工具类: 静态工具类适用于一些不涉及对象实例状态的操作,例如执行 SQL 查询,文件操作等。这些方法通常是静态的,可以通过类名直接调用。
IService 接口: IService 接口适用于业务服务层的抽象,封装了一些通用的业务操作,特别是针对实体对象的 CRUD
操作。IService 接口可以被业务层的服务类实现,提供具体的业务逻辑。

需求1
Controller层

    @GetMapping("/{id}")public UserVO selectUser(@PathVariable Long id) {return iUserService.queryUsersAndAddressById(id);}

Service实现类

    @Overridepublic UserVO queryUsersAndAddressById(Long id) {//1.查询用户User user = getById(id);if (user == null || user.getStatus() == 2){throw new RuntimeException("用户状态异常!");}//2.查询地址List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId, id).list();//3.封装VO//3.1装User的PO为VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);//3.2转地址VOif (CollUtil.isNotEmpty(addresses)) {userVO.setAddress(BeanUtil.copyToList(addresses, AddressVO.class));}return userVO;}

需求2
Controller层

    @ApiOperation("根据id批量查询用户接口")@GetMappingpublic List<UserVO> queryUserByIds(@RequestParam("ids") List<Long> ids) {return iUserService.queryUserAndAddressByIds(ids);}

Service实现类

    @Overridepublic List<UserVO> queryUserAndAddressByIds(List<Long> ids) {//1.查询用户List<User> users = listByIds(ids);if (CollUtil.isEmpty(users)){return Collections.emptyList();}//2.查询地址//2.1 获取用户id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());//2.2根据用户id查询地址List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();//2.3转换地址VOList<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);//2.4梳理地址集合,分类整理,相同用户的放入同一个集合中Map<Long, List<AddressVO>> addressMap = new HashMap<>();if (CollUtil.isNotEmpty(addressVOList)){addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));}//3.转VO返回List<UserVO> list = new ArrayList<>(users.size());for (User user : users){//3.1转换User的PO为VOUserVO vo = BeanUtil.copyProperties(user,UserVO.class);list.add(vo);//3.2转换地址VOvo.setAddress(addressMap.get(user.getId()));}return list;}

逻辑删除

在这里插入图片描述在这里插入图片描述

枚举处理器

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

JSON处理器

在这里插入图片描述

插件功能

分页插件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通用分页实体

在这里插入图片描述
Controller层

    @ApiOperation("根据条件分页查询用户接口查询")@GetMapping("/page")public PageDTO<UserVO> queryUserspage(UserQuery userQuery) {return iUserService.queryUserspage(userQuery);}

service实现类

    @Overridepublic PageDTO<UserVO> queryUserspage(UserQuery userQuery) {String name = userQuery.getName();Integer status = userQuery.getStatus();//1.构建查询条件//1.1分页条件Page<User> page = Page.of(userQuery.getPageNo(), userQuery.getPageSize());//1.2排序条件if (StrUtil.isNotBlank(userQuery.getSortBy())){//不为空page.addOrder(new OrderItem(userQuery.getSortBy(),userQuery.getIsAsc()));}else {//为空,默认按照更新时间排序page.addOrder(new OrderItem("update_time",false));}//2.分页查询Page<User> userPage = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);//3.封装VO结果PageDTO<UserVO> pageDTO = new PageDTO<>();//3.1总条数和总页数pageDTO.setTotal(userPage.getTotal());pageDTO.setPages(userPage.getPages());//当前页数据List<User> records = userPage.getRecords();if (CollUtil.isEmpty(records)){pageDTO.setList(Collections.emptyList());return pageDTO;}//拷贝User的VOList<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);pageDTO.setList(userVOS);//4.返回return pageDTO;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/459074.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拿捏循环链表

目录&#xff1a; 一&#xff1a;单链表&#xff08;不带头单向不循环&#xff09;与循环链表&#xff08;带头双向循环&#xff09;区别 二&#xff1a;循环链表初始化 三&#xff1a;循环链表头插 四&#xff1a;循环链表尾插 五&#xff1a;循环链表头删 六&#xff1…

【高阶数据结构】B-树详解

文章目录 1. 常见的搜索结构2. 问题提出使用平衡二叉树搜索树的缺陷使用哈希表的缺陷 3. B-树的概念4. B-树的插入分析插入过程分析插入过程总结 5. B-树的代码实现5.1 B-树的结点设计5.2 B-树的查找5.3 B-树的插入实现InsertKey插入和分裂测试 6. B-树的删除&#xff08;思想&…

跳过mysql5.7密码并重置密码 shell脚本

脚本 目前只是验证了5.7 版本是可以的&#xff0c;8.多的还需要验证 以下是一个简单的Shell脚本&#xff0c;用于跳过MySQL密码设置并重置密码&#xff1a; #!/bin/bash yum install psmisc -y# 停止MySQL服务 sudo service mysqld stop# 跳过密码验证 sudo mysqld --skip-g…

【MySQL进阶之路】SpringBoot 底层如何去和 MySQL 交互了呢?

SpringBoot 底层如何去和 MySQL 交互了呢&#xff1f; 我们在写做 Java 项目时&#xff0c;一般都是引入 MyBatis 框架来和 MySQL 数据库交互&#xff0c;如果需要在 MySQL 上执行什么语句&#xff0c;只需要在 Mapper.xml 文件中定义对应的 SQL 语句即可 那么他底层到底是如…

植物生长调节剂行业调研:预计2029年将达到1.2亿美元

未来增长的重点势必在以中国为代表的亚太地区。尤其在我国农业现代化、无人化发展需求下&#xff0c;提升种植的效率和品质是必然需求&#xff0c;我国市场规模增速也将高于全球平均水平。植物生长调节剂的应用具有成本低、收效快、效益高、节省劳动力的优点&#xff0c;不仅对…

Power Designer的使用 创建数据库表模型,生成sql语句,生成C#实体类

几年前用过PowerDesigner&#xff0c;好几年没用&#xff0c;有点忘记了&#xff0c;在这里记个笔记&#xff0c;需要的时候翻一翻 PowerDesigner版本16.5 下面的例子是以MySQL数据库为准 生成C#实体类 一 安装 1.1 安装 不让放网盘链接&#xff0c;审核通不过。。。。 …

windows+vscode配置远程Linux开发环境

1.Linux运行sshd服务 安装openssh-server sudo apt install openssh-server 开启服务 sudo service ssh start 检查sshd是否开启 sudo ps -aux | grep sshd 2.vscode上安装RemoteDevelopment插件 其他依赖性会自动安装 3.配置远程Linux主机信息 Linux主机ip 4.在vscode…

leetCode二叉树的堂兄弟节点 II

题目 给你一棵二叉树的根 root &#xff0c;请你将每个节点的值替换成该节点的所有 堂兄弟节点值的和 。 如果两个节点在树中有相同的深度且它们的父节点不同&#xff0c;那么它们互为 堂兄弟 。 请你返回修改值之后&#xff0c;树的根 root 。 注意&#xff0c;一个节点的…

代码随想录算法训练营第29天 | 491.递增子序列 ,46.全排列 ,47.全排列 II

回溯章节理论基础&#xff1a; https://programmercarl.com/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 491.递增子序列 题目链接&#xff1a;https://leetcode.cn/problems/non-decreasing-subsequences/ 思路&#xff1a; 本题求自…

关于域名递归解析服务的问题

域名递归解析服务是互联网基础设施的重要组成部分&#xff0c;它允许用户通过域名来访问网站或应用程序。然而&#xff0c;在某些情况下&#xff0c;域名递归解析服务可能会出现问题&#xff0c;导致用户无法正常访问网站或应用程序。本文将探讨域名递归解析服务可能面临的问题…

一文带你搞定搭建自己的组件库Rollup

一文带你搞定搭建自己的组件库(rollup.js) 目前Vue和React都是采用rollup.js进行打包,我们在公司开发的时候也可以用rollup搭建一个自己的组件库放到你的项目中,简化项目的结构项目性能。 接下来我将带你使用rollup从0——1搭建一个在vue中使用的组件库 开发前准备 我的开发…

提示由于找不到msvcp120dll无法继续执行此代码怎么办

在计算机系统中&#xff0c;MSVCP120.dll是一个至关重要的动态链接库文件&#xff0c;它是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多基于Windows的应用程序运行至关重要。当系统提示“msvcp120dll丢失”时&#xff0c;意味着该文件可能由于误删…