org.mybatis.dynamic.sql.select.SelectDSL Maven / Gradle / Ivy
/**
* Copyright 2016-2019 the original author or authors.
*
* 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
*
* http://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 org.mybatis.dynamic.sql.select;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.mybatis.dynamic.sql.BasicColumn;
import org.mybatis.dynamic.sql.SortSpecification;
import org.mybatis.dynamic.sql.select.QueryExpressionDSL.FromGatherer;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.util.Buildable;
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils;
/**
* Implements a SQL DSL for building select statements.
*
* @author Jeff Butler
*
* @param the type of model produced by this builder, typically SelectModel
*/
public class SelectDSL implements Buildable {
private Function adapterFunction;
private List> queryExpressions = new ArrayList<>();
private OrderByModel orderByModel;
private Long limit;
private Long offset;
private Long fetchFirstRows;
private SelectDSL(Function adapterFunction) {
this.adapterFunction = Objects.requireNonNull(adapterFunction);
}
public static QueryExpressionDSL.FromGatherer select(BasicColumn...selectList) {
return select(Arrays.asList(selectList));
}
public static QueryExpressionDSL.FromGatherer select(Collection selectList) {
return select(Function.identity(), selectList);
}
public static QueryExpressionDSL.FromGatherer select(Function adapterFunction,
BasicColumn...selectList) {
return select(adapterFunction, Arrays.asList(selectList));
}
public static QueryExpressionDSL.FromGatherer select(Function adapterFunction,
Collection selectList) {
return new FromGatherer.Builder()
.withSelectList(selectList)
.withSelectDSL(new SelectDSL<>(adapterFunction))
.build();
}
public static QueryExpressionDSL.FromGatherer selectDistinct(BasicColumn...selectList) {
return selectDistinct(Arrays.asList(selectList));
}
public static QueryExpressionDSL.FromGatherer selectDistinct(Collection selectList) {
return selectDistinct(Function.identity(), selectList);
}
public static QueryExpressionDSL.FromGatherer selectDistinct(Function adapterFunction,
BasicColumn...selectList) {
return selectDistinct(adapterFunction, Arrays.asList(selectList));
}
public static QueryExpressionDSL.FromGatherer selectDistinct(Function adapterFunction,
Collection selectList) {
return new FromGatherer.Builder()
.withSelectList(selectList)
.withSelectDSL(new SelectDSL<>(adapterFunction))
.isDistinct()
.build();
}
/**
* Select records by executing a MyBatis3 Mapper.
*
* @deprecated in favor of various select methods in {@link MyBatis3Utils}.
* This method will be removed without direct replacement in a future version
* @param the return type from a MyBatis mapper - typically a List or a single record
* @param mapperMethod MyBatis3 mapper method that performs the select
* @param selectList the column list to select
* @return the partially created query
*/
@Deprecated
public static QueryExpressionDSL.FromGatherer> selectWithMapper(
Function mapperMethod, BasicColumn...selectList) {
return select(selectModel -> MyBatis3SelectModelAdapter.of(selectModel, mapperMethod), selectList);
}
/**
* Select records by executing a MyBatis3 Mapper.
*
* @deprecated in favor of various select methods in {@link MyBatis3Utils}.
* This method will be removed without direct replacement in a future version
* @param the return type from a MyBatis mapper - typically a List or a single record
* @param mapperMethod MyBatis3 mapper method that performs the select
* @param selectList the column list to select
* @return the partially created query
*/
@Deprecated
public static QueryExpressionDSL.FromGatherer> selectDistinctWithMapper(
Function mapperMethod, BasicColumn...selectList) {
return selectDistinct(selectModel -> MyBatis3SelectModelAdapter.of(selectModel, mapperMethod),
selectList);
}
QueryExpressionDSL newQueryExpression(FromGatherer fromGatherer) {
QueryExpressionDSL queryExpression = new QueryExpressionDSL<>(fromGatherer);
queryExpressions.add(queryExpression);
return queryExpression;
}
QueryExpressionDSL newQueryExpression(FromGatherer fromGatherer, String tableAlias) {
QueryExpressionDSL queryExpression = new QueryExpressionDSL<>(fromGatherer, tableAlias);
queryExpressions.add(queryExpression);
return queryExpression;
}
void orderBy(SortSpecification...columns) {
orderByModel = OrderByModel.of(columns);
}
public LimitFinisher limit(long limit) {
this.limit = limit;
return new LimitFinisher();
}
public OffsetFirstFinisher offset(long offset) {
this.offset = offset;
return new OffsetFirstFinisher();
}
public FetchFirstFinisher fetchFirst(long fetchFirstRows) {
this.fetchFirstRows = fetchFirstRows;
return new FetchFirstFinisher();
}
@Override
public R build() {
SelectModel selectModel = SelectModel.withQueryExpressions(buildModels())
.withOrderByModel(orderByModel)
.withPagingModel(buildPagingModel())
.build();
return adapterFunction.apply(selectModel);
}
private List buildModels() {
return queryExpressions.stream()
.map(QueryExpressionDSL::buildModel)
.collect(Collectors.toList());
}
private PagingModel buildPagingModel() {
return new PagingModel.Builder()
.withLimit(limit)
.withOffset(offset)
.withFetchFirstRows(fetchFirstRows)
.build();
}
public class LimitFinisher implements Buildable {
public OffsetFinisher offset(long offset) {
SelectDSL.this.offset = offset;
return new OffsetFinisher();
}
@Override
public R build() {
return SelectDSL.this.build();
}
}
public class OffsetFinisher implements Buildable {
@Override
public R build() {
return SelectDSL.this.build();
}
}
public class OffsetFirstFinisher implements Buildable {
public FetchFirstFinisher fetchFirst(long fetchFirstRows) {
SelectDSL.this.fetchFirstRows = fetchFirstRows;
return new FetchFirstFinisher();
}
@Override
public R build() {
return SelectDSL.this.build();
}
}
public class FetchFirstFinisher {
public RowsOnlyFinisher rowsOnly() {
return new RowsOnlyFinisher();
}
}
public class RowsOnlyFinisher implements Buildable {
@Override
public R build() {
return SelectDSL.this.build();
}
}
}