|
@@ -0,0 +1,123 @@
|
|
|
+package org.hswebframework.web.dao.mybatis.mapper.dict;
|
|
|
+
|
|
|
+import org.hswebframework.ezorm.core.OptionConverter;
|
|
|
+import org.hswebframework.ezorm.core.param.Term;
|
|
|
+import org.hswebframework.ezorm.core.param.TermType;
|
|
|
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
|
|
|
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
|
|
|
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
|
|
|
+import org.hswebframework.ezorm.rdb.render.dialect.RenderPhase;
|
|
|
+import org.hswebframework.ezorm.rdb.render.dialect.function.SqlFunction;
|
|
|
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
|
|
|
+import org.hswebframework.web.dao.mybatis.mapper.AbstractSqlTermCustomer;
|
|
|
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
|
|
|
+import org.hswebframework.web.dict.EnumDict;
|
|
|
+
|
|
|
+import java.sql.JDBCType;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+
|
|
|
+ * @author zhouhao
|
|
|
+ * @since 3.0.0-RC
|
|
|
+ */
|
|
|
+public class DictInTermTypeMapper extends AbstractSqlTermCustomer {
|
|
|
+
|
|
|
+ private boolean not;
|
|
|
+
|
|
|
+ public static final String USE_DICT_MASK_FLAG = "dict-mask";
|
|
|
+
|
|
|
+ public DictInTermTypeMapper(boolean not) {
|
|
|
+ super(not ? TermType.nin : TermType.in);
|
|
|
+ this.not = not;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean support(RDBColumnMetaData column) {
|
|
|
+ Class type = column.getJavaType();
|
|
|
+ if (type.isArray()) {
|
|
|
+ type = type.getComponentType();
|
|
|
+ }
|
|
|
+ return ((type.isEnum() && EnumDict.class.isAssignableFrom(type))
|
|
|
+ ||
|
|
|
+ (column.getProperty(USE_DICT_MASK_FLAG).isTrue() && column.getOptionConverter() != null));
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("all")
|
|
|
+ private List<EnumDict> getAllOption(RDBColumnMetaData column) {
|
|
|
+ Class type = column.getJavaType();
|
|
|
+ if (null != type) {
|
|
|
+ if (type.isArray()) {
|
|
|
+ type = type.getComponentType();
|
|
|
+ }
|
|
|
+ if (type.isEnum() && EnumDict.class.isAssignableFrom(type)) {
|
|
|
+ return (List) Arrays.asList(type.getEnumConstants());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ OptionConverter converter = column.getOptionConverter();
|
|
|
+ if (converter == null) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ return (List) converter.getOptions();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
|
|
|
+
|
|
|
+ if (!support(column)) {
|
|
|
+ return buildNotSupport(wherePrefix, term, column, tableAlias);
|
|
|
+ }
|
|
|
+ ChangedTermValue changedValue = createChangedTermValue(term);
|
|
|
+
|
|
|
+ boolean any = term.getOptions().contains("any");
|
|
|
+
|
|
|
+ List<Object> list = BoostTermTypeMapper.convertList(column, changedValue.getOld());
|
|
|
+
|
|
|
+ EnumDict[] dicts = getAllOption(column)
|
|
|
+ .stream()
|
|
|
+ .filter(d -> d.eq(list))
|
|
|
+ .toArray(EnumDict[]::new);
|
|
|
+
|
|
|
+ changedValue.setValue(EnumDict.toMask(dicts));
|
|
|
+ Dialect dialect = column.getTableMetaData().getDatabaseMetaData().getDialect();
|
|
|
+
|
|
|
+ String columnName = dialect.buildColumnName(tableAlias, column.getName());
|
|
|
+ String where = "#{" + wherePrefix + ".value.value}";
|
|
|
+ SqlFunction sqlFunction = dialect.getFunction(SqlFunction.bitand);
|
|
|
+
|
|
|
+ if (sqlFunction == null) {
|
|
|
+ throw new UnsupportedOperationException("数据库不支持[BITAND]函数");
|
|
|
+ }
|
|
|
+ String bitAnd = sqlFunction.apply(SqlFunction.Param.of(RenderPhase.where, Arrays.asList(columnName, where)));
|
|
|
+
|
|
|
+ String n;
|
|
|
+ if (any) {
|
|
|
+ n = not ? "=" : "!=";
|
|
|
+ } else {
|
|
|
+ n = not ? "!=" : "=";
|
|
|
+ }
|
|
|
+ return new SqlAppender().add(bitAnd, n, any ? "0" : where);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ protected SqlAppender buildNotSupport(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
|
|
|
+ ChangedTermValue changedValue = createChangedTermValue(term);
|
|
|
+ Dialect dialect = column.getTableMetaData().getDatabaseMetaData().getDialect();
|
|
|
+
|
|
|
+ List<Object> values = BoostTermTypeMapper.convertList(column, changedValue.getOld());
|
|
|
+
|
|
|
+ changedValue.setValue(values);
|
|
|
+
|
|
|
+ String columnName = dialect.buildColumnName(tableAlias, column.getName());
|
|
|
+ SqlAppender appender = new SqlAppender();
|
|
|
+ appender.add(columnName, not ? " NOT" : " ").add("IN(");
|
|
|
+ for (int i = 0; i < values.size(); i++) {
|
|
|
+ appender.add("#{", wherePrefix, ".value.value[", i, "]}", ",");
|
|
|
+ }
|
|
|
+ appender.removeLast();
|
|
|
+ appender.add(")");
|
|
|
+ return appender;
|
|
|
+ }
|
|
|
+}
|