QueryCondition add enum param

This commit is contained in:
开源海哥 2023-05-14 11:49:56 +08:00
parent 47878fb5e6
commit 07425d1b81
3 changed files with 130 additions and 62 deletions

View File

@ -15,58 +15,27 @@
*/
package com.mybatisflex.core.handler;
import com.mybatisflex.annotation.EnumValue;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.StringUtil;
import com.mybatisflex.core.util.EnumWrapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class FlexEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
private final Class<?> enumPropertyType;
private final E[] enums;
private Field property;
private Method getter;
private EnumWrapper<E> enumWrapper;
public FlexEnumTypeHandler(Class<E> enumClass) {
List<Field> allFields = ClassUtil.getAllFields(enumClass, field -> field.getAnnotation(EnumValue.class) != null);
Field field = allFields.get(0);
String fieldGetterName = "get" + StringUtil.firstCharToUpperCase(field.getName());
List<Method> allMethods = ClassUtil.getAllMethods(enumClass, method -> {
String methodName = method.getName();
return methodName.equals(fieldGetterName);
});
enumPropertyType = ClassUtil.wrap(field.getType());
enums = enumClass.getEnumConstants();
if (allMethods.isEmpty()) {
if (Modifier.isPublic(field.getModifiers())) {
property = field;
} else {
throw new IllegalStateException("Can not find \"" + fieldGetterName + "()\" method in enum: " + enumClass.getName());
}
} else {
getter = allMethods.get(0);
}
enumWrapper = new EnumWrapper<>(enumClass);
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
Object value = getValue(parameter);
Object value = enumWrapper.getValue(parameter);
if (jdbcType == null) {
ps.setObject(i, value);
} else {
@ -74,55 +43,35 @@ public class FlexEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
}
}
private Object getValue(E object) {
try {
return getter != null
? getter.invoke(object)
: property.get(object);
} catch (Exception e) {
throw FlexExceptions.wrap(e);
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
Object value = rs.getObject(columnName, this.enumPropertyType);
Object value = rs.getObject(columnName, enumWrapper.getEnumPropertyType());
if (null == value && rs.wasNull()) {
return null;
}
return convertToEnum(value);
return enumWrapper.getEnum(value);
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Object value = rs.getObject(columnIndex, this.enumPropertyType);
Object value = rs.getObject(columnIndex, enumWrapper.getEnumPropertyType());
if (null == value && rs.wasNull()) {
return null;
}
return convertToEnum(value);
return enumWrapper.getEnum(value);
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Object value = cs.getObject(columnIndex, this.enumPropertyType);
Object value = cs.getObject(columnIndex, enumWrapper.getEnumPropertyType());
if (null == value && cs.wasNull()) {
return null;
}
return convertToEnum(value);
return enumWrapper.getEnum(value);
}
private E convertToEnum(Object value) {
for (E e : enums) {
if (value.equals(getValue(e))) {
return e;
}
}
return null;
}
}

View File

@ -18,6 +18,7 @@ package com.mybatisflex.core.query;
import com.mybatisflex.core.dialect.IDialect;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.EnumWrapper;
import java.io.Serializable;
import java.lang.reflect.Array;
@ -98,6 +99,12 @@ public class QueryCondition implements Serializable {
}
public void setValue(Object value) {
if (value != null && value.getClass().isEnum()) {
EnumWrapper enumWrapper = new EnumWrapper(value.getClass());
if (enumWrapper.hasEnumValueAnnotation()) {
value = enumWrapper.getValue((Enum) value);
}
}
this.value = value;
}
@ -120,7 +127,7 @@ public class QueryCondition implements Serializable {
this.effective = (effective != null && effective);
}
public <T> QueryCondition when(Predicate<T> fn){
public <T> QueryCondition when(Predicate<T> fn) {
Object val = this.value;
if (LOGIC_LIKE.equals(logic) && val instanceof String) {
String valStr = (String) val;

View File

@ -0,0 +1,112 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.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.mybatisflex.core.util;
import com.mybatisflex.annotation.EnumValue;
import com.mybatisflex.core.exception.FlexExceptions;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
public class EnumWrapper<E extends Enum<E>> {
private Class<?> enumClass;
private Class<?> enumPropertyType;
private E[] enums;
private Field property;
private Method getter;
private boolean hasEnumValueAnnotation = false;
public EnumWrapper(Class<E> enumClass) {
this.enumClass = enumClass;
List<Field> allFields = ClassUtil.getAllFields(enumClass, field -> field.getAnnotation(EnumValue.class) != null);
if (!allFields.isEmpty()) {
hasEnumValueAnnotation = true;
}
if (hasEnumValueAnnotation) {
Field field = allFields.get(0);
String fieldGetterName = "get" + StringUtil.firstCharToUpperCase(field.getName());
List<Method> allMethods = ClassUtil.getAllMethods(enumClass, method -> {
String methodName = method.getName();
return methodName.equals(fieldGetterName);
});
enumPropertyType = ClassUtil.wrap(field.getType());
enums = enumClass.getEnumConstants();
if (allMethods.isEmpty()) {
if (Modifier.isPublic(field.getModifiers())) {
property = field;
} else {
throw new IllegalStateException("Can not find \"" + fieldGetterName + "()\" method in enum: " + enumClass.getName());
}
} else {
getter = allMethods.get(0);
}
}
}
public Object getValue(E object) {
try {
return getter != null
? getter.invoke(object)
: property.get(object);
} catch (Exception e) {
throw FlexExceptions.wrap(e);
}
}
public E getEnum(Object value) {
for (E e : enums) {
if (value.equals(getValue(e))) {
return e;
}
}
return null;
}
public Class<?> getEnumClass() {
return enumClass;
}
public Class<?> getEnumPropertyType() {
return enumPropertyType;
}
public E[] getEnums() {
return enums;
}
public Field getProperty() {
return property;
}
public Method getGetter() {
return getter;
}
public boolean hasEnumValueAnnotation() {
return hasEnumValueAnnotation;
}
}