001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016
017package com.mybatisflex.core.query;
018
019import com.mybatisflex.core.field.FieldQuery;
020import com.mybatisflex.core.field.FieldQueryManager;
021import com.mybatisflex.core.field.QueryBuilder;
022import com.mybatisflex.core.paginate.Page;
023import com.mybatisflex.core.util.FieldWrapper;
024import com.mybatisflex.core.util.LambdaGetter;
025import com.mybatisflex.core.util.LambdaUtil;
026
027import java.util.Collections;
028import java.util.HashMap;
029import java.util.List;
030import java.util.Map;
031
032/**
033 * 使用 {@code Fields Query} 的方式进行关联查询。
034 *
035 * @author 王帅
036 * @since 2023-08-08
037 */
038public class FieldsBuilder<T> extends AbstractQueryBuilder<T> {
039
040    protected final Map<String, FieldQuery> fieldQueryMap;
041
042    public FieldsBuilder(MapperQueryChain<T> delegate) {
043        super(delegate);
044        this.fieldQueryMap = new HashMap<>();
045    }
046
047    /**
048     * 设置属性对应的 {@code QueryWrapper} 查询。
049     *
050     * @param field   属性
051     * @param builder {@code QueryWrapper} 构建
052     * @param <F>     属性类型
053     * @return 属性查询构建
054     */
055    public <F> FieldsBuilder<T> fieldMapping(LambdaGetter<F> field, QueryBuilder<F> builder) {
056        return fieldMapping(field, false, builder);
057    }
058
059    /**
060     * 设置属性对应的 {@code QueryWrapper} 查询。
061     *
062     * @param field   属性
063     * @param prevent 阻止对嵌套类属性的查询
064     * @param builder {@code QueryWrapper} 构建
065     * @param <F>     属性类型
066     * @return 属性查询构建
067     */
068    public <F> FieldsBuilder<T> fieldMapping(LambdaGetter<F> field, boolean prevent, QueryBuilder<F> builder) {
069        String fieldName = LambdaUtil.getFieldName(field);
070        Class<?> entityClass = LambdaUtil.getImplClass(field);
071        FieldQuery fieldQuery = new FieldQuery();
072        fieldQuery.setPrevent(prevent);
073        fieldQuery.setFieldName(fieldName);
074        fieldQuery.setQueryBuilder(builder);
075        fieldQuery.setEntityClass(entityClass);
076        fieldQuery.setFieldWrapper(FieldWrapper.of(entityClass, fieldName));
077        this.fieldQueryMap.put(entityClass.getName() + '#' + fieldName, fieldQuery);
078        return this;
079    }
080
081    /**
082     * {@inheritDoc}
083     */
084    @Override
085    public T one() {
086        List<T> entities = Collections.singletonList(baseMapper().selectOneByQuery(queryWrapper()));
087        FieldQueryManager.queryFields(baseMapper(), entities, fieldQueryMap);
088        return entities.get(0);
089    }
090
091    /**
092     * {@inheritDoc}
093     */
094    @Override
095    public <R> R oneAs(Class<R> asType) {
096        List<R> entities = Collections.singletonList(baseMapper().selectOneByQueryAs(queryWrapper(), asType));
097        FieldQueryManager.queryFields(baseMapper(), entities, fieldQueryMap);
098        return entities.get(0);
099    }
100
101    /**
102     * {@inheritDoc}
103     */
104    @Override
105    public List<T> list() {
106        List<T> entities = baseMapper().selectListByQuery(queryWrapper());
107        FieldQueryManager.queryFields(baseMapper(), entities, fieldQueryMap);
108        return entities;
109    }
110
111    /**
112     * {@inheritDoc}
113     */
114    @Override
115    public <R> List<R> listAs(Class<R> asType) {
116        List<R> entities = baseMapper().selectListByQueryAs(queryWrapper(), asType);
117        FieldQueryManager.queryFields(baseMapper(), entities, fieldQueryMap);
118        return entities;
119    }
120
121    /**
122     * {@inheritDoc}
123     */
124    @Override
125    public Page<T> page(Page<T> page) {
126        baseMapper().paginate(page, queryWrapper());
127        FieldQueryManager.queryFields(baseMapper(), page.getRecords(), fieldQueryMap);
128        return page;
129    }
130
131    /**
132     * {@inheritDoc}
133     */
134    @Override
135    public <R> Page<R> pageAs(Page<R> page, Class<R> asType) {
136        baseMapper().paginateAs(page, queryWrapper(), asType);
137        FieldQueryManager.queryFields(baseMapper(), page.getRecords(), fieldQueryMap);
138        return page;
139    }
140
141}