MyBaitsPlus 基本用法简单整理

整理一下 MyBaitsPlus 的一点简单用法。

在这里插入图片描述


查询时:new QueryWrapper,QueryWrapper 是 MyBatis-Plus 中用于构建查询操作的条件封装类

修改是:new UpdateWrapper,UpdateWrapper 是 MyBatis-Plus 中用于构建更新操作的条件封装类

//查询
QueryWrapper<XxxWalletEntity> xxxWalletEntityQueryWrapper = new QueryWrapper<>();
        
LambdaQueryWrapper<XxxWalletEntity> lambda = new QueryWrapper<XxxWalletEntity>().lambda();
        
LambdaQueryWrapper<XxxWalletEntity> in = new QueryWrapper<XxxWalletEntity>().lambda()
                .in(XxxWalletEntity::getAccountId, accountIds);
//修改
UpdateWrapper<XxxWalletEntity> updateWrapper = new UpdateWrapper<>();
            
LambdaUpdateWrapper<XxxWalletEntity> lambda = new UpdateWrapper<XxxWalletEntity>().lambda();

LambdaUpdateWrapper<XxxWalletEntity> eq = new UpdateWrapper<XxxWalletEntity>().lambda()
                    .eq(XxxWalletEntity::getAccountId, accountId);
                    .setSql("balance = balance + " + balance));

查询

单表查询

查询单条数据

写法一:(this.getOne)

是 MyBatis-Plus 提供的方法
this.getOne 返回的是一条数据

    /**
     * 根据用户id查询对象的数据
     * BusinessEntity 实体类对应的数据库表中有一个userId,根据这个查询查询该条数据
     */
    @Override
    public BusinessServiceDto getByUserId(Integer userId) {
        if (userId == null) {
            return null;
        }
        //根据id查询单条数据
        BusinessEntity businessEntity = this.getOne(new QueryWrapper<BusinessEntity>().lambda()
                .eq(BusinessEntity::getUserId, userId));
                
        //to方法是实体类转Dto的方法
        return this.to(businessEntity);
    }
//这一步是构建查询对象
new QueryWrapper<BusinessEntity>().lambda()
                .eq(BusinessEntity::getUserId, userId)

//这一步是执行查询             
this.getOne();


写法二:(XxxMapper.selectById)

是 MyBatis 的原生 Mapper 方法,尽管在 MyBatis-Plus 中也可以使用,但不是 MP 提供的

    /**
     * 根据id查询
     */
    @Override
    public XxxDto getXxxById(Integer id) {
        return this.to(xxxMapper.selectById(id));
    }

写法三:(this.getById)

是 MyBatis-Plus 提供的方法

    /**
     * 根据订单Id查询该对象
     */
    @Override
    public XxxOrderServiceDto getRiderXxxOrderById(Integer xxxOrderId) {
        if (xxxOrderId == null) {
            return null;
        }
        //获取对象
        XxxOrderEntity xxxOrderEntity = this.getById(xxxOrderId);
        //entity转serviceDto返回
        return this.to(xxxOrderEntity);
    }

查询 list 集合(this.list)

查询所有

this.list() 返回的是一个 list 集合

    /**
     * 根据userId查询一个列表集合
     */
    @Override
    public List<UserServiceDto> getUserListByuserId(Integer userId) {
    
    	//判空
        if (riderId == null) {
            return new ArrayList<>();
        }
        
        //查询
        List<UserEntity> list = this.list(new QueryWrapper<UserEntity>().lambda()
                .eq(UserEntity::getUserId, userId));
                
		//将list集合中的实体类转成Dto类型再返回
        return list.stream()
                .map(this::to)
                .collect(Collectors.toList());
    }

	//实体类转Dto
    private UserServiceDtoto(UserEntity entity) {
        if (entity == null) {
            return null;
        }
        UserServiceDtoto userServiceDtoto = new UserServiceDtoto();
        UserServiceDtoto.setId(entity.getId());
        //.......
        UserServiceDtoto.setRemark(entity.getRemark());
        UserServiceDtoto.setCreateTime(entity.getCreateTime());
        UserServiceDtoto.setUpdateTime(entity.getUpdateTime());
        return userServiceDtoto;
    }

