package mybatisex.core.mapper; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.reflection.property.PropertyNamer; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.LambdaUtils; import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.github.yulichang.interfaces.MPJBaseJoin; import com.github.yulichang.wrapper.MPJLambdaWrapper; import mybatisex.common.pojo.PageParam; import mybatisex.common.pojo.PageResult; import mybatisex.common.pojo.SortablePageParam; import mybatisex.common.pojo.SortingField; import mybatisex.core.util.MyBatisUtils; /** * 对实体类的操作 * * @param */ public interface PlusBaseMapperX extends BaseMapperX { static final Log logger = LogFactory.getLog(PlusBaseMapperX.class); /** * 博客地址:https://blog.csdn.net/qq_19266669/article/details/114369195 * 查看AbstractLambdaWrapper通过方法得到字段名称 * * @param column * @return */ default String columnToString(SFunction column) { return columnToString(column, true); } default String columnToString(SFunction column, boolean onlyColumn) { ColumnCache cache = getColumnCache(column); return onlyColumn ? cache.getColumn() : cache.getColumnSelect(); } /** * 获取 SerializedLambda 对应的列信息,从 lambda 表达式中推测实体类 *

* 如果获取不到列信息,那么本次条件组装将会失败 * * @return 列 * @throws com.baomidou.mybatisplus.core.exceptions.MybatisPlusException 获取不到列信息时抛出异常 */ default ColumnCache getColumnCache(SFunction column) { LambdaMeta meta = LambdaUtils.extract(column); String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName()); Class instantiatedClass = meta.getInstantiatedClass(); Map columnMap = tryInitCache(instantiatedClass); return getColumnCache(fieldName, instantiatedClass, columnMap); } default ColumnCache getColumnCache(String fieldName, Class lambdaClass, Map columnMap) { ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(fieldName)); Assert.notNull(columnCache, "can not find lambda cache for this property [%s] of entity [%s]", fieldName, lambdaClass.getName()); return columnCache; } @SuppressWarnings("unchecked") default Class getEntityClass() { return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), PlusBaseMapperX.class, 0); } @SuppressWarnings("unchecked") default Class currentMapperClass() { return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), PlusBaseMapperX.class, 0); } default Map tryInitCache(Class lambdaClass) { final Class entityClass = getEntityClass(); if (entityClass != null) { lambdaClass = entityClass; } Map columnMap = LambdaUtils.getColumnMap(lambdaClass); return columnMap; } /** * 根据 entity 条件,删除记录 * * @param queryWrapper 实体包装类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default boolean delete(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); return SqlHelper.retBool(delete(queryWrapper)); } /** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 * @param updateWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} * @throws SecurityException * @throws NoSuchFieldException */ default boolean update(T entity, SFunction column, Object value) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); String conditions = columnToString(column); var tableInfo = TableInfoHelper.getTableInfo(entity.getClass()); if (tableInfo != null) { String keyProperty = tableInfo.getKeyProperty(); Object keyVal = keyProperty != null ? tableInfo.getPropertyValue(entity, keyProperty) : null; if (keyVal != null) { updateWrapper.eq(tableInfo.getKeyColumn(), keyVal).set(conditions, value); return SqlHelper.retBool(update(entity, updateWrapper)); } } updateWrapper.eq(conditions, value); return SqlHelper.retBool(update(entity, updateWrapper)); } /** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 * @param updateWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} * @throws SecurityException * @throws NoSuchFieldException */ default boolean update(T entity, Map columns) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); var tableInfo = TableInfoHelper.getTableInfo(entity.getClass()); if (tableInfo != null) { String keyProperty = tableInfo.getKeyProperty(); Object keyVal = keyProperty != null ? tableInfo.getPropertyValue(entity, keyProperty) : null; if (keyVal != null) { updateWrapper.eq(tableInfo.getKeyColumn(), keyVal); columns.forEach(updateWrapper::set); return SqlHelper.retBool(update(entity, updateWrapper)); } } for (String key : columns.keySet()) { updateWrapper.eq(key, columns.get(key)); } return SqlHelper.retBool(update(entity, updateWrapper)); } /** * 将 * * @param entity * @param columns * @return */ @SuppressWarnings("unchecked") default boolean update(T entity, SFunction... columns) { // 这里是反射,通过反射来得到 try { Map columnVal = new HashMap<>(); for (SFunction column : columns) { String columnName = columnToString(column); String fieldName = getFieldName(column); Class clazz = entity.getClass(); PropertyDescriptor p = new PropertyDescriptor(fieldName, clazz); Method readMethod = p.getReadMethod(); // 得到跟新的值 Object value = readMethod.invoke(entity); // 把查询条件的值设置为null Method writeMethod = p.getWriteMethod(); // 将相等的值设置为控制 Object obj = null; writeMethod.invoke(entity, obj); columnVal.put(columnName, value); } return update(entity, columnVal); } catch (Exception e) { logger.error("update class" + entity.getClass() + " exception :" + e.getMessage()); return false; } } default String getFieldName(SFunction column) { LambdaMeta meta = LambdaUtils.extract(column); String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName()); return fieldName; } default boolean update(T entity, SFunction column, Collection coll) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); // 这里使用反射得到字段, String conditions = columnToString(column); updateWrapper.in(conditions, coll); return SqlHelper.retBool(update(entity, updateWrapper)); } default boolean update(T entity, String column, Object value) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); var tableInfo = TableInfoHelper.getTableInfo(entity.getClass()); if (tableInfo != null) { String keyProperty = tableInfo.getKeyProperty(); Object keyVal = keyProperty != null ? tableInfo.getPropertyValue(entity, keyProperty) : null; if (keyVal != null) { updateWrapper.eq(tableInfo.getKeyColumn(), keyVal).set(column, value); return SqlHelper.retBool(update(entity, updateWrapper)); } } updateWrapper.eq(column, value); return SqlHelper.retBool(update(entity, updateWrapper)); } default boolean update(T entity, String conditions, Object... values) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.in(conditions, values); return SqlHelper.retBool(update(entity, updateWrapper)); } /** * 根据 Wrapper,查询一条记录
*

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

* * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default T selectOne(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); return selectOne(queryWrapper, true); } /** * 根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default long selectCount(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); return SqlHelper.retCount(selectCount(queryWrapper)); } /** * 查询列表 * * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List selectList(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); return selectList(queryWrapper); } /** * 查询对象 * * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default Map getMap(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); List> selectMaps = selectMaps(queryWrapper); if (selectMaps != null && selectMaps.size() > 0) { return selectMaps.get(0); } return new HashMap<>(); } /** * 查询列表 * * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List> selectMaps(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); return selectMaps(queryWrapper); } /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List listObjs(T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); return selectObjs(queryWrapper, Function.identity()); } /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param mapper 转换函数 */ default List selectObjs(Wrapper queryWrapper, Function mapper) { return 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 selectPage(E page, T t, QueryMap... map) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t, map); try { return selectPage(page, queryWrapper); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 翻页查询 * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default > E selectPage(E page, T t) { Wrapper queryWrapper = QueryWrapperUtil.convertQuery(t); try { return selectPage(page, queryWrapper); } catch (Exception e) { e.printStackTrace(); } return null; } // select join /** * 查询对象 连表查询返回记录集合 * * @param wrapper joinWrapper * @param clazz resultType * @param objs 查询条件 */ /** * 根据 Wrapper 条件,查询总记录数 * * @param wrapper joinWrapper */ default Long selectJoinCount(MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinCount(wrapper); } /** * 连表查询返回一条记录 * * @param wrapper joinWrapper * @param clazz resultType */ default DTO selectJoinOne(Class clazz, MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinOne(clazz, wrapper); } /** * 连表查询返回Map * * @param wrapper joinWrapper */ default Map selectJoinMap(MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinMap(wrapper); } /** * 连表查询返回记录集合 * * @param wrapper joinWrapper * @param clazz resultType */ default List selectJoinList(Class clazz, MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinList(clazz, wrapper); } /** * 连表查询返回Map集合 * * @param wrapper joinWrapper */ default List> selectJoinMaps(MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinMaps(wrapper); } /** * 连表查询返回记录集合并分页 * * @param wrapper joinWrapper * @param clazz resultType * @param 分页返回对象 */ default > P selectJoinPage(P page, Class clazz, MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinPage(page, clazz, wrapper); } /** * 连表查询返回Map集合并分页 * * @param wrapper joinWrapper */ default

>> P selectJoinMapsPage(P page, MPJLambdaWrapper wrapper, Object... param) { wrapper = QueryLambdaUtil.convertQuery(wrapper, param); return this.selectJoinMapsPage(page, wrapper); } default PageResult selectPage(SortablePageParam pageParam, @Param("ew") Wrapper queryWrapper) { return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper); } default PageResult selectPage(PageParam pageParam, @Param("ew") Wrapper queryWrapper) { return selectPage(pageParam, null, queryWrapper); } default PageResult selectPage(PageParam pageParam, Collection sortingFields, @Param("ew") Wrapper queryWrapper) { // 特殊:不分页,直接查询全部 if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) { List list = selectList(queryWrapper); return new PageResult<>(list, (long) list.size()); } // MyBatis Plus 查询 IPage mpPage = MyBatisUtils.buildPage(pageParam, sortingFields); selectPage(mpPage, queryWrapper); // 转换返回 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); } // ========== 统计方法(基于 Lambda) ========== /** * 获取字段最大值(Lambda) */ default Object selectMax(SFunction column) { String columnName = columnToString(column); return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().select("MAX(" + columnName + ")")).stream().findFirst().orElse(null); } /** * 获取字段最小值(Lambda) */ default Object selectMin(SFunction column) { String columnName = columnToString(column); return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().select("MIN(" + columnName + ")")).stream().findFirst().orElse(null); } /** * 获取字段总和(Lambda) */ default Object selectSum(SFunction column) { String columnName = columnToString(column); return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().select("SUM(" + columnName + ")")).stream().findFirst().orElse(null); } /** * 获取字段平均值(Lambda) */ default Object selectAvg(SFunction column) { String columnName = columnToString(column); return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().select("AVG(" + columnName + ")")).stream().findFirst().orElse(null); } default PageResult selectJoinPage(PageParam pageParam, Class clazz, MPJLambdaWrapper lambdaWrapper) { // 特殊:不分页,直接查询全部 if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) { List list = selectJoinList(clazz, lambdaWrapper); return new PageResult<>(list, (long) list.size()); } // MyBatis Plus Join 查询 IPage mpPage = MyBatisUtils.buildPage(pageParam); mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper); // 转换返回 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); } default PageResult selectJoinPage(PageParam pageParam, Class resultTypeClass, MPJBaseJoin joinQueryWrapper) { IPage mpPage = MyBatisUtils.buildPage(pageParam); selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper); // 转换返回 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); } }