/* * Copyright (c) 2011-2020, 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 *

* https://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.service; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.conditions.query.ChainQuery; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.ChainUpdate; 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 com.baomidou.mybatisplus.extension.toolkit.ChainWrappers; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import org.springframework.transaction.annotation.Transactional; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; /** * 顶级 Service * * @author hubin * @since 2018-06-23 */ public interface IService { /** * 默认批次提交数量 */ int DEFAULT_BATCH_SIZE = 1000; /** * 插入一条记录(选择字段,策略插入) * * @param entity 实体对象 */ default boolean save(T entity) { return SqlHelper.retBool(getBaseMapper().insert(entity)); } /** * 插入(批量) * * @param entityList 实体对象集合 */ @Transactional(rollbackFor = Exception.class) default boolean saveBatch(Collection entityList) { return saveBatch(entityList, DEFAULT_BATCH_SIZE); } /** * 插入(批量) * * @param entityList 实体对象集合 * @param batchSize 插入批次数量 */ boolean saveBatch(Collection entityList, int batchSize); /** * 批量修改插入 * * @param entityList 实体对象集合 */ @Transactional(rollbackFor = Exception.class) default boolean saveOrUpdateBatch(Collection entityList) { return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE); } /** * 批量修改插入 * * @param entityList 实体对象集合 * @param batchSize 每次的数量 */ boolean saveOrUpdateBatch(Collection entityList, int batchSize); /** * 根据 ID 删除 * * @param id 主键ID */ default boolean removeById(Serializable id) { return SqlHelper.retBool(getBaseMapper().deleteById(id)); } /** * 根据 columnMap 条件,删除记录 * * @param columnMap 表字段 map 对象 */ default boolean removeByMap(Map columnMap) { Assert.notEmpty(columnMap, "error: columnMap must not be empty"); return SqlHelper.retBool(getBaseMapper().deleteByMap(columnMap)); } /** * 根据 entity 条件,删除记录 * * @param queryWrapper 实体包装类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default boolean remove(Wrapper queryWrapper) { return SqlHelper.retBool(getBaseMapper().delete(queryWrapper)); } /** * 删除(根据ID 批量删除) * * @param idList 主键ID列表 */ default boolean removeByIds(Collection idList) { if (CollectionUtils.isEmpty(idList)) { return false; } return SqlHelper.retBool(getBaseMapper().deleteBatchIds(idList)); } /** * 根据 ID 选择修改 * * @param entity 实体对象 */ default boolean updateById(T entity) { return SqlHelper.retBool(getBaseMapper().updateById(entity)); } /** * 根据 UpdateWrapper 条件,更新记录 需要设置sqlset * * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} */ default boolean update(Wrapper updateWrapper) { return update(null, updateWrapper); } /** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} */ default boolean update(T entity, Wrapper updateWrapper) { return SqlHelper.retBool(getBaseMapper().update(entity, updateWrapper)); } /** * 根据ID 批量更新 * * @param entityList 实体对象集合 */ @Transactional(rollbackFor = Exception.class) default boolean updateBatchById(Collection entityList) { return updateBatchById(entityList, DEFAULT_BATCH_SIZE); } /** * 根据ID 批量更新 * * @param entityList 实体对象集合 * @param batchSize 更新批次数量 */ boolean updateBatchById(Collection entityList, int batchSize); /** * TableId 注解存在更新记录,否插入一条记录 * * @param entity 实体对象 */ boolean saveOrUpdate(T entity); /** * 根据 ID 查询 * * @param id 主键ID */ default T getById(Serializable id) { return getBaseMapper().selectById(id); } /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表 */ default List listByIds(Collection idList) { return getBaseMapper().selectBatchIds(idList); } /** * 查询(根据 columnMap 条件) * * @param columnMap 表字段 map 对象 */ default List listByMap(Map columnMap) { return getBaseMapper().selectByMap(columnMap); } /** * 根据 Wrapper,查询一条记录
*

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

* * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default T getOne(Wrapper queryWrapper) { return getOne(queryWrapper, true); } /** * 根据 Wrapper,查询一条记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param throwEx 有多个 result 是否抛出异常 */ T getOne(Wrapper queryWrapper, boolean throwEx); /** * 根据 Wrapper,查询一条记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ Map getMap(Wrapper queryWrapper); /** * 根据 Wrapper,查询一条记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param mapper 转换函数 */ V getObj(Wrapper queryWrapper, Function mapper); /** * 查询总记录数 * * @see Wrappers#emptyWrapper() */ default int count() { return count(Wrappers.emptyWrapper()); } /** * 根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default int count(Wrapper queryWrapper) { return SqlHelper.retCount(getBaseMapper().selectCount(queryWrapper)); } /** * 查询列表 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List list(Wrapper queryWrapper) { return getBaseMapper().selectList(queryWrapper); } /** * 查询所有 * * @see Wrappers#emptyWrapper() */ default List list() { return list(Wrappers.emptyWrapper()); } /** * 翻页查询 * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default > E page(E page, Wrapper queryWrapper) { return getBaseMapper().selectPage(page, queryWrapper); } /** * 无条件翻页查询 * * @param page 翻页对象 * @see Wrappers#emptyWrapper() */ default > E page(E page) { return page(page, Wrappers.emptyWrapper()); } /** * 查询列表 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List> listMaps(Wrapper queryWrapper) { return getBaseMapper().selectMaps(queryWrapper); } /** * 查询所有列表 * * @see Wrappers#emptyWrapper() */ default List> listMaps() { return listMaps(Wrappers.emptyWrapper()); } /** * 查询全部记录 */ default List listObjs() { return listObjs(Function.identity()); } /** * 查询全部记录 * * @param mapper 转换函数 */ default List listObjs(Function mapper) { return listObjs(Wrappers.emptyWrapper(), mapper); } /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List listObjs(Wrapper queryWrapper) { return listObjs(queryWrapper, Function.identity()); } /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param mapper 转换函数 */ default List listObjs(Wrapper queryWrapper, Function mapper) { return getBaseMapper().selectObjs(queryWrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList()); } /** * 翻页查询 * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default >> E pageMaps(E page, Wrapper queryWrapper) { return getBaseMapper().selectMapsPage(page, queryWrapper); } /** * 无条件翻页查询 * * @param page 翻页对象 * @see Wrappers#emptyWrapper() */ default >> E pageMaps(E page) { return pageMaps(page, Wrappers.emptyWrapper()); } /** * 获取对应 entity 的 BaseMapper * * @return BaseMapper */ BaseMapper getBaseMapper(); /** * 获取 entity 的 class * * @return {@link Class} */ Class getEntityClass(); /** * 以下的方法使用介绍: * * 一. 名称介绍 * 1. 方法名带有 query 的为对数据的查询操作, 方法名带有 update 的为对数据的修改操作 * 2. 方法名带有 lambda 的为内部方法入参 column 支持函数式的 * 二. 支持介绍 * * 1. 方法名带有 query 的支持以 {@link ChainQuery} 内部的方法名结尾进行数据查询操作 * 2. 方法名带有 update 的支持以 {@link ChainUpdate} 内部的方法名为结尾进行数据修改操作 * * 三. 使用示例,只用不带 lambda 的方法各展示一个例子,其他类推 * 1. 根据条件获取一条数据: `query().eq("column", value).one()` * 2. 根据条件删除一条数据: `update().eq("column", value).remove()` * */ /** * 链式查询 普通 * * @return QueryWrapper 的包装类 */ default QueryChainWrapper query() { return ChainWrappers.queryChain(getBaseMapper()); } /** * 链式查询 lambda 式 *

注意:不支持 Kotlin

* * @return LambdaQueryWrapper 的包装类 */ default LambdaQueryChainWrapper lambdaQuery() { return ChainWrappers.lambdaQueryChain(getBaseMapper()); } /** * 链式查询 lambda 式 * kotlin 使用 * * @return KtQueryWrapper 的包装类 */ default KtQueryChainWrapper ktQuery() { return ChainWrappers.ktQueryChain(getBaseMapper(), getEntityClass()); } /** * 链式查询 lambda 式 * kotlin 使用 * * @return KtQueryWrapper 的包装类 */ default KtUpdateChainWrapper ktUpdate() { return ChainWrappers.ktUpdateChain(getBaseMapper(), getEntityClass()); } /** * 链式更改 普通 * * @return UpdateWrapper 的包装类 */ default UpdateChainWrapper update() { return ChainWrappers.updateChain(getBaseMapper()); } /** * 链式更改 lambda 式 *

注意:不支持 Kotlin

* * @return LambdaUpdateWrapper 的包装类 */ default LambdaUpdateChainWrapper lambdaUpdate() { return ChainWrappers.lambdaUpdateChain(getBaseMapper()); } /** *

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

* * @param entity 实体对象 */ default boolean saveOrUpdate(T entity, Wrapper updateWrapper) { return update(entity, updateWrapper) || saveOrUpdate(entity); } }