歡迎光臨
每天分享高質量文章

思考,擼一段 SQL ? 還是寫一段程式碼?

以下都為個人思考總結所得,只作為拋磚引玉之說,一定會有不同意見,如果你有不同看法,歡迎拍磚。

記得剛入公司帶我的研發哥們能寫一手漂亮的 SQL,搜尋準確、執行快、效率高。

配合Web專案中的查詢展示資料的需求,基本是分分鐘完成任務。

那段時間基本是仰視的態度,每天都去討教一點手寫 SQL 的要點,翻看一些 SQL 最佳化調整的技巧。

隨後經歷了幾個專案的打磨,不斷去調整公司的框架,發現專案中大段 SQL 出現的機率越來越小。

我不得不停下腳步,開始反思和總結出現這種現象的原因。如果你手上不忙並且感興趣,請聽我慢慢道來。

下麵是一個經典的系統許可權資料庫設計,作為例子來展開論述。

img

組織機構、使用者、角色、選單作為4個主要設計物件,新增三張兩兩關係對映表。

能很好的做到水平和縱向擴充套件,其中主要設計物件我只添加了幾個需要的欄位。

該設計完全可以引入到你的專案中,根據專案實際使用人群和需求新增必要欄位。

然後配合 Shiro 或者 Spring -Security 能很完美的解決組織使用者角色選單的許可權問題。

言歸正傳,專案需求中有這個一個要求,需要推送當前使用者所有的選單項,SQL寫法。

      select a.uuid,a.name
        from menu a
        left join role_menu b
        on a.uuid = b.menuid
        left join role_user c
        on b.roleid = c.roleid
        where c.userid = '使用者uuid';

你需要在資料庫中執行好,貼上到你的程式碼中,使用資料訪問物件去資料庫執行該SQL獲取資料。

下麵看段相同邏輯的面向物件程式碼邏輯。

        RoleUserPO roleUserPO = roleService.findUserRoleByUserId("使用者ID");
        if (roleUserPO == null) {
            return "當前使用者沒有設定角色!";
        }

        List roleMenuPOs = roleService.findRoleMenusByRoleId(roleUserPO.getRoleid());
        if (roleMenuPOs == null) {
            return "當使用者所在角色沒有設定選單!";
        }

        List menuPOLis = new ArrayList();
        for (RoleMenuPO roleMenuPO : roleMenuPOs) {
            menuPOLis.add(menuService.findMenuById(roleMenuPO.getMenuid()));
        }
        return menuPOLis;

上面這例子放在這裡這樣一對比是不是有感覺了,如果還不夠強烈請在往下看看。

專案需求中同樣也有一個這樣的要求,需要羅列特定角色在特定部門下的使用者,SQL 寫法。

select a.*
  from user a
  LEFT JOIN role_user b
    on a.UUID = b.userid
  LEFT JOIN orga_user c
    on a.uuid = c.userid
 where b.ROLEID = 'c9845b33973511e6acede16e8241c0fe'
   and c.ORGAID = '75284c22973211e6acede16e8241c0fe'

同樣擼段相同邏輯的面向物件程式碼邏輯。

        List userPO1s = roleService.findUsersByRoleId("角色ID");
        if (userPO1s == null) {
            return "當前角色沒有新增使用者!";
        }

        List userPO2s = orgaService.findUsersByOrgaId("組織機構ID");
        if (userPO2s == null) {
            return "當前機構沒有新增使用者!";
        }

        List userPOList = new ArrayList();
        for (UserPO userPO1 : userPO1s) {
            for (UserPO userPO2 : userPO2s) {
                if (userPO1.getUuid().equals(userPO2.getUuid())) {
                    userPOList.add(userPO1);
                    break;
                }
            }
        }
        return userPOList;

有沒有感覺出面向物件程式碼邏輯不僅讀起來簡單,而且能很清楚的提示出錯的原因。

而且現在主流的資料庫還是面向關係的,而程式語言已經從面向過程發展為面向物件。

也就是說兩者完全不搭調,也就是現在 ORM 框架不斷壯大的原因,程式設計中需要將資料表作為物件去對待和處理。

程式碼中出現大段 SQL 與面向物件的設計思路完全是背道而馳。

如果查詢 SQL 出現問題,將後臺列印的 SQL  貼上到 SQL 執行工具中去執行,分析原因,兩個工具切來切去,你不覺得費勁麼?

這應該就是後續我接觸的專案,SQL 減少的主要原因,我們喜歡在一個面向物件的頻道去程式設計。

好了,就這樣吧。以上都為個人思考總結所得,只作為拋磚引玉之說,如果你有不同意見,歡迎拍磚。

已同步到看一看
贊(0)

分享創造快樂