001/* 002 * Copyright (c) 2022-2025, 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 */ 016package com.mybatisflex.core.query; 017 018 019import com.mybatisflex.core.FlexConsts; 020import com.mybatisflex.core.constant.SqlConsts; 021import com.mybatisflex.core.dialect.DialectFactory; 022import com.mybatisflex.core.dialect.IDialect; 023import com.mybatisflex.core.dialect.impl.OracleDialect; 024import com.mybatisflex.core.util.ClassUtil; 025import com.mybatisflex.core.util.EnumWrapper; 026import com.mybatisflex.core.util.StringUtil; 027 028import java.lang.reflect.Array; 029import java.util.ArrayList; 030import java.util.Arrays; 031import java.util.Collections; 032import java.util.List; 033 034class WrapperUtil { 035 036 private WrapperUtil() { 037 } 038 039 static List<QueryWrapper> getChildQueryWrapper(QueryCondition condition) { 040 List<QueryWrapper> list = null; 041 while (condition != null) { 042 if (condition.checkEffective()) { 043 if (condition instanceof Brackets) { 044 List<QueryWrapper> childQueryWrapper = getChildQueryWrapper(((Brackets) condition).getChildCondition()); 045 if (!childQueryWrapper.isEmpty()) { 046 if (list == null) { 047 list = new ArrayList<>(); 048 } 049 list.addAll(childQueryWrapper); 050 } 051 } 052 // not Brackets 053 else if (condition instanceof OperatorSelectCondition) { 054 if (list == null) { 055 list = new ArrayList<>(); 056 } 057 list.add(((OperatorSelectCondition) condition).getQueryWrapper()); 058 } else { 059 Object value = condition.getValue(); 060 if (value instanceof QueryWrapper) { 061 if (list == null) { 062 list = new ArrayList<>(); 063 } 064 list.add((QueryWrapper) value); 065 list.addAll(((QueryWrapper) value).getChildSelect()); 066 } else if (value != null && value.getClass().isArray()) { 067 for (int i = 0; i < Array.getLength(value); i++) { 068 Object arrayValue = Array.get(value, i); 069 if (arrayValue instanceof QueryWrapper) { 070 if (list == null) { 071 list = new ArrayList<>(); 072 } 073 list.add((QueryWrapper) arrayValue); 074 list.addAll(((QueryWrapper) arrayValue).getChildSelect()); 075 } 076 } 077 } 078 } 079 } 080 condition = condition.next; 081 } 082 return list == null ? Collections.emptyList() : list; 083 } 084 085 086 static Object[] getValues(QueryCondition condition) { 087 if (condition == null) { 088 return FlexConsts.EMPTY_ARRAY; 089 } 090 091 List<Object> params = new ArrayList<>(); 092 getValues(condition, params); 093 094 return params.isEmpty() ? FlexConsts.EMPTY_ARRAY : params.toArray(); 095 } 096 097 098 private static void getValues(QueryCondition condition, List<Object> params) { 099 if (condition == null) { 100 return; 101 } 102 103 QueryColumn column = condition.getColumn(); 104 if (column instanceof HasParamsColumn) { 105 addParam(params, ((HasParamsColumn) column).getParamValues()); 106 } 107 108 Object value = condition.getValue(); 109 110 if (value == null) { 111 // column = user_name; logic = eq; value = null 112 // sql: user_name = null 113 String logic; 114 if (condition.checkEffective() 115 && (logic = condition.getLogic()) != null 116 && !logic.equals(SqlConsts.IS_NULL) 117 && !logic.equals(SqlConsts.IS_NOT_NULL)) { 118 params.add(null); 119 } 120 getValues(condition.next, params); 121 return; 122 } 123 124 if (value instanceof QueryColumn || value instanceof RawQueryCondition) { 125 getValues(condition.next, params); 126 return; 127 } 128 129 addParam(params, value); 130 getValues(condition.next, params); 131 } 132 133 @SuppressWarnings("all") 134 private static void addParam(List<Object> paras, Object value) { 135 if (value == null) { 136 paras.add(null); 137 } else if (ClassUtil.isArray(value.getClass())) { 138 for (int i = 0; i < Array.getLength(value); i++) { 139 addParam(paras, Array.get(value, i)); 140 } 141 } else if (value instanceof QueryWrapper) { 142 Object[] valueArray = ((QueryWrapper) value).getAllValueArray(); 143 paras.addAll(Arrays.asList(valueArray)); 144 } else if (value instanceof Enum) { 145 // 枚举类型,处理枚举实际值 146 EnumWrapper enumWrapper = EnumWrapper.of(value.getClass()); 147 // 如果是使用注解标识枚举实际值,则直接获取实际值,但如果是依靠全局枚举TypeHandler处理,则此处只能先存入枚举实例,在SQL执行时才能处理实际值 148 value = enumWrapper.hasEnumValueAnnotation() ? enumWrapper.getEnumValue((Enum) value) : value; 149 paras.add(value); 150 } else { 151 paras.add(value); 152 } 153 154 } 155 156 static String buildValue(List<QueryTable> queryTables, Object value) { 157 if (value instanceof Number || value instanceof Boolean) { 158 return String.valueOf(value); 159 } else if (value instanceof RawQueryCondition) { 160 return ((RawQueryCondition) value).getContent(); 161 } else if (value instanceof QueryColumn) { 162 return ((QueryColumn) value).toConditionSql(queryTables, DialectFactory.getDialect()); 163 } else { 164 return SqlConsts.SINGLE_QUOTE + value + SqlConsts.SINGLE_QUOTE; 165 } 166 } 167 168 169 static String withBracket(String sql) { 170 return SqlConsts.BRACKET_LEFT + sql + SqlConsts.BRACKET_RIGHT; 171 } 172 173 static String withAlias(String sql, String alias, IDialect dialect) { 174 return SqlConsts.BRACKET_LEFT + sql + SqlConsts.BRACKET_RIGHT + buildColumnAlias(alias, dialect); 175 } 176 177 static String buildAlias(String alias, IDialect dialect) { 178 return StringUtil.noText(alias) ? SqlConsts.EMPTY : getAsKeyWord(dialect) + dialect.wrap(alias); 179 } 180 181 static String buildColumnAlias(String alias, IDialect dialect) { 182 return StringUtil.noText(alias) ? SqlConsts.EMPTY : getAsKeyWord(dialect) + dialect.wrapColumnAlias(alias); 183 } 184 185 private static String getAsKeyWord(IDialect dialect) { 186 return dialect instanceof OracleDialect ? SqlConsts.BLANK : SqlConsts.AS; 187 } 188 189}