All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sf.r2dbc.sql.R2dbcConvertUtils Maven / Gradle / Ivy

The newest version!
package sf.r2dbc.sql;

import io.r2dbc.spi.Blob;
import io.r2dbc.spi.Clob;
import io.r2dbc.spi.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.convert.Jsr310Converters;
import reactor.core.publisher.Mono;
import sf.database.jdbc.type.AttributeConverterType;
import sf.database.jdbc.type.TypeHandler;
import sf.database.meta.ColumnMapping;
import sf.r2dbc.binding.BindMarker;

import javax.persistence.AttributeConverter;
import javax.persistence.EnumType;
import javax.persistence.TemporalType;
import java.io.ByteArrayOutputStream;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.util.Date;
import java.util.concurrent.CountDownLatch;

public class R2dbcConvertUtils {
    private static Logger log = LoggerFactory.getLogger(R2dbcConvertUtils.class);

    static GenericConversionService CONVERSION_SERVICE = new DefaultConversionService();

    static {
        Jsr310Converters.getConvertersToRegister().forEach(CONVERSION_SERVICE::addConverter);
    }

    public static  T get(N dbData, Class dbDataClass, ColumnMapping cm) {
        AttributeConverter attributeConverter = null;
        TypeHandler typeHandler = null;
        Class clz = null;
        if (cm != null) {
            clz = cm.getClz();
            typeHandler = cm.getHandler();
            if (typeHandler.getClass() == AttributeConverterType.class) {
                attributeConverter = ((AttributeConverterType) typeHandler).getAttributeConverter();
            }
        }
        return (T) convertToEntityAttribute(dbData, dbDataClass, clz, (AttributeConverter) attributeConverter);
    }

    public static  T get(N dbData, Class dbDataClass, Class targetClass, AttributeConverter attributeConverter, TypeHandler typeHandler) {
        return (T) convertToEntityAttribute(dbData, dbDataClass, targetClass, (AttributeConverter) attributeConverter);
    }

    public static void set(BindMarker spec, Statement target, Object value,
                           Class targetClass, AttributeConverter attributeConverter, TemporalType temporalType, EnumType enumType) {
        if (targetClass == null) {
            targetClass = Object.class;
        }
        if (value == null) {
            spec.bindNull(target, fixBugs(targetClass, temporalType));
        } else {
            spec.bind(target, convertToDatabaseColumn(value, targetClass, (AttributeConverter) attributeConverter, temporalType, enumType));
        }
    }

    public static Statement set(Statement spec, Object value, int index,
                                Class targetClass, AttributeConverter attributeConverter, TemporalType temporalType, EnumType enumType) {
        if (targetClass == null) {
            targetClass = Object.class;
        }
        if (value == null) {
            return spec.bindNull(index, targetClass);
        } else {
            return spec.bind(index, convertToDatabaseColumn(value, targetClass, (AttributeConverter) attributeConverter, temporalType, enumType));
        }
    }

    public static Statement set(Statement spec, Object value, String parameterName,
                                Class targetClass, AttributeConverter attributeConverter, TemporalType temporalType, EnumType enumType) {
        if (targetClass == null) {
            targetClass = Object.class;
        }
        if (value == null) {
            return spec.bindNull(parameterName, targetClass);
        } else {
            return spec.bind(parameterName, convertToDatabaseColumn(value, targetClass, (AttributeConverter) attributeConverter, temporalType, enumType));
        }
    }

    /**
     * 支持jpa的原生转换注解
     * @param attribute
     * @param targetClass
     * @param converter
     * @param temporalType
     * @param enumType
     * @param 
     * @param 
     * @return
     * @see javax.persistence.Convert
     * @see AttributeConverter
     */
    private static  Y convertToDatabaseColumn(X attribute, Class targetClass, AttributeConverter converter, TemporalType temporalType, EnumType enumType) {
        if (attribute == null) {
            return null;
        }
        if (targetClass == null) {
            targetClass = (Class) Object.class;
        }
        if (converter != null) {
            return converter.convertToDatabaseColumn(attribute);
        }

        return (Y) fixBugs(attribute, targetClass, temporalType, enumType);
    }

    /**
     * 支持jpa的原生转换注解
     * @param dbData
     * @param targetClass
     * @param converter
     * @param 
     * @param 
     * @return
     * @see javax.persistence.Convert
     * @see AttributeConverter
     */
    private static  X convertToEntityAttribute(Y dbData, Class dbDataClass, Class targetClass, AttributeConverter converter) {
        if (dbData == null || (targetClass != null && targetClass == dbData.getClass())) {
            return (X) dbData;
        }
        if (converter != null) {
            return converter.convertToEntityAttribute(dbData);
        }
        if (targetClass == null) {
            targetClass = (Class) Object.class;
        }
        if (dbDataClass == null) {
            dbDataClass = (Class) dbData.getClass();
        }
        Object data = dbData;
        //以下是特殊转换
        if (ByteBuffer.class.isAssignableFrom(dbDataClass)) {
//            ByteBuffer buffer = (ByteBuffer) dbData;
//            byte[] bytes = new byte[buffer.remaining()];
//            for (int i = 0; i < bytes.length; i++) {
//                bytes[i] = buffer.get(i);
//            }
//            data = bytes;
        } else if (Blob.class.isAssignableFrom(dbDataClass)) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Blob blob = (Blob) dbData;
            CountDownLatch latch = new CountDownLatch(1);
            Mono.from(blob.stream()).doFinally(signalType -> latch.countDown()).subscribe(buffer -> {
                while (buffer.hasRemaining()) {
                    baos.write(buffer.get());
                }
                buffer.clear();
            });
            try {
                latch.await();
            } catch (InterruptedException e) {
                log.error("", e);
            }
            data = baos.toByteArray();
        } else if (Clob.class.isAssignableFrom(dbDataClass)) {
            StringWriter sw = new StringWriter();
            CountDownLatch latch = new CountDownLatch(1);
            Clob clob = (Clob) dbData;
            Mono.from(clob.stream()).doFinally(signalType -> latch.countDown()).subscribe(sw::append);
            try {
                latch.await();
            } catch (InterruptedException e) {
                log.error("", e);
            }
            data = sw.toString();
        } else if (dbDataClass == Duration.class) {
            data = new Date(((Duration) dbData).toMillis());
        } else if (dbDataClass == LocalTime.class) {
            data = Time.valueOf((LocalTime) dbData);
        } else if (dbDataClass == LocalDate.class) {
            data = java.sql.Date.valueOf((LocalDate) dbData);
        } else if (dbDataClass == LocalDateTime.class) {
            data = Timestamp.valueOf((LocalDateTime) dbData);
        } else if (dbDataClass == OffsetTime.class) {
            data = Time.valueOf(((OffsetTime) dbData).toLocalTime());
        } else if (dbDataClass == OffsetDateTime.class) {
            data = Timestamp.valueOf(((OffsetDateTime) dbData).toLocalDateTime());
        }
//        if (ByteBuffer.class.isAssignableFrom(dbDataClass) && targetClass == Object.class) {
//            targetClass = (Class) byte[].class;
//        }
//        if (CONVERSION_SERVICE.canConvert(data.getClass(),targetClass)){
//            return CONVERSION_SERVICE.convert(data, targetClass);
//        }
        return CONVERSION_SERVICE.convert(data, targetClass);
    }

    /**
     * 1.r2dbc时间只认jdk8的时间
* 2.枚举的处理. * @param val * @param targetClass * @param temporalType * @param enumType * @return */ public static Object fixBugs(Object val, Class targetClass, TemporalType temporalType, EnumType enumType) { if (Date.class.isAssignableFrom(val.getClass())) { Date date = (Date) val; if (temporalType != null) { switch (temporalType) { case TIME: return new Time(date.getTime()).toLocalTime(); case DATE: return new java.sql.Date(date.getTime()).toLocalDate(); case TIMESTAMP: return new Timestamp(date.getTime()).toLocalDateTime(); default: break; } } //默认为时间戳 return new Timestamp(date.getTime()).toLocalDateTime(); } else if (val.getClass().isEnum()) { if (enumType == EnumType.ORDINAL) { return ((Enum) val).ordinal(); } return val.toString(); } return CONVERSION_SERVICE.convert(val, targetClass); } public static Class fixBugs(Class valueClass, TemporalType temporalType) { if (Date.class.isAssignableFrom(valueClass)) { if (temporalType != null) { switch (temporalType) { case TIME: return LocalTime.class; case DATE: return LocalDate.class; case TIMESTAMP: return LocalDateTime.class; default: break; } } //默认为时间戳 return LocalDateTime.class; } return valueClass; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy