【问题标题】:How to write a jOOQ converter for an EnumSet (MySQL SET type)如何为 EnumSet(MySQL SET 类型)编写 jOOQ 转换器
【发布时间】:2016-01-21 12:01:14
【问题描述】:

我想将 MySQL 类型 SET 与 jOOQ 代码生成一起使用,简而言之,它类似于 MySQL ENUM,但具有多个值。

我已经尝试过,但我认为泛型类型擦除通过当前的Converter 实现防止了这种情况。也许一些使用TypeTokenConverterType 可以解决这个问题。类似于it's used on the Gson library

让我们使用这个示例数据库:

CREATE TABLE sometable (
  id int(11) NOT NULL PRIMARY_KEY AUTO_INCREMENT,
  availability set('MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY','SATURDAY','SUNDAY')
    COLLATE utf8_spanish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;

代码生成器 XML 可能是这个:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
    <!-- Configure the database connection here -->
    <jdbc>
        <driver>org.gjt.mm.mysql.Driver</driver>
        <url>jdbc:mysql://192.168.1.x/test</url>
        <user>xxxx</user>
        <password>xxxx</password>
    </jdbc>
    <generator>
        <database>
            <name>org.jooq.util.mysql.MySQLDatabase</name>
            <inputSchema>test</inputSchema>
            <customTypes>
                <customType>
                    <name>DayOfWeek</name>
                    <type>java.time.DayOfWeek</type>
                    <converter>sargue.DayOfWeekConverter</converter>
                </customType>
            </customTypes>
            <forcedTypes>
                <forcedType>
                    <name>DayOfWeek</name>
                    <expression>day</expression>
                </forcedType>
            </forcedTypes>
        </database>
        <generate>
            <deprecated>false</deprecated>
        </generate>
        <target>
            <packageName>jooq</packageName>
            <directory>src/main/java</directory>
        </target>
    </generator>
</configuration>

所以现在我需要一个转换器。

package sargue;

import org.jooq.Converter;

import java.time.DayOfWeek;
import java.util.EnumSet;

public class DayOfWeekConverter implements Converter<String, EnumSet<DayOfWeek>>{
    @Override
    public EnumSet<DayOfWeek> from(String databaseObject) {
        if (databaseObject == null) return null;
        EnumSet<DayOfWeek> enumSet = EnumSet.noneOf(DayOfWeek.class);
        for (String s : databaseObject.split(","))
            if (!s.isEmpty())
                enumSet.add(DayOfWeek.valueOf(s));
        return enumSet;
    }

    @Override
    public String to(EnumSet<DayOfWeek> userObject) {
        if (userObject == null) return null;
        return userObject.stream().map(Enum::toString).collect(Collectors.joining(","));
    }

    @Override
    public Class<String> fromType() {
        return String.class;
    }

    @Override
    public Class<EnumSet<DayOfWeek>> toType() {
        // This doesn't work... we need something to circunvent type erasure
        // some sort of TypeToken as in other libraries
        return new EnumSet<DayOfWeek>().getClass();
    }
}

我想我可以为 EnumSet 编写一个转换器,但我会丢失封闭的类型,所以它没用。或者也许我错了,它可以做到!

可以吗?

【问题讨论】:

    标签: java mysql generics enums jooq


    【解决方案1】:

    这是个好主意。我怀疑在未来的 jOOQ 中添加这个功能是值得的:#4694

    通过这两个修复,您应该能够实现您正在寻找的内容:

    XML 配置

    <customType>
        <name>DayOfWeek</name>
        <type>java.util.EnumSet&lt;java.time.DayOfWeek&gt;</type>
        <converter>sargue.DayOfWeekConverter</converter>
    </customType>
    

    转换器代码

    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public Class<EnumSet<DayOfWeek>> toType() {
        return (Class) EnumSet.class;
    }
    

    没有其他方法可以创建Class&lt;EnumSet&lt;DayOfWeek&gt;&gt;DayOfWeek 类型信息在 Class 对象中丢失。 See also this question here。有一些你提到的技巧,但你真的不需要应用这些技巧。

    【讨论】:

    • 在jooq中使用EnumSet有什么好处?
    • @javapowered: 与什么相反?
    • 我的意思是我现在可以在Java中轻松地将String转换为EnumSet,反之亦然,所以jooq中的EnumSet根本不需要?我们会解决这种“按位”更新(添加和删除)吗?这可能很有帮助 imho stackoverflow.com/a/17089677/93647
    • @javapowered:我不太确定你在告诉我什么 :) 可能,你有一个完全不同的问题。这里的这个只是展示了如何创建一个转换器以防有人需要它。是否有人需要由每个人决定......
    • 好的,我认为我的问题与github.com/jOOQ/jOOQ/issues/4694 更相关,所以我在那里发表了评论。
    猜你喜欢
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 2011-09-25
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2015-01-15
    相关资源
    最近更新 更多