限制查询条数
    @Override
    public List<XxxServiceDto> selectList() {
        List<XxxEntity> list = this.list(new QueryWrapper<XxxEntity>().lambda()
        
        		//这表示数据库只会返回前 1000 条匹配的记录
                .last(" limit 1000"));

        return list.stream().map(this::to).collect(Collectors.toList());
    }

分页查询(this.page)

    /**
     * 单表分页查询
     */
    @Override
    public PageInter<XxxServiceDto> getXxxList(String title, Integer status, PageParam pageParam) {
        //分页
        Page<XxxEntity> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        //mp单表查询
        Page<XxxEntity> pageList = this.page(page, new QueryWrapper<XxxEntity>().lambda()
        		//如果title不为空,则执行查询
                .like(ObjectUtil.isNotEmpty(title), XxxEntity::getTitle, title)
                //如果status不为空,则执行查询
                .eq(ObjectUtil.isNotEmpty(status), XxxEntity::getStatus, status)
                //根据时间进行倒序
                .orderByDesc(XxxEntity::getAddTime));
        return PageInter.to(pageList, this::to);
    }

mp工具类里面的翻页查询方法-- page方法源码

在这里插入图片描述


备注:如果是调用分页查询的方法(SQL连表查询),但是想得到不分页的list集合,Page参数可以这么设置,list可以用getRecords()方法获取

    //如果调用分页查询的方法,相要得到不分页的list集合,那么这个分页参数对象的参数可以这样设置
    Page<XxxDto> page = new Page<>(1, -1);
    //查询,得到的是一个分页对象
    page = xxxMapper.getXxxList(page, xx, xx, xx);
    //从分页对象获取list集合
    List<XxxDto> list = page.getRecords();


其他示例

    /**
     * Xxx商场-Xxx装备-分页查询
     */
    @Override
    public PageInter<XxxServiceDto> getRiderXxxList(String title, Integer status, PageParam pageParam) {
        //分页
        Page<XxxEntity> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        //mp单表查询
        Page<XxxEntity> pageList = this.page(page, new QueryWrapper<XxxEntity>().lambda()
                .like(ObjectUtil.isNotEmpty(title), XxxEntity::getTitle, title)
                .eq(ObjectUtil.isNotEmpty(status), XxxEntity::getStatus, status)
                .orderByDesc(XxxEntity::getAddTime));
        return PageInter.to(pageList, this::to);
    }

单表模糊查询(like)

//如果title不为空,则执行查询
.like(ObjectUtil.isNotEmpty(title), XxxEntity::getTitle, title)

单表范围查询(in、between)

//IN 用于检查某个值是否在指定的集合中
//判断ids不为空,然后获取XxxEntity实体类的id,且需要该id存在Ids集合中
.in(CollUtil.isNotEmpty(Ids), XxxEntity::getId, Ids)
//查找状态为 0 或 2 的记录
.in(XxxEntity::getStatus, 0, 2)
//BETWEEN 用于检查某个值是否在两个指定值之间(包括这两个值)
 .between(dateStart != null && dateEnd != null, XxxEntity::getCreateTime, dateStart, dateEnd));

倒序查询(orderByDesc)

//根据addTime进行倒序查询
.orderByDesc(XxxEntity::getAddTime)

构建多个查询条件

写法一:(and 、or)

