package com.glxp.api.dao; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.enums.SqlMethod; import com.baomidou.mybatisplus.core.mapper.BaseMapper; 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.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.glxp.api.util.BeanCopyUtils; 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.Collection; import java.util.List; import java.util.Map; import java.util.Objects; /** * 自定义 Mapper 接口, 实现 自定义扩展 * * @param mapper 泛型 * @param table 泛型 * @param vo 泛型 * @author Lion Li * @since 2021-05-13 */ @SuppressWarnings("unchecked") public interface BaseMapperPlus extends BaseMapper { Log log = LogFactory.getLog(BaseMapperPlus.class); int DEFAULT_BATCH_SIZE = 1000; default Class currentVoClass() { return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 2); } default Class currentModelClass() { return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1); } default Class currentMapperClass() { return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0); } default List selectList() { return this.selectList(new QueryWrapper<>()); } /** * 批量插入 */ default boolean insertBatch(Collection entityList) { return insertBatch(entityList, DEFAULT_BATCH_SIZE); } /** * 批量更新 */ default boolean updateBatchById(Collection entityList) { return updateBatchById(entityList, DEFAULT_BATCH_SIZE); } /** * 批量插入或更新 */ default boolean insertOrUpdateBatch(Collection entityList) { return insertOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE); } /** * 批量插入(包含限制条数) */ default boolean insertBatch(Collection entityList, int batchSize) { String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.INSERT_ONE); return SqlHelper.executeBatch(this.currentModelClass(), log, entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity)); } /** * 批量更新(包含限制条数) */ default boolean updateBatchById(Collection entityList, int batchSize) { String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.UPDATE_BY_ID); return SqlHelper.executeBatch(this.currentModelClass(), log, entityList, batchSize, (sqlSession, entity) -> { MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); sqlSession.update(sqlStatement, param); }); } /** * 批量插入或更新(包含限制条数) */ default boolean insertOrUpdateBatch(Collection entityList, int batchSize) { TableInfo tableInfo = TableInfoHelper.getTableInfo(this.currentModelClass()); 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!"); return SqlHelper.saveOrUpdateBatch(this.currentModelClass(), this.currentMapperClass(), log, entityList, batchSize, (sqlSession, entity) -> { Object idVal = tableInfo.getPropertyValue(entity, keyProperty); String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.SELECT_BY_ID); return StringUtils.checkValNull(idVal) || CollectionUtils.isEmpty(sqlSession.selectList(sqlStatement, entity)); }, (sqlSession, entity) -> { MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.UPDATE_BY_ID); sqlSession.update(sqlStatement, param); }); } /** * 插入或更新(包含限制条数) */ default boolean insertOrUpdate(T entity) { if (null != entity) { TableInfo tableInfo = TableInfoHelper.getTableInfo(this.currentModelClass()); 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(selectById((Serializable) idVal)) ? insert(entity) > 0 : updateById(entity) > 0; } return false; } default V selectVoById(Serializable id) { return selectVoById(id, this.currentVoClass()); } /** * 根据 ID 查询 */ default C selectVoById(Serializable id, Class voClass) { T obj = this.selectById(id); if (ObjectUtil.isNull(obj)) { return null; } return BeanCopyUtils.copy(obj, voClass); } default List selectVoBatchIds(Collection idList) { return selectVoBatchIds(idList, this.currentVoClass()); } /** * 查询(根据ID 批量查询) */ default List selectVoBatchIds(Collection idList, Class voClass) { List list = this.selectBatchIds(idList); if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } return BeanCopyUtils.copyList(list, voClass); } default List selectVoByMap(Map map) { return selectVoByMap(map, this.currentVoClass()); } /** * 查询(根据 columnMap 条件) */ default List selectVoByMap(Map map, Class voClass) { List list = this.selectByMap(map); if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } return BeanCopyUtils.copyList(list, voClass); } default V selectVoOne(Wrapper wrapper) { return selectVoOne(wrapper, this.currentVoClass()); } /** * 根据 entity 条件,查询一条记录 */ default C selectVoOne(Wrapper wrapper, Class voClass) { T obj = this.selectOne(wrapper); if (ObjectUtil.isNull(obj)) { return null; } return BeanCopyUtils.copy(obj, voClass); } default List selectVoList(Wrapper wrapper) { return selectVoList(wrapper, this.currentVoClass()); } /** * 根据 entity 条件,查询全部记录 */ default List selectVoList(Wrapper wrapper, Class voClass) { List list = this.selectList(wrapper); if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } return BeanCopyUtils.copyList(list, voClass); } default

> P selectVoPage(IPage page, Wrapper wrapper) { return selectVoPage(page, wrapper, this.currentVoClass()); } /** * 分页查询VO */ default > P selectVoPage(IPage page, Wrapper wrapper, Class voClass) { IPage pageData = this.selectPage(page, wrapper); IPage voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal()); if (CollUtil.isEmpty(pageData.getRecords())) { return (P) voPage; } voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass)); return (P) voPage; } }