-
Notifications
You must be signed in to change notification settings - Fork 13k
Allow omit a 'method' attribute on SqlProvider annotation #1499
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
Conversation
Related with mybatisgh-1279
|
This PR will make it easier to use ProviderSqlSource normally. I use a special way to make generic crud operations . In my case, method will point to a fixed number of methods. These methods will generate special SQL based on the mapperMethod name. One of them is as follows @SelectProvider(type = JPAQueryMethodProvider.class, method = "queryMethod")
User findByLastnameAndFirstname(@Param("lastname") String lastname, @Param("firstname")String firstname);
@SelectProvider(type = JPAQueryMethodProvider.class, method = "queryMethod")
User findByFirstnameLike(@Param("firstname")String firstname); |
|
The common basic methods are as follows: public interface SelectAllMapper<T> {
@SelectProvider(type = BaseSelectProvider.class, method = "dynamicSQL")
List<T> selectAll();
}
public interface SelectMapper<T> {
@SelectProvider(type = BaseSelectProvider.class, method = "dynamicSQL")
List<T> select(T record);
}
public UserMapper extends SelectAllMapper<User>, SelectMapper<User> {
} |
|
Thank you, @kazuki43zoo ! I didn't give much thought when I proposed the resolver interface, but it should be possible to define the resolver method as 'static'. Then we might have to consider searching the method by its signature instead.
Or, is there any cleaner idea? |
|
By the way, I thought about the original request after a while and it looked a little bit unusual. With the common/generic mapper strategy, as @abel533 explained, the base mapper contains the provider annotations, so users don't have to write method names manually in most cases. So, it's useful only when defining SQL providers manually. |
I think so, too.
I think that there are developers that prefer to write a dynamic SQL using provider method instead of XML because the Java code can be debug or measure coverage easily rather than XML. |
|
Hi @harawata , Thank you for you comments.
I think it is clearer to use an interface for indicating an API specification, what is the reason (advantage) to not use an interface? |
harawata
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few comments.
| default Method resolveMethod(ProviderContext context) { | ||
| List<Method> targetMethods = Arrays.stream(getClass().getMethods()) | ||
| .filter(m -> m.getName().equals(context.getMapperMethod().getName())) | ||
| .filter(m -> CharSequence.class.isAssignableFrom(m.getReturnType())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be better to check the return type later to throw clearer error message e.g. 'the return type of the method must be CharSequence or its subclass'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix via 877284a
| * </li> | ||
| * <li> | ||
| * If cannot resolve a method by {@link org.apache.ibatis.builder.annotation.ProviderMethodResolver}(= not implement it or it was returned {@code null}), | ||
| * the MyBatis will search and use a fallback method that named {@code resolveSql} from specified type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolveSql -> provideSql ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix via b1cfb84
|
Thanks for your review! |
|
Thanks for the update! (the below is the comment I was going to post before submitted the review)
I guess you are right. It should be the developer's choice.
Okay. Let's go with the interface. |
Allow omit a 'method' attribute on SqlProvider annotation
Fixes gh-1279
I've tried to fix gh-1279. In this change, a developer can omit the
methodattribute on SqlProvider annotation (such as@SelectProvider, etc...).If the
methodattribute was omitted, the MyBatis try to resolve a target method as follow:If specified type is implements
ProviderMethodResolveradded by this PR, the MyBatis use a method that returned by itIf cannot resolve by
ProviderMethodResolver(= not implement or it was returnednull), the MyBatis will search aprovideSqlmethod(= reserved fallback method) from specified type.If cannot resolve a target method by above processing, the MyBatis throw a
BuilderException.NOTE:
For this change, I add the
ProviderMethodResolverinterface and default implementation. In default implementation, it return a method that method name is matched with mapper method. If not found or found multiple methods, it throw aBuilderException.WDYT?
Related Issues or PRs