| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- 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 <T>
- */
- public interface PlusBaseMapperX<T> extends BaseMapperX<T> {
- 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<T, ?> column) {
- return columnToString(column, true);
- }
- default String columnToString(SFunction<T, ?> column, boolean onlyColumn) {
- ColumnCache cache = getColumnCache(column);
- return onlyColumn ? cache.getColumn() : cache.getColumnSelect();
- }
- /**
- * 获取 SerializedLambda 对应的列信息,从 lambda 表达式中推测实体类
- * <p>
- * 如果获取不到列信息,那么本次条件组装将会失败
- *
- * @return 列
- * @throws com.baomidou.mybatisplus.core.exceptions.MybatisPlusException 获取不到列信息时抛出异常
- */
- default ColumnCache getColumnCache(SFunction<T, ?> column) {
- LambdaMeta meta = LambdaUtils.extract(column);
- String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName());
- Class<?> instantiatedClass = meta.getInstantiatedClass();
- Map<String, ColumnCache> columnMap = tryInitCache(instantiatedClass);
- return getColumnCache(fieldName, instantiatedClass, columnMap);
- }
- default ColumnCache getColumnCache(String fieldName, Class<?> lambdaClass, Map<String, ColumnCache> 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<T> getEntityClass() {
- return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), PlusBaseMapperX.class, 0);
- }
- @SuppressWarnings("unchecked")
- default Class<T> currentMapperClass() {
- return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), PlusBaseMapperX.class, 0);
- }
- default Map<String, ColumnCache> tryInitCache(Class<?> lambdaClass) {
- final Class<T> entityClass = getEntityClass();
- if (entityClass != null) {
- lambdaClass = entityClass;
- }
- Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(lambdaClass);
- return columnMap;
- }
- /**
- * 根据 entity 条件,删除记录
- *
- * @param queryWrapper 实体包装类
- * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
- */
- default boolean delete(T t) {
- Wrapper<T> 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<T, ?> column, Object value) {
- UpdateWrapper<T> 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<String, Object> columns) {
- UpdateWrapper<T> 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<T, ?>... columns) {
- // 这里是反射,通过反射来得到
- try {
- Map<String, Object> columnVal = new HashMap<>();
- for (SFunction<T, ?> 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<T, ?> column) {
- LambdaMeta meta = LambdaUtils.extract(column);
- String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName());
- return fieldName;
- }
- default boolean update(T entity, SFunction<T, ?> column, Collection<?> coll) {
- UpdateWrapper<T> 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<T> 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<T> updateWrapper = new UpdateWrapper<>();
- updateWrapper.in(conditions, values);
- return SqlHelper.retBool(update(entity, updateWrapper));
- }
- /**
- * 根据 Wrapper,查询一条记录 <br/>
- * <p>
- * 结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
- * </p>
- *
- * @param queryWrapper 实体对象封装操作类
- * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
- */
- default T selectOne(T t) {
- Wrapper<T> 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<T> queryWrapper = QueryWrapperUtil.convertQuery(t);
- return SqlHelper.retCount(selectCount(queryWrapper));
- }
- /**
- * 查询列表
- *
- * @param queryWrapper 实体对象封装操作类
- * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
- */
- default List<T> selectList(T t) {
- Wrapper<T> queryWrapper = QueryWrapperUtil.convertQuery(t);
- return selectList(queryWrapper);
- }
- /**
- * 查询对象
- *
- * @param queryWrapper 实体对象封装操作类
- * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
- */
- default Map<String, Object> getMap(T t) {
- Wrapper<T> queryWrapper = QueryWrapperUtil.convertQuery(t);
- List<Map<String, Object>> 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<Map<String, Object>> selectMaps(T t) {
- Wrapper<T> queryWrapper = QueryWrapperUtil.convertQuery(t);
- return selectMaps(queryWrapper);
- }
- /**
- * 根据 Wrapper 条件,查询全部记录
- *
- * @param queryWrapper 实体对象封装操作类
- * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
- */
- default List<Object> listObjs(T t) {
- Wrapper<T> queryWrapper = QueryWrapperUtil.convertQuery(t);
- return selectObjs(queryWrapper, Function.identity());
- }
- /**
- * 根据 Wrapper 条件,查询全部记录
- *
- * @param queryWrapper 实体对象封装操作类
- * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
- * @param mapper 转换函数
- */
- default <V> List<V> selectObjs(Wrapper<T> queryWrapper, Function<? super Object, V> 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 extends IPage<T>> E selectPage(E page, T t, QueryMap... map) {
- Wrapper<T> 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 extends IPage<T>> E selectPage(E page, T t) {
- Wrapper<T> 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<T> wrapper, Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinCount(wrapper);
- }
- /**
- * 连表查询返回一条记录
- *
- * @param wrapper joinWrapper
- * @param clazz resultType
- */
- default <DTO> DTO selectJoinOne(Class<DTO> clazz, MPJLambdaWrapper<T> wrapper, Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinOne(clazz, wrapper);
- }
- /**
- * 连表查询返回Map
- *
- * @param wrapper joinWrapper
- */
- default Map<String, Object> selectJoinMap(MPJLambdaWrapper<T> wrapper, Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinMap(wrapper);
- }
- /**
- * 连表查询返回记录集合
- *
- * @param wrapper joinWrapper
- * @param clazz resultType
- */
- default <DTO> List<DTO> selectJoinList(Class<DTO> clazz, MPJLambdaWrapper<T> wrapper, Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinList(clazz, wrapper);
- }
- /**
- * 连表查询返回Map集合
- *
- * @param wrapper joinWrapper
- */
- default List<Map<String, Object>> selectJoinMaps(MPJLambdaWrapper<T> wrapper, Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinMaps(wrapper);
- }
- /**
- * 连表查询返回记录集合并分页
- *
- * @param wrapper joinWrapper
- * @param clazz resultType
- * @param <DTO> 分页返回对象
- */
- default <DTO, P extends IPage<DTO>> P selectJoinPage(P page, Class<DTO> clazz, MPJLambdaWrapper<T> wrapper,
- Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinPage(page, clazz, wrapper);
- }
- /**
- * 连表查询返回Map集合并分页
- *
- * @param wrapper joinWrapper
- */
- default <P extends IPage<Map<String, Object>>> P selectJoinMapsPage(P page, MPJLambdaWrapper<T> wrapper,
- Object... param) {
- wrapper = QueryLambdaUtil.convertQuery(wrapper, param);
- return this.selectJoinMapsPage(page, wrapper);
- }
- default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
- return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
- }
- default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
- return selectPage(pageParam, null, queryWrapper);
- }
- default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields,
- @Param("ew") Wrapper<T> queryWrapper) {
- // 特殊:不分页,直接查询全部
- if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
- List<T> list = selectList(queryWrapper);
- return new PageResult<>(list, (long) list.size());
- }
- // MyBatis Plus 查询
- IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
- selectPage(mpPage, queryWrapper);
- // 转换返回
- return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
- }
- // ========== 统计方法(基于 Lambda) ==========
- /**
- * 获取字段最大值(Lambda)
- */
- default Object selectMax(SFunction<T, ?> column) {
- String columnName = columnToString(column);
- return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>().select("MAX(" + columnName + ")")).stream().findFirst().orElse(null);
- }
- /**
- * 获取字段最小值(Lambda)
- */
- default Object selectMin(SFunction<T, ?> column) {
- String columnName = columnToString(column);
- return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>().select("MIN(" + columnName + ")")).stream().findFirst().orElse(null);
- }
- /**
- * 获取字段总和(Lambda)
- */
- default Object selectSum(SFunction<T, ?> column) {
- String columnName = columnToString(column);
- return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>().select("SUM(" + columnName + ")")).stream().findFirst().orElse(null);
- }
- /**
- * 获取字段平均值(Lambda)
- */
- default Object selectAvg(SFunction<T, ?> column) {
- String columnName = columnToString(column);
- return selectObjs(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>().select("AVG(" + columnName + ")")).stream().findFirst().orElse(null);
- }
- default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
- // 特殊:不分页,直接查询全部
- if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) {
- List<D> list = selectJoinList(clazz, lambdaWrapper);
- return new PageResult<>(list, (long) list.size());
- }
- // MyBatis Plus Join 查询
- IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
- mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
- // 转换返回
- return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
- }
- default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass,
- MPJBaseJoin<T> joinQueryWrapper) {
- IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
- selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
- // 转换返回
- return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
- }
- }
|