/* * Copyright (c) 2011-2024, baomidou (jobob@qq.com). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.baomidou.mybatisplus.extension.toolkit; import com.baomidou.mybatisplus.core.conditions.AbstractWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper; import com.baomidou.mybatisplus.extension.kotlin.KtQueryChainWrapper; import com.baomidou.mybatisplus.extension.kotlin.KtUpdateChainWrapper; import org.apache.ibatis.executor.BatchResult; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * 以静态方式调用Service中的函数 * * @author VampireAchao * @since 2022-05-03 */ public class Db { private static final Log log = LogFactory.getLog(Db.class); private Db() { /* Do not new me! */ } /** * 插入一条记录(选择字段,策略插入) * * @param entity 实体对象 */ public static boolean save(T entity) { if (Objects.isNull(entity)) { return false; } Integer result = SqlHelper.execute(getEntityClass(entity), baseMapper -> baseMapper.insert(entity)); return SqlHelper.retBool(result); } /** * 插入(批量) * * @param entityList 实体对象集合 */ public static boolean saveBatch(Collection entityList) { return saveBatch(entityList, Constants.DEFAULT_BATCH_SIZE); } /** * 插入(批量) * * @param entityList 实体对象集合 * @param batchSize 插入批次数量 */ public static boolean saveBatch(Collection entityList, int batchSize) { if (CollectionUtils.isEmpty(entityList)) { return false; } Class entityClass = getEntityClass(entityList); List batchResults = SqlHelper.execute(entityClass, baseMapper -> baseMapper.saveBatch(entityList, batchSize)); return batchResults.stream().flatMapToInt(r -> IntStream.of(r.getUpdateCounts())).allMatch(i -> i > 0); } /** * 批量修改插入 * * @param entityList 实体对象集合 */ public static boolean saveOrUpdateBatch(Collection entityList) { return saveOrUpdateBatch(entityList, Constants.DEFAULT_BATCH_SIZE); } /** * 批量修改插入 * * @param entityList 实体对象集合 * @param batchSize 每次的数量 */ public static boolean saveOrUpdateBatch(Collection entityList, int batchSize) { if (CollectionUtils.isEmpty(entityList)) { return false; } Class entityClass = getEntityClass(entityList); List batchResults = SqlHelper.execute(entityClass, baseMapper -> baseMapper.saveOrUpdateBatch(entityList, batchSize)); return batchResults.stream().flatMapToInt(r -> IntStream.of(r.getUpdateCounts())).allMatch(i -> i > 0); } /** * 根据 ID 删除 * * @param id 主键ID * @param entityClass 实体类 */ public static boolean removeById(Serializable id, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> SqlHelper.retBool(baseMapper.deleteById(id))); } /** * 根据实体(ID)删除 * * @param entity 实体 */ public static boolean removeById(T entity) { if (Objects.isNull(entity)) { return false; } return SqlHelper.execute(getEntityClass(entity), baseMapper -> SqlHelper.retBool(baseMapper.deleteById(entity))); } /** * 根据 entity 条件,删除记录 * * @param queryWrapper 实体包装类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static boolean remove(AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> SqlHelper.retBool(baseMapper.delete(queryWrapper))); } /** * 根据 ID 选择修改 * * @param entity 实体对象 */ public static boolean updateById(T entity) { if (Objects.isNull(entity)) { return false; } return SqlHelper.execute(getEntityClass(entity), baseMapper -> SqlHelper.retBool(baseMapper.updateById(entity))); } /** * 根据 UpdateWrapper 条件,更新记录 需要设置sqlset * * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} */ public static boolean update(AbstractWrapper updateWrapper) { return update(null, updateWrapper); } /** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} */ public static boolean update(T entity, AbstractWrapper updateWrapper) { return SqlHelper.execute(getEntityClass(updateWrapper), baseMapper -> SqlHelper.retBool(baseMapper.update(entity, updateWrapper))); } /** * 根据ID 批量更新 * * @param entityList 实体对象集合 */ public static boolean updateBatchById(Collection entityList) { return updateBatchById(entityList, Constants.DEFAULT_BATCH_SIZE); } /** * 根据ID 批量更新 * * @param entityList 实体对象集合 * @param batchSize 更新批次数量 */ public static boolean updateBatchById(Collection entityList, int batchSize) { Class entityClass = getEntityClass(entityList); List batchResults = SqlHelper.execute(entityClass, baseMapper -> baseMapper.updateBatchById(entityList, batchSize)); return batchResults.stream().flatMapToInt(r -> IntStream.of(r.getUpdateCounts())).allMatch(i -> i > 0); } /** * 删除(根据ID 批量删除) * * @param list 主键ID或实体列表 * @param entityClass 实体类 */ public static boolean removeByIds(Collection list, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> SqlHelper.retBool(baseMapper.deleteBatchIds(list))); } /** * 根据 columnMap 条件,删除记录 * * @param columnMap 表字段 map 对象 * @param entityClass 实体类 */ public static boolean removeByMap(Map columnMap, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> SqlHelper.retBool(baseMapper.deleteByMap(columnMap))); } /** * TableId 注解存在更新记录,否插入一条记录 * * @param entity 实体对象 */ public static boolean saveOrUpdate(T entity) { if (Objects.isNull(entity)) { return false; } return SqlHelper.execute(getEntityClass(entity), baseMapper -> baseMapper.saveOrUpdate(entity)); } /** * 根据 ID 查询 * * @param id 主键ID * @param entityClass 实体类 */ public static T getById(Serializable id, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectById(id)); } /** * 根据 Wrapper,查询一条记录
*

结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")

* * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static T getOne(AbstractWrapper queryWrapper) { return getOne(queryWrapper, true); } /** * 根据 entity里不为空的字段,查询一条记录
*

结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")

* * @param entity 实体对象 */ public static T getOne(T entity) { return getOne(Wrappers.lambdaQuery(entity), true); } /** * 根据 entity里不为空的字段,查询一条记录 * * @param entity 实体对象 * @param throwEx 有多个 result 是否抛出异常 */ public static T getOne(T entity, boolean throwEx) { return getOne(Wrappers.lambdaQuery(entity), throwEx); } /** * 根据 Wrapper,查询一条记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param throwEx 有多个 result 是否抛出异常 */ public static T getOne(AbstractWrapper queryWrapper, boolean throwEx) { Class entityClass = getEntityClass(queryWrapper); if (throwEx) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectOne(queryWrapper)); } return SqlHelper.execute(entityClass, baseMapper -> SqlHelper.getObject(log, baseMapper.selectList(queryWrapper))); } /** * 查询(根据 columnMap 条件) * * @param columnMap 表字段 map 对象 * @param entityClass 实体类 */ public static List listByMap(Map columnMap, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectByMap(columnMap)); } /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表 * @param entityClass 实体类 */ public static List listByIds(Collection idList, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectBatchIds(idList)); } /** * 根据 Wrapper,查询一条记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static Map getMap(AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> SqlHelper.getObject(log, baseMapper.selectMaps(queryWrapper))); } /** * 根据 entity不为空条件,查询一条记录 * * @param entity 实体对象 */ public static Map getMap(T entity) { return getMap(Wrappers.lambdaQuery(entity)); } /** * 查询总记录数 * * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static long count(Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectCount(null)); } /** * 根据entity中不为空的数据查询记录数 * * @param entity 实体类 */ public static long count(T entity) { return count(Wrappers.lambdaQuery(entity)); } /** * 根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static long count(AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectCount(queryWrapper)); } /** * 查询列表 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static List list(AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectList(queryWrapper)); } /** * @param page 分页条件 * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param entity * @return 列表数据 */ public static List list(IPage page, AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectList(page, queryWrapper)); } /** * 查询所有 * * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static List list(Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectList(null)); } /** * @param page 分页条件 * @param entityClass 实体类 * @param entity * @return 列表数据 * @since 3.5.3.2 */ public static List list(IPage page, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectList(page, null)); } /** * 根据entity中不为空的字段进行查询 * * @param entity 实体类 * @see Wrappers#emptyWrapper() */ public static List list(T entity) { return list(Wrappers.lambdaQuery(entity)); } /** * 根据entity中不为空的字段进行查询 * * @param page 分页条件 * @param entity 实体类 * @param entity * @return 列表数据 * @since 3.5.3.2 */ public static List list(IPage page, T entity) { return list(page, Wrappers.lambdaQuery(entity)); } /** * 查询列表 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static List> listMaps(AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectMaps(queryWrapper)); } /** * @since 3.5.3.2 * @param page 分页参数 * @param queryWrapper queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @return 列表数据 * @param entity */ public static List> listMaps(IPage> page, AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectMaps(page, queryWrapper)); } /** * 查询所有列表 * * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static List> listMaps(Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectMaps(null)); } /** * 分页查询列表 * * @param page 分页条件 * @param entityClass 实体类 * @param entity * @return 列表数据 * @since 3.5.3.2 */ public static List> listMaps(IPage> page, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectMaps(page, null)); } /** * 根据entity不为空的条件查询列表 * * @param entity 实体类 */ public static List> listMaps(T entity) { return listMaps(Wrappers.lambdaQuery(entity)); } /** * 根据entity不为空的条件查询列表 * * @param page 分页条件 * @param entity entity * @param entity * @return 列表数据 * @since 3.5.3.2 */ public static List> listMaps(IPage> page, T entity) { return listMaps(page, Wrappers.lambdaQuery(entity)); } /** * 查询全部记录 * * @param entityClass 实体类 */ public static List listObjs(Class entityClass) { return listObjs(entityClass, i -> i); } /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static List listObjs(AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectObjs(queryWrapper)); } /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param mapper 转换函数 */ public static List listObjs(AbstractWrapper queryWrapper, SFunction mapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectList(queryWrapper).stream().map(mapper).collect(Collectors.toList())); } /** * 查询全部记录 * * @param entityClass 实体类 * @param mapper 转换函数 */ public static List listObjs(Class entityClass, SFunction mapper) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectList(null).stream().map(mapper).collect(Collectors.toList())); } /** * 无条件翻页查询 * * @param page 翻页对象 * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static >> E pageMaps(E page, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectMapsPage(page, null)); } /** * 翻页查询 * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static >> E pageMaps(E page, AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectMapsPage(page, queryWrapper)); } /** * 无条件翻页查询 * * @param page 翻页对象 * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static IPage page(IPage page, Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectPage(page, null)); } /** * 翻页查询 * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ public static IPage page(IPage page, AbstractWrapper queryWrapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> baseMapper.selectPage(page, queryWrapper)); } /** * 链式查询 普通 * * @return QueryWrapper 的包装类 */ public static QueryChainWrapper query(Class entityClass) { return ChainWrappers.queryChain(entityClass); } /** * kt链式查询 * * @return KtQueryWrapper 的包装类 */ public static KtQueryChainWrapper ktQuery(Class entityClass) { return ChainWrappers.ktQueryChain(entityClass); } /** * 链式查询 lambda 式 *

注意:不支持 Kotlin

* * @return LambdaQueryWrapper 的包装类 */ public static LambdaQueryChainWrapper lambdaQuery(Class entityClass) { return ChainWrappers.lambdaQueryChain(entityClass); } /** * 链式更改 普通 * * @return UpdateWrapper 的包装类 */ public static UpdateChainWrapper update(Class entityClass) { return ChainWrappers.updateChain(entityClass); } /** * kt链式更改 * * @return KtUpdateWrapper 的包装类 */ public static KtUpdateChainWrapper ktUpdate(Class entityClass) { return ChainWrappers.ktUpdateChain(entityClass); } /** * 链式更改 lambda 式 *

注意:不支持 Kotlin

* * @return LambdaUpdateWrapper 的包装类 */ public static LambdaUpdateChainWrapper lambdaUpdate(Class entityClass) { return ChainWrappers.lambdaUpdateChain(entityClass); } /** *

* 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法 * 此次修改主要是减少了此项业务代码的代码量(存在性验证之后的saveOrUpdate操作) *

* * @param entity 实体对象 */ public static boolean saveOrUpdate(T entity, AbstractWrapper updateWrapper) { return update(entity, updateWrapper) || saveOrUpdate(entity); } /** * 根据 Wrapper,查询一条记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param mapper 转换函数 */ public static V getObj(AbstractWrapper queryWrapper, SFunction mapper) { return SqlHelper.execute(getEntityClass(queryWrapper), baseMapper -> mapper.apply(baseMapper.selectOne(queryWrapper))); } /** * 从集合中获取实体类型 * * @param entityList 实体集合 * @param 实体类型 * @return 实体类型 */ protected static Class getEntityClass(Collection entityList) { Class entityClass = null; for (T entity : entityList) { if (entity != null && entity.getClass() != null) { entityClass = getEntityClass(entity); break; } } Assert.notNull(entityClass, "error: can not get entityClass from entityList"); return entityClass; } /** * 从wrapper中尝试获取实体类型 * * @param queryWrapper 条件构造器 * @param 实体类型 * @return 实体类型 */ protected static Class getEntityClass(AbstractWrapper queryWrapper) { Class entityClass = queryWrapper.getEntityClass(); if (entityClass == null) { T entity = queryWrapper.getEntity(); if (entity != null) { entityClass = getEntityClass(entity); } } Assert.notNull(entityClass, "error: can not get entityClass from wrapper"); return entityClass; } /** * 从entity中尝试获取实体类型 * * @param entity 实体 * @param 实体类型 * @return 实体类型 */ @SuppressWarnings("unchecked") protected static Class getEntityClass(T entity) { return (Class) entity.getClass(); } /** * 获取表信息,获取不到报错提示 * * @param entityClass 实体类 * @param 实体类型 * @return 对应表信息 */ protected static TableInfo getTableInfo(Class entityClass) { return Optional.ofNullable(TableInfoHelper.getTableInfo(entityClass)).orElseThrow(() -> ExceptionUtils.mpe("error: can not find TableInfo from Class: \"%s\".", entityClass.getName())); } }