記得剛入公司帶個人研發哥們能寫一手漂亮的 SQL,搜索準確、執行快、效率高。html
配合Web項目中的查詢展現數據的需求,基本是分分鐘完成任務。java
那段時間基本是仰視的態度,天天都去討教一點手寫 SQL 的要點,翻看一些 SQL 優化調整的技巧。數據庫
隨着積累和實踐,SQL 水平提升的很快,同時也寫了不少,有興趣的能夠看看:http://www.cnblogs.com/編程
隨後經歷了幾個項目的打磨,不斷去調整公司的框架,發現項目中大段 SQL 出現的機率愈來愈小。框架
我不得不停下腳步,開始反思和總結出現這種現象的緣由。若是你手上不忙而且感興趣,請聽我慢慢道來。數據庫設計
下面是一個經典的系統權限數據庫設計,做爲例子來展開論述。編程語言
組織機構、用戶、角色、菜單做爲4個主要設計對象,添加三張兩兩關係映射表。工具
能很好的作到水平和縱向擴展,其中主要設計對象我只添加了幾個須要的字段。優化
該設計徹底能夠引入到你的項目中,根據項目實際使用人羣和需求添加必要字段。ui
而後配合 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<RoleMenuPO> roleMenuPOs = roleService.findRoleMenusByRoleId(roleUserPO.getRoleid()); if (roleMenuPOs == null) { return "當用戶所在角色沒有設置菜單!"; } List<MenuPO> menuPOLis = new ArrayList<MenuPO>(); 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<UserPO> userPO1s = roleService.findUsersByRoleId("角色ID"); if (userPO1s == null) { return "當前角色沒有添加用戶!"; } List<UserPO> userPO2s = orgaService.findUsersByOrgaId("組織機構ID"); if (userPO2s == null) { return "當前機構沒有添加用戶!"; } List<UserPO> userPOList = new ArrayList<UserPO>(); 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 減小的主要緣由,咱們喜歡在一個面向對象的頻道去編程。
好了,就這樣吧。以上都爲我的思考總結所得,只做爲拋磚引玉之說,若是你有不一樣意見,歡迎拍磚。