Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow registering a type handler for a common interface of enums. #947

Merged
merged 1 commit into from
Mar 15, 2017

Conversation

harawata
Copy link
Member

@harawata harawata commented Mar 15, 2017

It is common for multiple enums to have a common interface along with a corresponding type handler.
Up to version 3.4.2, to use this type handler, users had to list all the enum implementations in the @MappedType or <typeHandlers />.

This PR allows users to register the type handler against the common interface.
Please see the attached test case for how it works.

Cc-ing @gaohanghbut @liyuj @yxc023 @charlesluo2014 @Hubbitus @fengdh @fayou @sskeater @jlkm2010
Thought you guys might be interested.

@harawata harawata added the enhancement Improve a feature or add a new feature label Mar 15, 2017
@harawata harawata added this to the 3.4.3 milestone Mar 15, 2017
@harawata harawata self-assigned this Mar 15, 2017
@harawata harawata merged commit f3bd219 into mybatis:master Mar 15, 2017
kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this pull request Mar 16, 2017
kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this pull request Mar 16, 2017
@gaohanghbut
Copy link

@harawata thanks for your attribution

@kazuki43zoo
Copy link
Member

Hi @harawata, I have one question.
I don't know how to convert to enum instance from result set value using this solution. I think that it need to set enum type to cutom TypeHandler for converting a enum instance. Could you tell me how to do it ?

@harawata
Copy link
Member Author

@kazuki43zoo ,
I re-checked the code and you are right. This fix is incomplete :(
I'll create another PR soon.
Thank you for the review!

harawata added a commit to harawata/mybatis-3 that referenced this pull request Apr 13, 2017
…o a new instance of the type handler that takes the enum type as a constructor argument.
harawata added a commit that referenced this pull request Apr 16, 2017
…take2

Proper fix for #947 . When there is a type handler registered to a super interface of an enum, new instance of the type handler should be created with the enum type as a constructor argument.
@mahengyang
Copy link

mahengyang commented Jul 20, 2017

the constractor of custom typehandler has some error

public HasValueEnumTypeHandler(Class<E> type) {
   if (type == null)
     throw new IllegalArgumentException("Type argument cannot be null");
   this.type = type;
   this.enums = type.getEnumConstants();

this.enums is aways null becase the parameter type is a interface

@harawata
Copy link
Member Author

@mahengyang

type is supposed to be an enum that implements HasValue interface, not the interface itself.

@mahengyang
Copy link

mahengyang commented Jul 21, 2017

@harawata if there is many enum,we need write every enum type handler in mybatis-config.xml, like this, Witch makes me feel a little verbose

<typeHandlers>
    <typeHandler javaType="com.qbike.eum.LeipaiOrderStatus" handler="com.qbike.mybatis.EnumTypeHandler"/>
    <typeHandler javaType="com.qbike.eum.TestStatus" handler="com.qbike.mybatis.EnumTypeHandler"/>
</typeHandlers>

the handler EnumTypeHandler

public class EnumTypeHandler<E extends Enum<E> & EnumCode> extends BaseTypeHandler<E> {
    private Class<E> type;
    private EnumCode[] enums;

    public EnumTypeHandler(Class<E> type) {
        this.type = type;
        this.enums = type.getEnumConstants();
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return find(rs.getInt(columnName));
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return find(rs.getInt(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return find(cs.getInt(columnIndex));
    }

    private E find(int status) {
        for (EnumCode enumCode : enums) {
            if (enumCode.getCode() == status) {
                return (E) enumCode;
            }
        }
        return null;
    }
}

@harawata
Copy link
Member Author

@mahengyang ,
Are you actually having a problem, or just reading the code?
this.enums being null should not be a problem because the instance registered against HasValue interface is not used when converting enums (a new instance is created and registered for each enum).

There is a working test case, so if you found a bug, please create a failing test case.
Thanks!

Note that there is a bug in 3.4.4 and you need to use 3.4.5-SNAPSHOT for now (I assumed you knew it seeing your comment on #976 ).

@michaelplavnik
Copy link

Implementation of the feature is still incomplete.
When used with XMLConfigBuilder.parse, eager instantiation of the defined handlers happens and each enum type need to be explicitly listed.

XMLConfigBuilder.parse is called by mybatis-spring project for example.

@kazuki43zoo
Copy link
Member

@michaelplavnik This PR is already merged. Please create a new issue as related this.

pulllock pushed a commit to pulllock/mybatis-3 that referenced this pull request Oct 19, 2023
pulllock pushed a commit to pulllock/mybatis-3 that referenced this pull request Oct 19, 2023
…o a new instance of the type handler that takes the enum type as a constructor argument.
pulllock pushed a commit to pulllock/mybatis-3 that referenced this pull request Oct 19, 2023
…erface-take2

Proper fix for mybatis#947 . When there is a type handler registered to a super interface of an enum, new instance of the type handler should be created with the enum type as a constructor argument.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve a feature or add a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants