当 SQL 子句需要 "disappear" 用于退化情况时,有没有办法使用 @Bind 而不是 @Define ?
Is there a way to use @Bind instead of @Define when an SQL clause needs to "disappear" for a degenerate case?
注意:此示例已大大简化。
我从这样的方法开始:
private static final String QUERY_B = QUERY_A + " AND (foo = :bar) \n";
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId,
@Bind("bar") String bar);
但是,如果 bar
是一个空字符串,我需要整个子句消失,例如 就好像它只是:
private static final String QUERY_B = QUERY_A + " \n";
所以,我构建了一个查询,在这种情况下,只需插入 "true"
,即
private static final String QUERY_B = QUERY_A + " AND true \n";
我们的想法是在将子句传递给函数之前生成一个子句,"true"
或 (foo = 123)
:
private static final String QUERY_B = QUERY_A + " AND <clause> \n";
但这意味着我必须使用 @Define
,而不是 @Bind
:
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId,
@Define("clause") String clause);
现在这意味着该方法对 SQL 注入开放。
我不想尝试自己对其进行消毒 (Defense Option 4)。
有没有办法回到使用 @Bind
、而不 创建一个完全独立的方法,即
@SqlQuery(MASTER_QUERY + " AND " + QUERY_A)
public abstract Long doQueryB(@Bind("userId") String userId);
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId,
@Bind("bar") String bar);
...因为在 bar
的情况下,有几个密切相关的方法都需要重复,除此之外,我们期望 bar
的种类越来越多以后会引入,如果我们走那条路,将需要创建大量的方法。
我过去通过使用 OR 子句来检查参数是否需要 "disappear" 来实现类似的逻辑。因此,如果是空字符串,您的 SQL 可能如下所示:
private static final String QUERY_B = QUERY_A + " AND (:bar = '' OR foo = :bar) \n";
这种方法的最大优点是您可以保持方法签名不变:
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId, @Bind("bar") String bar);
注意:此示例已大大简化。
我从这样的方法开始:
private static final String QUERY_B = QUERY_A + " AND (foo = :bar) \n";
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId,
@Bind("bar") String bar);
但是,如果 bar
是一个空字符串,我需要整个子句消失,例如 就好像它只是:
private static final String QUERY_B = QUERY_A + " \n";
所以,我构建了一个查询,在这种情况下,只需插入 "true"
,即
private static final String QUERY_B = QUERY_A + " AND true \n";
我们的想法是在将子句传递给函数之前生成一个子句,"true"
或 (foo = 123)
:
private static final String QUERY_B = QUERY_A + " AND <clause> \n";
但这意味着我必须使用 @Define
,而不是 @Bind
:
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId,
@Define("clause") String clause);
现在这意味着该方法对 SQL 注入开放。
我不想尝试自己对其进行消毒 (Defense Option 4)。
有没有办法回到使用 @Bind
、而不 创建一个完全独立的方法,即
@SqlQuery(MASTER_QUERY + " AND " + QUERY_A)
public abstract Long doQueryB(@Bind("userId") String userId);
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId,
@Bind("bar") String bar);
...因为在 bar
的情况下,有几个密切相关的方法都需要重复,除此之外,我们期望 bar
的种类越来越多以后会引入,如果我们走那条路,将需要创建大量的方法。
我过去通过使用 OR 子句来检查参数是否需要 "disappear" 来实现类似的逻辑。因此,如果是空字符串,您的 SQL 可能如下所示:
private static final String QUERY_B = QUERY_A + " AND (:bar = '' OR foo = :bar) \n";
这种方法的最大优点是您可以保持方法签名不变:
@SqlQuery(MASTER_QUERY + " AND " + QUERY_B)
public abstract Long doQueryB(@Bind("userId") String userId, @Bind("bar") String bar);