iT邦幫忙

0

程式撈 Db Table 一個或多個條件撈法,function 拆不拆問題

  • 分享至 

  • xImage

請教一下撈取 db 寫作方式問題
當有一個 user 表,內有 name,sex,age,birthday,phone,address,datetime 等多個欄位,可能在不同情境下,會用上述一個或多個欄位撈用戶資料。
目前寫法是在前 db 組語法時,用 if 判斷該參數是否有值或非 0,有就補進去一起撈,好處是只要寫一個 function 滿足各種搜尋條件,缺點是撈 db 這個 function 裡會有許多 if 判斷,不這麼做會產生一堆 function,每次看到一長串 if 就會想,難道就沒有更好做法?

if params.name != "" {
    組語法補 and name = ?
}

if params.sex != "" {
    組語法補 and sex = ?
}

if params.age != 0 {
    組語法補 and age = ?
}

if params.birthday != "" {
    組語法補 and birthday = ?
}

if params.phone != "" {
    組語法補 and phone = ?
}

if params.address != "" {
    組語法補 and = ?
}

if params.startTime != "" {
    組語法補 and dateTime >= ?
}

if params.endTime != "" {
    組語法補 and dateTime < ?
}
.
.
.
.
最後再執行db query,取出資料後
再做一些日期轉換、型別轉換等資料處理,組合成商業邏輯需要的資料結構後 return

使用程式語言 go、php,會用 orm 或 raw sql query

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
pascalchang09
iT邦新手 5 級 ‧ 2023-06-17 09:17:58

如果是我,可能會選擇這些欄位一起撈出來,後續再做業務邏輯相關的判斷

vicentli iT邦研究生 4 級 ‧ 2023-06-17 12:39:56 檢舉

謝謝回應,我沒說明清楚,欄位是都會撈出來,只是撈的時候條件會很多元(補了一下說明),所以要在 repository 寫比較多 if 條件判斷

0
sam0407
iT邦大師 1 級 ‧ 2023-06-17 13:20:53

覺得不好就重構他!!
但重構後不一定會比較好就對了~~

go、php我都不會,但他們都算是物件導向的語言吧?
物件導向有三大特性裡其中之一叫多型(Polymorphism),多型又分為多載(Overloading)和覆寫(Overriding)

多載(Overloading)就是您想要的。

vicentli iT邦研究生 4 級 ‧ 2023-06-17 21:11:32 檢舉

謝謝回應,雖然 go 不算物件導向類型,您說的我會爬文看看

0

我必須說,真的是有很多這種需求

但我不懂你的語言,以C#來說,可以使用Entity來操作
建立查詢條件的class,把查詢條件帶入Function,用EF下Where語法來套,會比SQL語法串接美觀很多

不然一直串SQL其實不是普通的醜又煩XD

商業邏輯記得搬去一個位置集中

vicentli iT邦研究生 4 級 ‧ 2023-06-17 21:16:00 檢舉

謝謝回覆,go 如果用 gorm 也是可以 if 成立後 db.where(name = xxx)這樣寫,應該跟你說的類似?只是不會用 gorm 的就會組的比較煩雜。建立查詢條件的 class 就不太明白了 XDD

0
ckp6250
iT邦好手 1 級 ‧ 2023-06-17 20:52:02

如果是 mysql , 我會這麼寫

Select *
	from user
Where
	name regexp ?
	and sex regexp ?
	and age regexp ?
	and birthday regexp ?
	and phone regexp ?
    and address regexp ?

這樣就不用判斷 != ""

regexp 很好用,有值或無值都適用

看更多先前的回應...收起先前的回應...
vicentli iT邦研究生 4 級 ‧ 2023-06-17 21:19:02 檢舉

感謝回覆,我是頭一次看到這樣的用法,但都 and 多個條件了,如果沒帶其中一個參數,不會掛掉嗎

ckp6250 iT邦好手 1 級 ‧ 2023-06-18 04:48:05 檢舉

沒有參數,就等於是空白了,所以,不會掛掉。

https://n.sfs.tw/content/index/11494

vicentli iT邦研究生 4 級 ‧ 2023-06-18 20:20:45 檢舉

給你個讚

select *
  from xuser
 where xname = coalesce(input_name, xname)
   and sex = coalesce(input_sex, sex)
   and birthday >= coalesce(input_startdate, birthday)
   and birthday <= coalesce(input_enddate, birthday)
	

user,name 是ANSI SQL 保留字,所以我改用xuser,xname. coalesce() 是ANSI SQL 標準函數.

Coalesce 這個還蠻有想法的耶,這會是慣用的方法嗎?

ckp6250 iT邦好手 1 級 ‧ 2023-06-19 21:09:12 檢舉

coalesce 比 regexp 有效率。

vicentli iT邦研究生 4 級 ‧ 2023-06-20 23:17:37 檢舉

哇!又一個完全沒見過的方法,實在太強了!又學到一招,謝謝

0
menghuiguli
iT邦新手 5 級 ‧ 2023-06-21 11:55:22

您可以考虑使用查询构建器(query builder)或 ORM(对象关系映射)来编写更简洁、可维护的代码。

查询构建器是一种 API,它允许您使用方法链来构建 SQL 查询语句,而无需手动编写 SQL 代码。ORM 是一种将数据库表映射到对象的技术,它允许您使用面向对象的方式来操作数据库,而无需直接编写 SQL 代码。

以下是一个使用查询构建器的示例代码片段,用于从 user 表中获取用户数据:

<?php
// 假设 $params 是一个包含搜索参数的关联数组
$params = [
    'name' => 'John',
    'age' => 30,
    'address' => '123 Main St',
    // ...
];

// 构建查询语句
$query = $db->table('user');
foreach ($params as $key => $value) {
    if ($value) {
        $query->where($key, $value);
    }
}
$result = $query->get();
// ...
?>

在上面的示例中,我们使用 Laravel 查询构建器来构建 SQL 查询语句。我们首先将 user 表传递给 table 方法,然后使用 foreach 循环遍历搜索参数,并使用 where 方法根据参数构建查询。最后,我们使用 get 方法执行查询并获取结果。

使用查询构建器,您可以轻松地构建复杂的查询,而不需要编写大量的 SQL 代码。您也可以使用 ORM 来编写更具有表现力和可维护性的代码,这可以提高代码的可读性和可重用性,同时也可以减少代码中的冗余和错误。

我要發表回答

立即登入回答