有条件的Doobie查询与选项字段

发布于 2025-02-11 12:36:49 字数 1143 浏览 1 评论 0原文

我有关注

case class Request(name:Option[String], age: Option[Int], address: Option[List[String]])

,我想构建这样的查询,并且只有在定义字段时才能适用条件:

val req = Request(Some("abc"), Some(27), Some(List["add1", "add2"])    
select name, age, email from user where name = "abc" AND age = 27 AND address in("add1", "add2");

我经过了Doobies文档,并发现了有关允许我执行以下操作的片段。

val baseSql: Fragment = sql"select name, age, email from user";
val nameFilter: Option[Fragment] = name.map(x => fr" name = $x")
val ageFilter: Option[Fragment] = age.map(x => fr" age = $x")
val addressFilter: Option[Fragment] = address.map(x => fr " address IN ( " ++ x.map(y => fr "$y").intercalate(fr",") ++ fr" )"

val q = baseSql ++ whereAndOpt(nameFilter, ageFilter, addressFilter)

从我的理解来看,如果所有字段都被定义了,则应看起来像这样:

select name, age, email from user where name = "abc" AND age = 27 AND address in("add1","add2");

但是查询看起来像这样:

select name, age, email from user where name = ? AND age = ? AND address in(?);

这里有什么问题,我找不到。

提前致谢 !!!!

I have following

case class Request(name:Option[String], age: Option[Int], address: Option[List[String]])

And I want to construct a query like this the conditions should apply if and only if the field is defined:

val req = Request(Some("abc"), Some(27), Some(List["add1", "add2"])    
select name, age, email from user where name = "abc" AND age = 27 AND address in("add1", "add2");

I went through doobies documentation and found about fragments which allow me to do the following.

val baseSql: Fragment = sql"select name, age, email from user";
val nameFilter: Option[Fragment] = name.map(x => fr" name = $x")
val ageFilter: Option[Fragment] = age.map(x => fr" age = $x")
val addressFilter: Option[Fragment] = address.map(x => fr " address IN ( " ++ x.map(y => fr "$y").intercalate(fr",") ++ fr" )"

val q = baseSql ++ whereAndOpt(nameFilter, ageFilter, addressFilter)

from my understanding the query should look like this if all the fields are defined:

select name, age, email from user where name = "abc" AND age = 27 AND address in("add1","add2");

but the query looks like this:

select name, age, email from user where name = ? AND age = ? AND address in(?);

What is wrong here I am not able to find that.

Thanks in advance !!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╭ゆ眷念 2025-02-18 12:36:49

一切都很好。

doobie在查询中使用在sql功能中防止SQL注入(参数化查询),然后传递数据库应将数据库放入连续的参数。

这样思考:如果有人发布name =“'''; drop table用户;选择1“。然后,您最终

select name, age, email from user where name = ''; DROP table users; SELECT 1

会遇到一个问题。

由于数据库正在为您插入参数,因此在不可能的注入不可能的情况下,它可以在解析原始文本后进行。此功能不仅由Doobie使用,而且实际上是每个现代库或框架,使您可以以高于普通驱动程序的级别与数据库进行交谈。

因此,您看到的是数据库所看到的参数化查询,您只是看不到将传递给它的参数。

Everything is fine.

Doobie prevents SQL injections by SQL functionality where you use ? in your query (parametrized query), and then pass the values that database should put into the consecutive ? arguments.

Think like this: if someone posted name = "''; DROP table users; SELECT 1". Then you'd end up with

select name, age, email from user where name = ''; DROP table users; SELECT 1

which could be a problem.

Since the database is inserting arguments for you, it can do it after the parsing of a raw text, when such injection is impossible. This functionality is used not only by Doobie but by virtually every modern library or framework that let you talk to database at level higher than plain driver.

So what you see is a parametrized query in the way that database will see it, you just don't see the parameters that will be passed to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文