这种写法来构建多个查询条件比较不直观

    @Override
    public PageInter<AccountMovementLogServiceDto> getXxxxxxLog(Integer businessId, PageParam pageParam) {

        //分页对象
        Page<AccountMovementLogEntity> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());

        //分页单表查询
        page = this.page(page, new QueryWrapper<AccountMovementLogEntity>().lambda()
                .and(wrapper -> wrapper
                        .eq(businessId != null, AccountMovementLogEntity::getMovementId, businessId)
                        // 该商家是资金移动方
                        .eq(AccountMovementLogEntity::getMovementType, AccountMovementLogType.BUSINESS.getType()))
                .or(wrapper -> wrapper
                        .eq(businessId != null, AccountMovementLogEntity::getReceiveId, businessId)
                        // 该商家是资金接收方
                        .eq(AccountMovementLogEntity::getReceiveType, AccountMovementLogType.BUSINESS.getType()))
                .orderByDesc(AccountMovementLogEntity::getCreateTime));

        //entity 转 dto 再返回
        return PageInter.to(page, this::to);
    }

写法二:(or)
    /**
     * 根据Pid查询分组列表
     */
    @Override
    public List<AuthGroupServiceDto> selectListByPid(Integer pid) {
        LambdaQueryWrapper<AuthGroupEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DsAuthGroupEntity::getPid, pid);
        //如果 a.eq(AuthGroupEntity::getRules == “*”,则再查询 AuthGroupEntity::getPid == pid
        wrapper.or(a -> a.eq(AuthGroupEntity::getRules, "*").and(b -> b.eq(AuthGroupEntity::getPid, pid)));

        return this.list(wrapper).stream()
                .map(this::to)
                .collect(Collectors.toList());
    }

写法三:简单判断并构建查询条件

直接if条件判断,然后再把查询条件构建到 LambdaQueryWrapper 对象即可,最后再用 this.list() 执行查询,再调用 .stream() 方法把entity 转成 dto

    @Override
    public List<XxxServiceDto> selectXxxList(ArchiveParam param) {
        LambdaQueryWrapper<XxxEntity> queryWrapper = new QueryWrapper<XxxEntity>().lambda()
        		//使用 select(XxxEntity::getId) 指定查询结果只返回 XxxEntity 中的 id 字段,因此查询将返回一个 id 列表
                .select(XxxEntity::getId)
                .in(CollUtil.isNotEmpty(param.getIds()), XxxEntity::getId, param.getIds());
        //根据条件判断,构建查询条件
        if (param.getBegin() != null) {
            queryWrapper.ge(XxxEntity::getDateTime, param.getBegin());
        }
        if (param.getEnd() != null) {
            queryWrapper.le(XxxEntity::getDateTime, param.getEnd());
        }
        //调用 this.list() 方法执行查询,得到一个元素为 XxxEntity 类型的 list 集合
        return this.list(queryWrapper)
        		//将集合(如列表、集合等)转换为流(Stream)对象
        		.stream()
        		//调用当前类中的 to 方法进行转换,具体是把 XxxEntity 转成成 dto。
                .map(this::to)
                //将转换后的结果收集到一个列表中并返回
                .collect(Collectors.toList());
    }

上面的这个select 和 in 构建的查询条件类似于如下:只查询id

SELECT id FROM XxxEntity WHERE id IN (value1, value2, ..., valueN);

不等于(ne)

.ne(…):这个方法代表 “not equal”(不等于)的意思,表示查询的条件中要求某个字段的值不等于给定的值。

    /**
     * 查询管理员列表
     */
    @Override
    public List<AdminXxxxxDto> getAdminList() {
        List<AdminEntity> list = this.list(new LambdaQueryWrapper<AdminEntity>()
                .eq(AdminEntity::getStatus, 1)
                .ne(AdminEntity::getCityId, 0));
        return list.stream()
                .map(this::to)
                .collect(Collectors.toList());
    }

小于(le)

小于等于:le (less than or equal to)
大于:gt (greater than)

    @Override
    public List<XxxServiceDto> getTaskList() {
        List<XxxEntity> list = this.list(new QueryWrapper<XxxEntity>().lambda()
        		 //日期判断,小于
                .le(XxxEntity::getCompTime, new Date())
                //查找状态为 0 或 2 的记录
                .in(XxxEntity::getStatus, 0, 2)
                //限制查询结果为最多 100 条
                .last(" limit 100"));
        return list.stream().map(this::to).collect(Collectors.toList());
    }

