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

Add ListTypeHandler #2762

Closed
wants to merge 7 commits into from
Closed

Conversation

FlyInWind1
Copy link
Contributor

I know this is really a big change, and may bring up some backward compatible problem, so suggest is welcome

Add future

  1. Add ResolvedType, only wrap Jackson JavaType. For not depend on jackson, copy classes relate to JavaType into
    org.apache.ibatis.reflection.type.jackson package. Now use JavaType from external Jackson first. TypeHandler lost information of actualTypeArguments when class is ParameterizedType #2187
  2. Add ResolvedMethod, to get returnType and parameterType easier
  3. Implement ListTypeHandler SetTypeHandler. when we use @Param annotation, like this param.field, that cause my custom TypeHandler dosen't work #1445
  4. Register ListTypeHandler, SetTypeHandler and ArrayTypeHandler into TypeHandlerRegistry, then we don't
    need to write typeHandler="ArrayTypeHandler" in xml
  5. resultType and resultMap in xml is not obligatory, get Mapper Class by namespace and get Method by id, then we can
    get returnType

Other changes

  1. Add ParamNameResolver#getNamedParamsType, this may return a MapDescriptorResolvedType when
    ParamNameResolver#getNamedParams return a ParamMap, MapDescriptorResolvedType contains each value ResolvedType
  2. List or array index access check, see PropertyTokenizer#isIndexAccess, without this change ArrayTypeHandler will use
    for #{array[0]}
  3. LanguageDriver interface add two createSqlSource methods that use ResolvedType instead of Class, all createSqlSource
    methods are default for backward compatible
  4. TypeReference do not resolve TypeParameter at construct time, getRawType is useless for now
  5. Make some method and field protected. I tried to make my futures compatible with mybatisPlus, but fond they copy
    lost of code to their project. make method protected, so that mybatisPlus do not need copy

May be not backward compatible

  1. TypeHandlerRegistry#typeHandlerMap use ResolvedType as map key, this may have problem for user custom typeHandler.
    For example user write a typeHandler for ArrayList<Object> but hope autoMapping for ArrayList<String>, this may no
    problem before, but now autoMapping will can't find typeHandler, because of typeParameter not match
  2. TypeHandlerRegistry#getMappingTypeHandler will check whether the TypeHandler need a Class for construct. I hope user
    can just write typeHandler without write javaType, because javaType attribute can't resolve ParameterizedType. BaseBuilder#resolveTypeHandler does not account javaType for caching handlers #995
  3. Try to resolve TypeHandler at SqlSourceBuilder, not use UnknownTypeHandler, because in UnknownTypeHandler can only
    get parameter Class, not ParameterizedType
  4. DynamicSqlSource add ParamType, for pass ParameterizedType, I add a parameterType parameter to constructor, this may
    occur exception if user pass instance that not instanceof parameterType
  5. User can pass Map<String,String> into function with Map<Map,Integer> parameter by cast, just like (Map)
    stringValueMap. Mybatis use UnknownTypeHandler for Map parameter at before, there is no problem if user pass wrong
    type. but now we can know we just need use IntegerTypeHandler to handle Map values, use IntegerTypeHandler to handle
    String will occur exception

@harawata
Copy link
Member

harawata commented Dec 21, 2022

Thank you, @FlyInWind1 !

This PR includes several changes.


Implement ListTypeHandler SetTypeHandler.

Are these new type handlers specifically for ARRAY JDBC type?
#1445 has nothing to do with ARRAY type (MySQL does not have ARRAY type).
As ARRAY is rarely used (it's often considered to be an anti-pattern), it may be better to let uses define their own type handler when it's necessary rather than adding many rarely used entries to TypeHandlerRegistry.


Regarding ParameterizedType support, you modified the right places , so nice work!
Bringing in ResolvedType, however, looks overkill.

As I commented on #2187 , I have been working on it for a while.
As you understand the issue, it would be great if you could take a look at my work-in-progress branch.
https://github.com/harawata/mybatis-3/tree/type-based-handler-resolution
I'm still unsure about a few things, but if you are willing to help me finish the enhancement, I'll open a draft PR to continue discussion.

What I am looking for is a failing test case (meaning, a scenario that should work, but doesn't).
For example, you changed the type of the field ResultMap.type from Class to ResolvedType.
I want to know which test case requires this change (in other words, why this change was necessary).


resultType and resultMap in xml is not obligatory, get Mapper Class by namespace and get Method by id, then we can get returnType

> List or array index access check, see PropertyTokenizer#isIndexAccess, without this change ArrayTypeHandler will use
for #{array[0]}

These look reasonable, but each of them should be an independent PR.


Make some method and field protected. I tried to make my futures compatible with mybatisPlus, but fond they copy lost of code to their project. make method protected, so that mybatisPlus do not need copy

I'm not sure which method/field you are talking about, but I generally prefer not to expose internal stuff. We should be able to change internal code without worrying about other projects.
In any case, this should be a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants