-
|
A two part question, first a design question and the second specific to my situation: First, why are specific parameter values specified to the query builder in things like the WHERE clause? I don't see how it can statically type check these (or can it and I'm missing that?), and I would expect you would want to cache/prepare the query either in the database directly or at least cache the string itself (to avoid rebuilding it every query), however, your values would be different on every query, so why build them together? In summary, the design seems to be:
What I would have expected:
By making it two step build instead of one you don't generate the query every time you execute, you prepare/cache it. Am I missing something? This seems like the obvious design, but I'm assuming you had your reasons. Second, I would like to prepare the SQL statement, not always rebuild it, but apply different values every time. I am planning to just discard the generated Thanks |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
Why SeaQuery does “string + values” every time
fn query(a: Option<i32>, b: Option<char>) -> SelectStatement {
Query::select()
.column("id")
.from("character")
.apply_if(a, |q, v| {
q.and_where(Expr::col("font_id").eq(v));
})
.apply_if(b, |q, v| {
q.and_where(Expr::col("ascii").like(v));
})
.take()
}
assert_eq!(
query(Some(5), Some('A')).to_string(MysqlQueryBuilder),
"SELECT `id` FROM `character` WHERE `font_id` = 5 AND `ascii` LIKE 'A'"
);
assert_eq!(
query(Some(5), None).to_string(MysqlQueryBuilder),
"SELECT `id` FROM `character` WHERE `font_id` = 5"
);
assert_eq!(
query(None, None).to_string(MysqlQueryBuilder),
"SELECT `id` FROM `character`"
);Why you can’t just skip values
|
Beta Was this translation helpful? Give feedback.
-
|
Thanks for this full answer. A few thoughts:
|
Beta Was this translation helpful? Give feedback.
Why SeaQuery does “string + values” every time
String building is cheap: Constructing the SQL string is not the bottleneck. Database drivers already have prepared statement caches internally. So even if SeaQuery hands over a fresh (string, values) each time, the driver can reuse the prepared plan under the hood. You don’t pay the full parse cost every time.
AST structural difference: SeaQuery builds queries dynamically. The AST can differ between calls depending on conditions (e.g. optional filters, dynamic joins, conditional WHERE clauses). That makes it tricky to pre‑prepare a single statement and just swap values - because the shape of the query itself may change. Example from readme: