Flexible data type conversion mechanism of O / R mapping library Lightsleep for Java 8

Regarding Lightsleep, I posted an introductory article on Qiita, so please see below.

Introducing Lightsleep, an O / R mapping library that works only with Java Runtime and JDBC drivers

Lightsleep has a mechanism for flexible data type conversion, which is used internally. It is not essential to know the details of using Lightsleep, but it is helpful to know what kind of conversion will be done.

Where to use data type conversion

It is mainly used in the following two places.

  1. Where to convert property values of entity objects to literal strings to generate SQL For example

    • "Yukari's apples"'Yukari''s apples'
    • 2017/2/12 (java.sql.Date) ➔ DATE'2017-02-17'
  2. Where to set the value obtained from DB to entity object For example --BigDecimal ➔ Integer (column type is NUMBER (9) / Oracle) --Long ➔ java.sql.Date (column type is BIGINT)

The above 2 is the original purpose of data type conversion, so that it can be stored even if the value to be stored and the type of the variable to store it are different.

1 uses this mechanism to generate SQL literal strings. Since the conversion content is different from the normal character string, the conversion destination data type is SqlString class. By having a data type conversion map for each database handler, it is possible to generate DBMS-specific SQL.

Class that performs data type conversion

org.lightsleep.helper.TypeConverter is a class that performs data type conversion. When using Lightsleep, I don't think it's common to use this class directly, but I'll explain it briefly.

This class has two constructors:

  1. TypeConverter(Class<ST> sourceType, Class<DT> destinType, Function<ST, DT> function)
  2. <MT> TypeConverter(TypeConverter<ST, MT> typeConverter1, TypeConverter<MT, DT> typeConverter2)

The arguments of constructor 1 are the data type (sourceType) of the conversion source, the data type (destinType) of the conversion destination, and the Function object (function) that performs the conversion. function is described by a lambda expression.

java:Long->java.sql.Date


    new TypeConverter<>(Long.class, Date.class, object -> new Date(object))

The arguments for constructor 2 are two other TypeConverter objects.

java:java.util.Date->Integer


    new TypeConverter<>(
        TypeConverter.get(typeConverterMap, java.util.Date.class, Long.class),
        TypeConverter.get(typeConverterMap, Long.class, Integer.class)
    )

The static TypeConverter.get method in the above example is a method to get the TypeConverter object registered in the map. The Function object of this TypeConverter object will be typeConverter1.function.andThen (typeConverter2.function) `(composite function).

Since the TypeConverter object has a key generated from the conversion source data type and the conversion destination data type, use the static TypeConverter # put method instead of Map # put when registering the map.

java:Long->java.sql.Date


TypeConverter.put(typeConverterMap,
    new TypeConverter<>(Long.class, Date.class, object -> new Date(object))
);

java:java.util.Date->Integer


TypeConverter.put(typeConverterMap,
    new TypeConverter<>(
        TypeConverter.get(typeConverterMap, java.util.Date.class, Long.class),
        TypeConverter.get(typeConverterMap, Long.class, Integer.class)
    )
);

Data type conversion processing is performed by the static TypeConverter # convert method. This method performs the conversion process according to the following procedure.

  1. Generate a map key from the conversion source object type and conversion destination data type of the argument.
  2. Get the TypeConverter object from the argument data conversion type map.
  3. Convert the data type by calling the apply method of the Function object of the TypeConverter object.

However, if the conversion source object of the argument is null or castable to the conversion destination data type, the conversion source object is returned as it is without conversion processing.

In 2, static TypeConverter # get is used, but if the specified source data type and destination data type combination cannot be found, then the source data type cannot be found in the interface or superclass of that type. I will try it. If found, you can use that conversion function, so create a key from the found data type and the destination data type and register it in the map so that you can simply search for the TypeConverter object in the next conversion process. If no convertible TypeConverter object is finally found, a ConvertException is thrown.

Storage location of TypeConverter object

The TypeConverter object is stored in a variable of type Map <String, TypeConverter <?,? >> In the following classes.

  1. TypeConverter class
  2. Standard class and its subclasses (MySQL, Oracle, PostgreSQL, SQLite, SQLServer)

1 has a map of static variables and 2 has a map of instance variables. The Standard class and its subclasses are singleton classes and there is only one object per class, so there is one data type conversion map per class as well as 1.

Two are commonly used in the data type conversion process, and which one is used is determined by specifying the Database property in lightsleep.propeties.

TypeConverter object stored in the data type conversion map of each class

TypeConverter class

This class of data type conversion maps contains the following TypeConverter objects that perform common data type conversions that are independent of O / R mappings.

Conversion source data type Conversion destination data type Conversion content
Byte Boolean 0 ➔ false
1 ➔ true
In other cases, throw ConvertException
Short
Integer
Long
Float
Double
BigDecimal
Character '0' ➔ false
'1' ➔ true
Throw ConvertException in other cases
String "0" ➔ false
"1" ➔ true
Throw ConvertException in other cases
Boolean Bytefalse ➔ 0
true ➔ 1
Short Throw ConvertException if out of range
Integer
Long
Float
Double
BigDecimal
Character
String Throw ConvertException if non-numeric or out of range
Boolean Shortfalse ➔ 0
true ➔ 1
Byte
Integer Throw ConvertException if out of range
Long
Float
Double
BigDecimal
Character
String Throw ConvertException if non-numeric or out of range
Boolean Integerfalse ➔ 0
true ➔ 1
Byte
Short
Long Throw ConvertException if out of range
Float
Double
BigDecimal
Character
String Throw ConvertException if non-numeric or out of range
java.util.Date Throw ConvertException if out of range
Boolean Longfalse ➔ 0
true ➔ 1
Byte
Short
Integer
Float Throw ConvertException if out of range
Double
BigDecimal
Character
String Throw ConvertException if non-numeric or out of range
java.util.Date Get long value
Boolean Floatfalse ➔ 0.0F
true ➔ 1.0F
Byte
Short
Integer
Long
Double
BigDecimal
Character
String Throw ConvertException for non-numeric values
Boolean Doublefalse ➔ 0.0D
true ➔ 1.0D
Byte
Short
Integer
Long
Float
BigDecimal
Character
String Throw ConvertException for non-numeric values
Boolean BigDecimalfalse ➔ BigDecimal.ZERO
true ➔ BigDecimal.ONE
Byte
Short
Integer
Long
Float
Double
Character
String Throw ConvertException for non-numeric values
Boolean Characterfalse ➔ '0'
true ➔ '1'
Byte
Short
Integer Throw ConvertException if out of range
Long
Float
Double
BigDecimal
String Throw ConvertException if String length is other than 1
BigDecimal String Convert with toPlainString ()
java.uitl.Date"yyyy-MM-dd"
java.sql.Date
Time "HH:mm:ss"
Timestamp "yyyy-MM-dd HH:mm:ss.SSS"
Object Convert with toString ()
Integer java.util.Date
Long
BigDecimal Throw ConvertException if conversion to Long is out of range
String "yyyy-MM-dd" ➔ String
Throw ConvertException if format is incorrect
Integer java.sql.Date
Long
BigDecimal Throw ConvertException if conversion to Long is out of range
java.util.Date
String "yyyy-MM-dd" ➔ String
Throw ConvertException if format is incorrect
Integer Time
Long
BigDecimal Throw ConvertException if conversion to Long is out of range
java.util.Date
String "HH: mm: ss" ➔ String
Throw ConvertException if format is incorrect
Long Timestamp
Integer
BigDecimal Throw ConvertException if conversion to Long is out of range
java.util.Date
String "yyyy-MM-dd HH: mm: ss" or
"yyyy-MM-dd HH: mm: ss.SSS " ➔ String
Throw ConvertException if format is incorrect
Enum Byte Convert with ordinal ()
Throw ConvertException if out of range
Short
Integer Convert with ordinal ()
Long

Standard class

The data type conversion map of this class adds a TypeConverter object specific to the following O / R mappings to all TypeConverter objects of the TypeConverter class.

Conversion source data type Conversion destination data type Conversion content
Clob String Throw ConvertException if length exceeds Integer.MAX_VALUE
Contents Throws ConvertException if SQLException is thrown when retrieving
Blob byte[]
java.sql.Array boolean [] Convert each element to array element data type with TypeConverter
byte[]
short[]
int[]
long[]
float[]
double[]
BigDecimal[]
String[]
java.util.Date[]
java.sql.Date[]
Time[]
Timestamp[]
Boolean SqlStringfalse ➔ FALSE
true ➔ TRUE
Object '...'
Character
BigDecimal
String '...'
If long, ? (SQL parameter) >
java.util.DateDATE'yyyy-MM-dd'
java.sql.Date
Time TIME'HH:mm:ss'
Timestamp TIMESTAMP'yyyy-MM-dd HH:mm:ss.SSS'
Enum '...' (converted with toString ())
byte [] X'...'
If long, ? (SQL parameter)
boolean [] ARRAY [x, y, z, ...]
Turn each element into a SqlString with TypeConverter Conversion
char[]
byte[][]
short[]
int[]
long[]
float[]
double[]
BigDecimal[]
String[]
java.util.Date[]
java.sql.Date[]
Time[]
Timestamp[]
Iterable (x, y, z, ...)
Convert each element to SqlString with TypeConverter >

MySQL class

The data type conversion map for this class adds a MySQL-specific TypeConverter object to every TypeConverter object that the Standard class has.

Conversion source data type Conversion destination data type Conversion content
BooleanSqlStringfalse ➔ 0
true ➔ 1
String '...'
Control characters are converted to escape sequences
? if long > (SQL parameters)

Oracle class

The data type conversion map for this class adds an Oracle Database-specific TypeConverter object to every TypeConverter object that the Standard class has.

Conversion source data type Conversion destination data type Conversion content
BooleanSqlStringfalse ➔ 0
true ➔ 1
String '...'
The control character is'...'||CHR(n)||'...'Conversion to
If long? (SQL parameters)
Time TO_TIMESTAMP('1970-01-01 HH:mm:ss','YYYY-MM-DD HH24:MI:SS.FF3')
byte [] ? (SQL parameter)
oracle.sql.TIMESTAMP java.util.Date When SQLException is thrown when getting the value Throw ConvertException
java.sql.Date
java.sql.Time
java.sql.Timestamp

PostgreSQL class

The data type conversion map for this class adds a PostgreSQL-specific TypeConverter object to every TypeConverter object that the Standard class has.

Conversion source data type Conversion destination data type Conversion content
String SqlString '...'
Control characters are converted to escape sequences
If it is long, ? (SQL parameter)
byte [] E'\\ x ...'
If long, ? ( SQL parameter)

SQLite class

The data type conversion map for this class adds a SQLite-specific TypeConverter object to every TypeConverter object that the Standard class has.

Conversion source data type Conversion destination data type Conversion content
Boolean SqlStringfalse ➔ 0
true ➔ 1
java.util.Date'yyyy-MM-dd'
java.sql.Date
Time 'HH:mm:ss'
Timestamp 'yyyy-MM-dd HH:mm:ss.SSS'
byte [] ? (SQL parameter)

SQLServer class

The data type conversion map for this class adds a Microsoft SQL Server-specific TypeConverter object to every TypeConverter object that the Standard class has.

Conversion source data type Conversion destination data type Conversion content
Boolean SqlStringfalse ➔ 0
true ➔ 1
java.sql.DateCAST('yyyy:MM:dd' AS DATE)
Time CAST('HH:mm:ss' AS DATE)
Timestamp CAST('yyyy-MM-dd HH:mm:ss.SSS' AS DATETIME2)
String '...'
The control character is '...' + CHAR (n) +'... Convert to'
? (SQL parameter) if long
byte [] ? (SQL parameter)

Recommended Posts

Flexible data type conversion mechanism of O / R mapping library Lightsleep for Java 8
[Java] Precautions for type conversion
Step-by-step understanding of O / R mapping
Introducing Lightsleep, an O / R mapping library that works only with Java Runtime and JDBC drivers
Java date data type conversion (Date, Calendar, String)
[Basic knowledge of Java] About type conversion
[Java] Calculation mechanism, operators and type conversion
Java type conversion
Review and implementation of CSV library for loading large amounts of data into MySQL (Java)
JAVA object mapping library
[Java] Data type ①-Basic type
[Java] Date type conversion