使用 MyBatis Velocity 的动态 SQL 请求

Dynamic SQL request with MyBatis Velocity

这是一个有效的例子:

public class Parameter {
  private final String name;
  private final Long Id;
  ... constructor and getters
}

@Mapper
public interface UserMyBatisRepository {
    @Select("select * from users WHERE users.name=@{name} #if($_parameter.id) AND users.id=@{id}#end")
    public List<User> find(Parameter p);
}

我想将字段 sql 添加到 Parameter 中并像这样使用 Mapper

@Select("@{sql}")
public List<User> find(Parameter p);
or
@Select("$_parameter.sql")
public List<User> find(Parameter p);

在这种情况下似乎不应用格式,因为我不断收到如下错误:

### SQL: ?
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''select * from users WHERE users.name=@{name} #if($_parameter.id) AND u' at line 1

### SQL: select * from users WHERE users.name=@{name} #if($_parameter.id) AND users.id=@{id}#end
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{name} #if($_parameter.id) AND users.id=@{id}#end' at line 1

有没有合适的实现方式?

您需要使用 SQL 提供商。

// other imports...
import org.apache.ibatis.annotations.Lang;
import org.apache.ibatis.annotations.SelectProvider;
import org.mybatis.scripting.velocity.VelocityLanguageDriver;

@Mapper
public interface UserMyBatisRepository {

  @Lang(VelocityLanguageDriver.class)
  @SelectProvider(type = Provider.class, method = "find")
  List<User> find(Parameter p);

  class Provider {
    public String find(Parameter p) {
      return p.getSql();
    }
  }

}

@Lang 如果在配置中指定 defaultScriptingLanguage 则不需要

p.s.
对于默认的 XML 脚本,请参阅