123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /**
- * Copyright (c) 2011-2020, hubin (jobob@qq.com).
- * <p>
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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 com.baomidou.mybatisplus;
- import java.io.IOException;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.List;
- import com.baomidou.mybatisplus.toolkit.CollectionUtils;
- import com.baomidou.mybatisplus.toolkit.StringUtils;
- /**
- * <p>
- * 重定义 AbstractSQL ,实现标准TSQL的 查询条件自定义
- * </p>
- *
- * @author yanghu
- * @Date 2016-08-22
- */
- @SuppressWarnings("serial")
- public abstract class MybatisAbstractSQL<T> implements Serializable {
- private static final String AND = " AND ";
- private static final String OR = " OR ";
- private static final String AND_NEW = ") \nAND (";
- private static final String OR_NEW = ") \nOR (";
- /**
- * SQL条件
- */
- private final SQLCondition sql = new SQLCondition();
- /**
- * 子类泛型实现
- *
- * @return 泛型实例
- */
- public abstract T getSelf();
- public T WHERE(String conditions) {
- sql().where.add(conditions);
- sql().lastList = sql().where;
- return getSelf();
- }
- public T OR() {
- sql().lastList.add(OR);
- return getSelf();
- }
- public T OR_NEW() {
- sql().lastList.add(OR_NEW);
- return getSelf();
- }
- public T AND() {
- sql().lastList.add(AND);
- return getSelf();
- }
- public T AND_NEW() {
- sql().lastList.add(AND_NEW);
- return getSelf();
- }
- public T GROUP_BY(String columns) {
- sql().groupBy.add(columns);
- return getSelf();
- }
- public T HAVING(String conditions) {
- sql().having.add(conditions);
- sql().lastList = sql().having;
- return getSelf();
- }
- public T ORDER_BY(String columns) {
- sql().orderBy.add(columns);
- return getSelf();
- }
- public T LAST(String last) {
- sql().last = last;
- return getSelf();
- }
- private SQLCondition sql() {
- return sql;
- }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sql().sql(sb);
- return sb.toString();
- }
- /**
- * 查看构造器where是否为空
- *
- * @return
- */
- public boolean isEmptyOfWhere() {
- return CollectionUtils.isEmpty(sql().where);
- }
- /**
- * SQL连接器
- */
- private static class SafeAppendable implements Serializable {
- private final Appendable appendable;
- private boolean empty = true;
- public SafeAppendable(Appendable appendable) {
- super();
- this.appendable = appendable;
- }
- public SafeAppendable append(CharSequence charSequence) {
- try {
- if (empty && charSequence.length() > 0) {
- empty = false;
- }
- appendable.append(charSequence);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return this;
- }
- public boolean isEmpty() {
- return empty;
- }
- }
- /**
- * SQL条件类
- */
- private static class SQLCondition implements Serializable {
- final List<String> where = new ArrayList<>();
- final List<String> having = new ArrayList<>();
- final List<String> groupBy = new ArrayList<>();
- final List<String> orderBy = new ArrayList<>();
- final List<String> andOr = new ArrayList<>();
- String last = null;
- List<String> lastList = new ArrayList<>();
- public SQLCondition() {
- andOr.add(AND);
- andOr.add(OR);
- andOr.add(AND_NEW);
- andOr.add(OR_NEW);
- }
- /**
- * 构建SQL的条件
- *
- * @param builder 连接器
- * @param keyword TSQL中的关键字
- * @param parts SQL条件语句集合
- * @param open 起始符号
- * @param close 结束符号
- * @param conjunction 连接条件
- */
- private void sqlClause(SafeAppendable builder, String keyword, List<String> parts, String open, String close,
- String conjunction) {
- parts = clearNull(parts);
- if (!parts.isEmpty()) {
- if (!builder.isEmpty()) {
- builder.append("\n");
- }
- builder.append(keyword);
- builder.append(" ");
- builder.append(open);
- String last = "__";
- for (int i = 0, n = parts.size(); i < n; i++) {
- String part = parts.get(i);
- if (i > 0) {
- if (andOr.contains(part) || andOr.contains(last)) {
- builder.append(part);
- last = part;
- continue;
- } else {
- builder.append(conjunction);
- }
- }
- builder.append(part);
- }
- builder.append(close);
- }
- }
- /**
- * 清除LIST中的NULL和空字符串
- *
- * @param parts 原LIST列表
- * @return
- */
- private List<String> clearNull(List<String> parts) {
- List<String> temps = new ArrayList<>();
- for (String part : parts) {
- if (StringUtils.isEmpty(part)) {
- continue;
- }
- temps.add(part);
- }
- return temps;
- }
- /**
- * 按标准顺序连接并构建SQL
- *
- * @param builder 连接器
- * @return
- */
- private String buildSQL(SafeAppendable builder) {
- sqlClause(builder, "WHERE", where, "(", ")", AND);
- sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");
- sqlClause(builder, "HAVING", having, "(", ")", AND);
- sqlClause(builder, "ORDER BY", orderBy, "", "", ", ");
- if (StringUtils.isNotEmpty(last)) {
- builder.append(" ");
- builder.append(last);
- }
- return builder.toString();
- }
- public String sql(Appendable appendable) {
- return buildSQL(new SafeAppendable(appendable));
- }
- }
- }
|