gpt4 book ai didi

java - JDBI SQL 对象查询中的动态顺序

转载 作者:搜寻专家 更新时间:2023-10-30 20:59:42 25 4
gpt4 key购买 nike

如何在 JDBI 中使用 SQL 对象查询进行排序?

我想做这样的事情:

@SqlQuery(
"SELECT * FROM users " +
"WHERE something = :something " +
"ORDER BY :orderBy :orderDir"
)
List<User> getUsers(
@Bind("something") Integer something
, @BindOrderBy("orderBy") String orderBy
, @BindOrderDir("orderDir") String orderDir
);

@SqlQuery(
"SELECT * FROM users " +
"WHERE something = :something " +
"ORDER BY :orderBy :orderDir"
)
List<User> getUsers(
@Bind("something") Integer something
, @Bind("orderBy") OrderBy orderBy
, @Bind("orderDir") OrderDir orderDir
);

最佳答案

我最近一直在探索与 JDBI 捆绑在一起的 DropWizard,并很快遇到了同样的问题。不幸的是,JDBI 的文档乏善可陈(JavaDoc 和它的 git 存储库上的一些示例单元测试不能单独使用),这令人失望。

这是我发现的基于我的示例 DAO 在 JDBI 的 Sql 对象 API 中实现动态顺序的内容:

@UseStringTemplate3StatementLocator
public interface ProductsDao {

@RegisterMapperFactory(BeanMapperFactory.class) // will map the result of the query to a list of Product POJOs(Beans)
@SqlQuery("select * from products order by <orderby> <order> limit :limit offset :offset")
List<Product> getProducts(@Define("orderby") String orderBy, @Define("order") String order,
@Bind("limit") int limit, @Bind("offset") int offset);

@SqlQuery("select count(*) from products")
int getProductsCount();

}

@UseStringTemplate3StatementLocator - 这个注释允许我们使用 <arg>查询中的语法。这些参数将被替换为我们通过 @Define 提供的任何值注解。

为了能够使用此功能,我必须另外将此依赖项添加到我的 pom.xml 中文件:

<dependency>
<groupId>antlr</groupId>
<artifactId>stringtemplate</artifactId>
<version>2.3b6</version> <!-- I am not sure if this specific version is meant to be used though -->
</dependency>

SQL 注入(inject)警告应该注意的是,这打开了我们 Sql Injection因为值直接插入到查询中。 (与查询中的 :arg 语法和使用准备好的语句并防止 sql 注入(inject)的 @Bind 注释相反)。至少您应该清理将用于 @Define 的参数领域。 (下面是 DropWizard 的简单示例)。

@Path("/products")
@Produces(MediaType.APPLICATION_JSON)
public class ProductsResource {
private static ImmutableSet<String> orderByChoices = ImmutableSet.of("id", "name", "price", "manufactureDate");

private final ProductsDao dao;

public ProductsResource(ProductsDao dao) {
this.dao = dao;
}

@GET
// Use @InjectParam to bind many query parameters to a POJO(Bean) instead.
// https://jersey.java.net/apidocs/1.17/jersey/com/sun/jersey/api/core/InjectParam.html
// i.e. public List<Product> index(@InjectParam ProductsRequest request)
// Also use custom Java types for consuming request parameters. This allows to move such validation/sanitization logic outside the 'index' method.
// https://jersey.java.net/documentation/1.17/jax-rs.html#d4e260
public List<Product> index(@DefaultValue("id") @QueryParam("orderby") String orderBy,
@DefaultValue("asc") @QueryParam("order") String order,
@DefaultValue("20") @QueryParam("perpage") IntParam perpage,
@DefaultValue("0") @QueryParam("page") IntParam page)

int limit, offset;

order = order.toLowerCase();
orderBy = orderBy.toLowerCase();

if (!orderByChoices.contains(orderBy)) orderBy = "id"; //sanitize <orderby>
if (order != "asc" && order != "desc") order = "asc"; //sanitize <order>

limit = perpage.get();
offset = page.get() < 0 ? 0 : page.get() * limit;

return dao.getProducts(orderBy, order, limit, offset);

}
}

关于java - JDBI SQL 对象查询中的动态顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16790529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com