撸一段 SQL ? 还是撸一段代码?

本文通过具体案例对比了直接编写SQL查询与采用面向对象编程方式处理数据的不同之处,阐述了为何现代项目中直接使用SQL的情况逐渐减少。

   记得刚入公司带我的研发哥们能写一手漂亮的 SQL,搜索准确、执行快、效率高。

   配合Web项目中的查询展示数据的需求,基本是分分钟完成任务。

   那段时间基本是仰视的态度,每天都去讨教一点手写 SQL 的要点,翻看一些 SQL 优化调整的技巧。

   随着积累和实践,SQL 水平提高的很快,同时也写了很多,有兴趣的可以看看:http://www.cnblogs.com/

   随后经历了几个项目的打磨,不断去调整公司的框架,发现项目中大段 SQL 出现的概率越来越小。

   我不得不停下脚步,开始反思和总结出现这种现象的原因。如果你手上不忙并且感兴趣,请听我慢慢道来。

   下面是一个经典的系统权限数据库设计,作为例子来展开论述。

   组织机构、用户、角色、菜单作为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<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 减少的主要原因,我们喜欢在一个面向对象的频道去编程。

  好了,就这样吧。以上都为个人思考总结所得,只作为抛砖引玉之说,如果你有不同意见,欢迎拍砖。

  

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值