DSL风格数据库编程之实践

原创
2015/03/12 12:20
阅读数 2.8K

现在的应用系统中,绝多多数的情况下都是要用到数据库的,而适合Java框架的数据库处理方案太多了,这里就不一一列出了。

现在又比较流行一种DSL(Domain Specific Language)风格的数据库访问方式,比如:JOOQ、Querydsl等等,都比较成熟。仔细研究了一下,觉得存在如下问题:这两货都是收费的,这明显不符合时代潮流么;第二就是有点过度封装的意思,有许多东西都封装了,导致学习及使用成本上升;再就是体量都比较大,能不能又瘦又小又好用?
当然,也有一些同学有自己的实现,不能一一研究并列举,今天仅做验证性开发,不足之处同学们尽快提出来,只要合情合理,我们都会采纳。

OK,说做就做,花点时间看看,可不可以自己做个实现?

删除代码示例

delete(USER).where(
                USER.NAME.eq("悠然")
        );
        delete(USER).where(
                USER.NAME.leftLike("A"),
                USER.AGE.between(20,30)
        );



插入代码示例

insertInto(USER).values(
                USER.NAME.value("悠然"),
                USER.AGE.value(22)
        );



更新代码示例

update(USER).set(
                USER.NAME.to("abc"),
                USER.AGE.to(3)
        ).where(
                USER.NAME.eq("悠然")
        );



查询代码示例

selectFrom(USER);

        select(
                customField("%s-%s"),
                USER.NAME,USER.AGE
        ).from(USER);

        select(
                customField("upper(%s)-%s"),
                USER.NAME,USER.AGE
        ).from(USER);

        selectFrom(USER).orderBy(USER.NAME.desc());

        selectFrom(USER).where(
                USER.NAME.eq("abc")
        );

        selectFrom(USER).where(
                USER.NAME.like("abc")
        );

        selectFrom(USER).where(
                or(
                        USER.NAME.like("abc"),
                        USER.AGE.gt(20)
                )
        );

        selectFrom(USER).where(
                USER.AGE.gt(20).and(
                        USER.NAME.like("abc"),
                        USER.AGE.gt(20)
                )
        );
        
        selectFrom(USER).where(
                USER.NAME.leftLike("abc")
        );
        
        selectFrom(USER).where(
                USER.AGE.between(23, 25)
        );
        
        select(USER.AGE.max()).from(USER);
        select(USER.AGE.min()).from(USER);
        select(USER.AGE.avg()).from(USER);
        select(USER.AGE.count()).from(USER);
        select(USER.AGE.sum()).from(USER);
        select(USER.NAME.distinct()).from(USER);
        
        select(USER.AGE.sum()).from(USER).having(
                USER.AGE.sum().gt(100)
        ).union(
                select(USER.AGE.sum()).from(USER).having(
                        USER.AGE.sum().gt(100)
                )
        );



查询是最复杂,也是最多变的,上面已经列举了大多数情况。

总结

通过上面的示例,基本上涵盖了四种SQL语句的处理方式。当然每种方案都有它自己的优点与缺点,正所谓萝卜芹菜各有所爱。

这个方案的优点是把SQL逻辑用有语义的代码进行编写,更容易理解;同时由于其与SQL语句的结构相当相似,也更容易写出相应的SQL逻辑,熟悉SQL的人的学习成本非常低;同时也可以非常好的避免SQL注入问题;较SQL拼接是有相当的改善的。也避免了SQL与Java代码分离导致的开发和调试的不方便。

当然也有它的缺点,比如,经常听到的反对声音就是不如写原生SQL。

完整实现版即将推出。

如果关心Tiny,可以访问Tiny主站:http://www.tinygroup.org,也可以一起加入我们。


展开阅读全文
打赏
0
2 收藏
分享
加载中
79
2016/05/16 17:07
回复
举报
13
2015/03/28 23:06
回复
举报
悠悠然然博主

引用来自“黄亿华”的评论

USER是根据表结构生成的代码么?

是的
2015/03/16 11:35
回复
举报
USER是根据表结构生成的代码么?
2015/03/16 11:07
回复
举报
Hibernate 的 QBC 好像一曲同工啊.
2015/03/16 10:17
回复
举报
更多评论
打赏
5 评论
2 收藏
0
分享
返回顶部
顶部