SQL 在 Mybatis Generator 中生成 Instant 的服务器类型

SQL Server type to generate Instant in Mybatis Generator

我想在SQL服务器中定义列,以便Mybatis Generator生成java.time.Instantjava.time.OffsetDateTime。根据 Mybatis Generator Core,当 useJSR310Typestrue

时,类型为 TIMESTAMP_WITH_TIMEZONE 的列映射到 OffsetDateTime

我使用类型 DATETIMEOFFSET in my DDL but my entities were translated as Object. Of course using DATETIME2 结果是 LocalDateTime,这不是我想要的。

示例 DDL

CREATE TABLE Users
(
    UserId        Int IDENTITY (1,1) NOT NULL,
    UserFirstName Nvarchar(50)       NOT NULL,
    UserLastName  Nvarchar(50)       NOT NULL,
    UserEmail     Nvarchar(100)      NOT NULL,
    Created DATETIME2 NOT NULL,
    Creator INT NOT NULL,
    Modified DATETIME2 NOT NULL,
    Modifier INT NOT NULL
);

generatorConfig.xml

的相关片段
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "https://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>

    <contexttargetRuntime="MyBatis3DynamicSql" defaultModelType="hierarchical">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <jdbcConnection driverClass="${jdbcDriverClass}"
                        connectionURL="${jdbcUrl}"
                        userId="${jdbcUsername}"
                        password="${jdbcPassword}"
        >
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>

        <javaTypeResolver type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
            <property name="useJSR310Types" value="true"/>
        </javaTypeResolver>

        <javaModelGenerator targetPackage=""
                            targetProject="${workingDir}/src/main/java"/>

        <javaClientGenerator targetPackage=""
                             targetProject="${workingDir}/src/main/java" type="ANNOTATEDMAPPER"/>

        
        <table tableName="Users" domainObjectName="User" mapperName="UserBaseMapper">
            <property name="rootInterface" value=""/>
            <generatedKey column="UserId" identity="true" sqlStatement="JDBC"/>
        </table>

    </context>

</generatorConfiguration>

MyBatis Generator 依赖 JDBC 类型解析驱动。您可以在此处查看 SQL 服务器如何进行类型映射:https://docs.microsoft.com/en-us/sql/connect/jdbc/using-basic-data-types?view=sql-server-ver15

根据该页面,DATETIMEOFFSET 映射到非标准 JDBC 类型 microsoft.sql.Types.DATETIMEOFFSET。生成器对那个类型一无所知(MyBatis 本身也不知道)。这就是生成器将列解析为 Object.

的原因

如果您想在 SQL 服务器中使用 DATETIMEOFFSET 列,那么您可以在生成器中使用覆盖将 Java 类型映射到 microsoft.sql.DateTimeOffset。您还需要编写一个类型处理程序,以便 MyBatis 可以使用此类型。

不幸的是 SQL 服务器没有直接映射到 TIMESTAMP_WITH_TIMEZONE 的类型。

还有另一种方法。

建议Mybatis使用Instant

     <table tableName="Users" domainObjectName="User" mapperName="UserBaseMapper">
        <property name="rootInterface" value=""/>
        <generatedKey column="UserId" identity="true" sqlStatement="JDBC"/>
        <columnOverride column="Created" jdbcType="TIMESTAMP_WITH_TIMEZONE" javaType="java.time.Instant"/>
        <columnOverride column="Modified" jdbcType="TIMESTAMP_WITH_TIMEZONE" javaType="java.time.Instant"/>
    </table>

也许(也许)JDBC 类型是多余的,但它在 SQL 服务器和 H2 数据库上都有效,其中 H2 使用 TIMESTAMP WITH TIME ZONE 作为列类型