MyBatis枚举使用 [英] MyBatis enum usage

查看:134
本文介绍了MyBatis枚举使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道以前有人问过,但是根据我到目前为止发现的信息,我无法实现解决方案。所以也许有人可以向我解释。

I know this has been asked before, but I wasn't able to implement a solution based on the information I found so far. so perhaps someone can explain it to me.

我有一个表状态。它有两列:id和name。 id是一个PK。

I have a table "status". It has two columns:id and name. id is a PK.

而不是使用POJO状态,我想使用一个枚举。我创建了如下枚举:

Instead of using a POJO Status, I would like to use an enum. I created such an enum as follows:

public enum Status {
    NEW(1), READY(2), CLOSED(3);

    private int id;

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

    Status(int id) {
        this.id = id;
    }
}

这里是我的mapper

here is my mapper

     <select id="getStatusByName" resultType="Status" parameterType="String">       
        SELECT  ls.id, ls.name
        FROM status AS ls
        WHERE ls.name = #{name}
    </select>

但由于某种原因,我尝试检索一个枚举,一些中断,但没有异常抛出。

but for some reason, when I try to retrieve an enum, something breaks, but no exception is thrown.

推荐答案

我已经从一对夫妇的角度,这里是我的发现。注意事项:我使用MyBatis-3.1.1做了所有这些调查,所以在早期版本中可能会有不同的表现。

I have worked on this question from a couple of angles and here are my findings. Caveat: I did all these investigations using MyBatis-3.1.1, so things might have behaved differently in earlier versions.

首先,MyBatis有一个内置的 EnumTypeHandler 。默认情况下,任何时候您将Java枚举指定为resultType或parameterType,这将会处理该类型。对于查询,当尝试将数据库记录转换为Java枚举时,EnumTypeHandler仅接受一个参数,并尝试查找与该值对应的Java枚举值。

First, MyBatis has a built-in EnumTypeHandler. By default, any time you specify a Java enum as a resultType or parameterType, this is what will handle that type. For queries, when trying to convert a database record into a Java enum, the EnumTypeHandler only takes one argument and tries to look up the Java enum value that corresponds to that value.

一个例子会更好的说明。假设您以上的查询返回 2 就绪,当我通过就绪作为参数。在这种情况下,我收到错误消息无枚举常量com.foo.Status.2 。如果我将SELECT语句的顺序颠倒为

An example will better illustrate. Suppose your query above returns 2 and "Ready" when I pass in "Ready" as the argument. In that case, I get the error message No enum constant com.foo.Status.2. If I reverse the order of your SELECT statement to be

SELECT ls.name, ls.id

然后错误消息是没有枚举常量com.foo.Status.Ready 。我假设你可以推断MyBatis在做什么。请注意,EnumTypeHandler忽略从查询返回的第二个值。

then the error message is No enum constant com.foo.Status.Ready. I assume you can infer what MyBatis is doing. Note that the EnumTypeHandler is ignoring the second value returned from the query.

将查询更改为

SELECT UPPER(ls.name)

导致它工作:返回Status.READY枚举。

causes it to work: the Status.READY enum is returned.

所以接下来我试图为状态枚举定义我自己的TypeHandler。不幸的是,与默认的 EnumTypeHandler 一样,我只能得到一个值(id或name),以引用正确的枚举,而不是两者。所以如果数据库id与上面硬编码的值不匹配,那么你将不一致。如果您确保数据库ID始终与您在枚举中指定的id相匹配,那么从数据库中所需的所有数据都是名称(转换为大写)。

So next I tried to define my own TypeHandler for the Status enum. Unfortunately, as with the default EnumTypeHandler, I could only get one of the values (id or name) in order to reference the right Enum, not both. So if the database id does not match the value you hardcoded above, then you will have a mismatch. If you ensure that the database id always matches the id you specify in the enum, then all you need from the database is the name (converted to upper case).

然后我以为我会聪明并实现一个MyBatis ObjectFactory,同时抓住int id和String的名称,并确保它们在Java枚举中被匹配,但是我没有使用MyBatis不会为Java调用ObjectFactory枚举类型(至少我不能让它工作)。

Then I thought I'd get clever and implement a MyBatis ObjectFactory, grab both the int id and String name and ensure those are matched up in the Java enum I pass back, but that did not work as MyBatis does not call the ObjectFactory for a Java enum type (at least I couldn't get it to work).

所以我的结论是,只要你需要匹配,MyBatis中的Java枚举就很容易从数据库到枚举常量名称的名称 - 使用内置的EnumTypeHandler或定义自己的,如果在SQL中执行UPPER(name)不足以匹配Java枚举名称。在许多情况下,这是足够的,因为枚举值可能只是对列的检查约束,并且它只有单个值,而不是id。如果您还需要匹配一个int id和一个名称,那么在设置Java枚举和/或数据库条目时,可以手动匹配ID。

So my conclusion is that Java enums in MyBatis are easy as long as you just need to match up the name from the database to the enum constant name - either use the built-in EnumTypeHandler or define your own if doing UPPER(name) in the SQL isn't enough to match the Java enum names. In many cases, this is sufficient, as the enumerated value may just be a check constraint on a column and it has only the single value, not an id as well. If you need to also match up an int id as well as a name, then make the IDs match manually when setting up the Java enum and/or database entries.

最后如果你想看到一个例子,可以在这里查看我的MyBatis koan的koan 23: https://github.com / midpeter444 / MyBatis的-koans 的。如果您只想查看我的解决方案,请查看完成的koans / koan23目录。我还有一个例子,通过Java枚举将数据插入数据库。

Finally, if you'd like to see a working example of this, see koan 23 of my MyBatis koans here: https://github.com/midpeter444/mybatis-koans. If you just want to see my solution, look in the completed-koans/koan23 directory. I also have an example there of inserting a record into the database via a Java enum.

这篇关于MyBatis枚举使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