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