/* * Copyright (c) 2011-2022, 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.enums.SqlMethod; 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.*; 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.service.IService; import org.apache.ibatis.binding.MapperMethod; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; /** * 以静态方式调用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; } @SuppressWarnings("unchecked") Class entityClass = (Class) entity.getClass(); Integer result = SqlHelper.execute(entityClass, baseMapper -> baseMapper.insert(entity)); return SqlHelper.retBool(result); } /** * 插入(批量) * * @param entityList 实体对象集合 */ public static boolean saveBatch(Collection entityList) { return saveBatch(entityList, IService.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); Class mapperClass = ClassUtils.toClassConfident(getTableInfo(entityClass).getCurrentNamespace()); String sqlStatement = SqlHelper.getSqlStatement(mapperClass, SqlMethod.INSERT_ONE); return SqlHelper.executeBatch(entityClass, LogFactory.getLog(Db.class), entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity)); } /** * 批量修改插入 * * @param entityList 实体对象集合 */ public static boolean saveOrUpdateBatch(Collection entityList) { return saveOrUpdateBatch(entityList, IService.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); TableInfo tableInfo = getTableInfo(entityClass); Class mapperClass = ClassUtils.toClassConfident(tableInfo.getCurrentNamespace()); String keyProperty = tableInfo.getKeyProperty(); Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for primary key from entity!"); return SqlHelper.saveOrUpdateBatch(entityClass, mapperClass, LogFactory.getLog(Db.class), entityList, batchSize, (sqlSession, entity) -> { Object idVal = tableInfo.getPropertyValue(entity, keyProperty); return StringUtils.checkValNull(idVal) || CollectionUtils.isEmpty(sqlSession.selectList(SqlHelper.getSqlStatement(mapperClass, SqlMethod.SELECT_BY_ID), entity)); }, (sqlSession, entity) -> { MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); sqlSession.update(SqlHelper.getSqlStatement(mapperClass, SqlMethod.UPDATE_BY_ID), param); }); } /** * 根据 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; } @SuppressWarnings("unchecked") Class entityClass = (Class) entity.getClass(); return SqlHelper.execute(entityClass, 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; } @SuppressWarnings("unchecked") Class entityClass = (Class) entity.getClass(); return SqlHelper.execute(entityClass, 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, IService.DEFAULT_BATCH_SIZE); } /** * 根据ID 批量更新 * * @param entityList 实体对象集合 * @param batchSize 更新批次数量 */ public static boolean updateBatchById(Collection entityList, int batchSize) { Class entityClass = getEntityClass(entityList); TableInfo tableInfo = getTableInfo(entityClass); String sqlStatement = SqlHelper.getSqlStatement(ClassUtils.toClassConfident(tableInfo.getCurrentNamespace()), SqlMethod.UPDATE_BY_ID); return SqlHelper.executeBatch(entityClass, LogFactory.getLog(Db.class), entityList, batchSize, (sqlSession, entity) -> { MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); sqlSession.update(sqlStatement, param); }); } /** * 删除(根据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; } @SuppressWarnings("unchecked") Class entityClass = (Class) entity.getClass(); TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!"); String keyProperty = tableInfo.getKeyProperty(); Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!"); Object idVal = tableInfo.getPropertyValue(entity, tableInfo.getKeyProperty()); return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal, entityClass)) ? save(entity) : updateById(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); } /** * 根据 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))); } /** * 查询总记录数 * * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static long count(Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectCount(null)); } /** * 根据 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) { Class entityClass = getEntityClass(queryWrapper); return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectList(queryWrapper)); } /** * 查询所有 * * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static List list(Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectList(null)); } /** * 查询列表 * * @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)); } /** * 查询所有列表 * * @param entityClass 实体类 * @see Wrappers#emptyWrapper() */ public static List> listMaps(Class entityClass) { return SqlHelper.execute(entityClass, baseMapper -> baseMapper.selectMaps(null)); } /** * 查询全部记录 * * @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); } /** * 链式查询 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); } /** * 链式更改 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 实体类型 */ @SuppressWarnings("unchecked") protected static Class getEntityClass(Collection entityList) { Class entityClass = null; for (T entity : entityList) { if (entity != null && entity.getClass() != null) { entityClass = (Class) entity.getClass(); break; } } Assert.notNull(entityClass, "error: can not get entityClass from entityList"); return entityClass; } /** * 从wrapper中尝试获取实体类型 * * @param queryWrapper 条件构造器 * @param 实体类型 * @return 实体类型 */ @SuppressWarnings("unchecked") protected static Class getEntityClass(AbstractWrapper queryWrapper) { Class entityClass = queryWrapper.getEntityClass(); if (entityClass == null) { T entity = queryWrapper.getEntity(); if (entity != null) { entityClass = (Class) entity.getClass(); } } Assert.notNull(entityClass, "error: can not get entityClass from wrapper"); return entityClass; } /** * 获取表信息,获取不到报错提示 * * @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())); } }