不为null

写法一:(isNotNull)
    @Override
    public List<CityServiceDto> getCityInfoList(Boolean examinable, Boolean expire, Boolean normality) {
        List<DsCityEntity> list = this.list(new QueryWrapper<CityEntity>().lambda()
                .eq(CityEntity::getIsDisabled, 0)
                .eq(examinable != null, CityEntity::isExaminable, examinable)
                .eq(expire != null, CityEntity::isExpire, expire)
                .eq(normality != null, CityEntity::isNormalCity, normality)
                .isNotNull(CityEntity::getMapLatLng)
                .ne(CityEntity::getMapLatLng, ""));

        return list.stream()
                .map(this::to)
                .collect(Collectors.toList());
    }

写法二:(filter)

这个是在 stream 流中惊醒过滤的

    /**
     * 获取所有列表
     */
    @Override
    public List<DevelopApisServiceDto> getList(String suggest) {
        List<DevelopApisEntity> list = this.list(new QueryWrapper<DevelopApisEntity>().lambda()
                .like(StrUtil.isNotBlank(suggest), DevelopApisEntity::getName, suggest));
        return list.stream()
                .map(this::to)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

.isNotNull(…):是 mp 的从数据库中查出非null的数据;
filter(Objects::nonNull): 是把查询来的数据,在内存中再进行一次处理


单表批量查询(in)

    @Override
    public Map<Integer, String> getNameBatch(List<Integer> ids) {
        if (CollUtil.isEmpty(ids)) {
            return new HashMap<>();
        }
        List<CityEntity> list = this.list(new QueryWrapper<CityEntity>().lambda()
                .in(CityEntity::getId, ids));
        return list.stream()
                .collect(Collectors.toMap(CityEntity::getId, CityEntity::getName));
    }

单表分批批量查询(ListUtil.partition)★★★

在这里插入图片描述

/**
 * 根据骑手ids集合批量查询
 */
@Override
public Map<Integer, RiderBindServiceDto> getBindByRiderIds(List<Integer> riderIds) {
    if (CollUtil.isEmpty(riderIds)) {
        return new HashMap<>();
    }
    //把骑手ids集合分区,一个list元素存100个骑手id
    List<List<Integer>> partition = ListUtil.partition(riderIds, 100);

    Map<Integer, RiderBindServiceDto> bindServiceDtoMap = partition.stream()
            .map(v -> this.list(new QueryWrapper<DsRiderBindEntity>().lambda()
                    .in(DsRiderBindEntity::getRiderId, v)))
            .flatMap(Collection::stream)
            .map(this::to)
            .collect(Collectors.toMap(RiderBindServiceDto::getRiderId, Function.identity()));

    return bindServiceDtoMap;
}

解释:

在这里插入图片描述


新增或修改

单表新增

批量新增(saveBatch)

把 list 集合的数据新增到数据库,需要把集合的对象先转成 entity 实体类

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertXxxList(List<DailyXxxDto> allBusinessList) {

        //dto 转 entity
        List<DailyXxxEntity> businessList = allBusinessList.stream().map(this::to).collect(Collectors.toList());
        //执行批量插入操作
        return this.saveBatch(businessList);
    }

单表修改

写法一:(update)

修改某个实体,这里是 new UpdateWrapper

    @Override
    public boolean updateFlag(Integer cityId, boolean examinablexxx, boolean expirexxx, boolean normalCityxxx) {
        if (cityId == null) {
            return false;
        }
        return this.update(new UpdateWrapper<CityEntity>().lambda()
                .set(CityEntity::isExaminablexxx, examinablexxx)
                .set(CityEntity::isExpirexxx, expirexxx)
                .set(CityEntity::isNormalCityxxx, normalCityxxx)
                .eq(CityEntity::getId, cityId));
    }

写法二:(updateById)

    /**
     * 修改Xxx根据Id
     */
    @Override
    public Boolean updateXxx(XxxDto dto) {
        if (dto == null) {
            return null;
        }
        //把 dto转成entity,再执行修改操作
        return this.updateById(this.to(dto));
    }

写法三:(.setEntity 修改实体)

根据id修改整个实体对象

setEntity(…):这个方法是 UpdateWrapper 的一个调用,用于指定更新操作中使用的实体对象。调用 setEntity 后,更新操作会将指定实体的字段值更新到数据库中

    /**
     * 更新账户余额
     */
    @Override
    public boolean updateAccount(XxxWalletDto dto) {
        if (dto == null) {
            return false;
        }
        XxxWalletEntity entity = this.to(dto);
        return this.update(new UpdateWrapper<XxxWalletEntity>().lambda()
                .eq(XxxWalletEntity::getAccountId, entity.getAccountId())
                .setEntity(this.to(dto)));
    }

写法四:(.setSql 拼接sql )

    /**
     * 增加账户余额
     */
    @Override
    public boolean addWallet(Integer accountId, BigDecimal balance) {
        // 加锁
        LockUtil.openAccountBalance(accountId, () -> {
            if (accountId == null || BigDecimal.ZERO.compareTo(balance) >= 0) {
                throw BizException.newInstance(ErrorCode.ARGUMENT_ERROR);
            }
            // 这个执行修改的对应的sql语句:
            // UPDATE xxx_wallet_entity SET balance = balance + ? WHERE account_id = ?
            this.update(new UpdateWrapper<XxxWalletEntity>().lambda()
                    .eq(XxxWalletEntity::getAccountId, accountId)
                    .setSql("balance = balance + " + balance));
        }, () -> {
            throw BizException.newInstance(ErrorCode.BUSY);
        });
        return true;
    }

更新指定字段(.set)

通过 id 更新该行数据指定的字段


    /**
     * 更新地址
     */
    @Override
    public boolean xxxUpdateAddress(Integer orderId, String address, LocationDto location) {
        if (orderId == null || location == null) {
            return false;
        }
        return this.update(new UpdateWrapper<XxxAddressEntity>().lambda()
                .set(XxxAddressEntity::getEndAddress, address)
                .set(XxxAddressEntity::getEndLat, location.getLatitude())
                .set(XxxAddressEntity::getEndLng, location.getLongitude())
                .eq(XxxAddressEntity::getOrderId, orderId)
        );
    }

this.update 执行修改操作后生成的 sql 示例:

UPDATE xxx_address 
SET end_address = '某地地址', end_lat = 30.123456, end_lng = 120.654321 
WHERE order_id = 123

新增或修改(this.saveOrUpdate)

更具对象是否有id来判断是新增还是修改

    /**
     * Xxx商场-Xxx装备-添加/编辑
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean xxxSaveOrUpdate(XxxServiceDto xxxServiceDto) {
        //把Dto转成Entity,调用mp方法执行添加和编辑操作
        return this.saveOrUpdate(this.to(xxxServiceDto));
    }

删除

写法一:(.removeBatchByIds)

根据ids集合,进行删除,可以单个也可批量。

    /**
     * 商城-商城订单-删除(单个/批量)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteXxxOrderById(List<Integer> ids) {
        if (ids == null || ids.isEmpty()){
            return false;
        }
        return this.removeBatchByIds(ids);
    }

写法二:(.remove)

使用了 MyBatis-Plus 的 remove 方法和 QueryWrapper 来构建删除条件

    /**
     * 根据id删除xxx信息
     */
    @Override
    public boolean removeByRiderIds(List<XxxServiceDto> riderList) {
        if (CollUtil.isEmpty(riderList)) {
            return false;
        }
        List<Integer> riderIds = riderList.stream()
                .map(XxxServiceDto::getRiderId)
                .collect(Collectors.toList());
        // 执行删除方法
        return this.remove(new QueryWrapper<XxxEntity>().lambda()
                .in(XxxEntity::getRiderId, riderIds));
    }

写法三:( .removeById)

根据id删除

    /**
     * 删除
     */
    @Override
    public boolean removeById(Long id) {
        if (id == null) {
            return false;
        }
        return super.removeById(id);
    }


流操作

    /**
     * 获取订单小费
     */
    @Override
    public BigDecimal getOrderTips(Integer orderId) {
        if (orderId == null) {
            return BigDecimal.ZERO;
        }

        List<XxxOrderTipEntity> list = this.list(new QueryWrapper<XxxOrderTipEntity>().lambda()
                .eq(XxxOrderTipEntity::getOid, orderId)
                .eq(XxxOrderTipEntity::getBusiPay, 1)
                .eq(XxxOrderTipEntity::getIsPay, 1)
                .eq(XxxOrderTipEntity::getIsUse, 1));
                
        //使用 Java Stream API 对小费记录进行处理:
        Optional<Integer> amount = list.stream()
        		// filter 方法用于过滤掉 amount 为 null 或 0 的记录
                .filter(v -> v.getAmount() != null && v.getAmount() != 0)
                // map 方法提取每个有效小费的 amount 值
                .map(XxxOrderTipEntity::getAmount)
                // 使用 reduce 方法将流中的所有金额进行累加
                // Integer::sum 是一个方法引用,用于将流中的所有元素相加,最终返回一个 Optional<Integer>
                .reduce(Integer::sum);

        return amount.map(integer -> new BigDecimal(integer)
        				// new BigDecimal(100) 是除数,表示将金额从分转换为元。
        				// 2 表示结果保留两位小数。
        				// RoundingMode.DOWN:指定取整模式为向下取整,这意味着在小数点后超出的部分会被舍去
                        .divide(new BigDecimal(100), 2, RoundingMode.DOWN))
                // 如果 amount 是空的(即没有有效小费记录),orElse 方法将返回 BigDecimal.ZERO,表示小费总额为零
                .orElse(BigDecimal.ZERO);
    }

divide 是 BigDecimal 类中的一个方法,用于执行除法运算。具体来说,divide 方法的作用是将一个 BigDecimal 对象除以另一个 BigDecimal 对象,并返回一个新的 BigDecimal 结果

.orElse(BigDecimal.ZERO) 的解释:

如果 list 中没有任何满足过滤条件的 XxxOrderTipEntity 对象(即没有有效的小费金额),则流操作将不会产生任何元素,最终的 reduce 方法返回的是 Optional.empty()




### 关于 MyBatisPlus 的 Greater Than 使用方法 MyBatis-Plus 是一款增强型的 MyBatis 框架,它简化了开发流程并提供了丰富的功能支持。对于实现 `greater than`(大于)条件查询的操作,可以通过多种方式完成。 #### 方法一:使用 Wrapper 构建器 MyBatis-Plus 提供了一个强大的动态 SQL 构建工具——Wrapper 接口及其子类 QueryWrapper 和 UpdateWrapper。可以利用这些接口来构建复杂的查询条件。以下是通过 `QueryWrapper` 实现大于操作的一个例子: ```java import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.demo.entity.User; public class UserService { public List<User> getUsersOlderThan(int age) { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.gt("age", age); // gt 表示 greater than return userMapper.selectList(queryWrapper); } } ``` 上述代码片段展示了如何使用 `gt()` 方法设置字段值大于指定数值的条件[^3]。 #### 方法二:自定义 SQL 查询语句 如果需要更灵活或者复杂一些的查询逻辑,则可以选择编原生 SQL 并结合 MyBatis-Plus 进行调用。下面是一个简单的例子展示如何手动入带有 “>`” 符号的 SQL 条件: ```sql SELECT * FROM users WHERE age > #{age}; ``` 然后将其映射到对应的 Mapper 文件中去执行相应的 DAO 层操作即可[^4]。 #### 注意事项 当处理数据库中的比较运算符时,请始终注意数据类型的匹配以及可能存在的空值情况等问题;另外还需考虑性能优化方面的事情比如索引的应用等[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_L_J_H_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值