How does the mybatis parameter replacement work in

2019-05-08 06:50发布

问题:

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} ");
 }
 // ...