How does the mybatis parameter replacement work in @SelectProvider

断了今生、忘了曾经 提交于 2020-01-13 12:06:53

问题


I've in inherited some code that I'm trying to understand and any searching I do to find something on @SelectProvider turns up a whole lot of nothing.

Java DAO

@SelectProvider(type = CategoryDaoSelectProvider.class, method = "findByParentIdAndName")
Category findByParentIdAndName(@Param("parentId") Long parentId, @Param("name") String name);

Select Provider

public class CategoryDaoSelectProvider {
    public static String findByParentIdAndName(Map<String, Object> params) {
        Long parentId = (Long)params.get("parentId");  // WHY IS THIS HERE???

        StringBuffer buffer = new StringBuffer();
        buffer.append("SELECT COUNT(id) FROM Category ");

        if (parentId == null) {
            buffer.append("WHERE parentId IS NULL ");
        } else {
            buffer.append("WHERE parentId = #{parentId} ");
        }

        buffer.append("AND LOWER(name) = LOWER(#{name}) ");

        return buffer.toString();
    }
}

What purpose does the param parentId serve in this code? As far as I can tell it never actually does anything unless somehow magically the #{parentId} is replaced with the value. Is this param just not used in this situation? Where does mybatis actually do the injections into the query?


回答1:


SelectProviders receive parameters in 2 ways: as items in the params Map argument and as #{parentId} (in your example). You code shows parentId being checked before it is used in the select statement. The parentId variable is needed because you can't query #{parentId}.

Btw, this isn't the best implementation of a SelectProviders, you're supposed to use SELECT(), WHERE() and SQL() at the end to return the compiled statement. I guess your example works too.




回答2:


You could rewrite that piece of code as follows, which is perhaps a bit clearer? The actual value of parentId is indeed not necessary, but the info on whether or not the parameter is present is required.

 // ...
 boolean hasIdParam = params.containsKey("parentId");

 StringBuffer buffer = new StringBuffer();
 buffer.append("SELECT COUNT(id) FROM Category ");

 if (!hasIdParam) {
    buffer.append("WHERE parentId IS NULL ");
 } else {
    buffer.append("WHERE parentId = #{parentId} ");
 }
 // ...


来源:https://stackoverflow.com/questions/8912510/how-does-the-mybatis-parameter-replacement-work-in-selectprovider

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!