
sf.r2dbc.sql.R2dbcConvertUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sorm Show documentation
Show all versions of sorm Show documentation
java jpa tool for spring
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