当前位置: 代码迷 >> SQL >> SQL动态打包工具类
  详细解决方案

SQL动态打包工具类

热度:79   发布时间:2016-05-05 13:11:17.0
SQL动态封装工具类
在项目中直接使用jdbc操作的时候,sql的动态条件拼装一直是个非常头疼的事情,前一阵子研究ibatis,发现他的代码生成工具iBATOR生成的example类实际是个很不错的sql拼装类,于是拿过来修改了下,

使用:

            BaseSelector select = new BaseSelector();            select.setCommand("select  from  user ");            select.createCriteria().andEqualTo("org_code", "YZ1201")            .andGreaterThanOrEqualTo("day_code", "2009-01-01")            .andLessThanOrEqualTo("day_code", "2009-03-31");

调用 select.toSql() 输出:
select  from  user where org_code = 'YZ1201' and day_code >= '2009-01-01' and day_code <= '2009-03-31' 


抛砖引玉,有哪位兄弟有更高的拿来看看啊
5 楼 smilebug 2009-07-22  
貌似LZ的这个封装里,order by 没有封装进来吧。
6 楼 wgx19830922 2009-07-22  
用这种形式的话是不是如果参数是带有单引号或者双引号或者其他特殊字符串的时候会有转义错误的!
是不是应该用preparestatement来进行参数的设置呢?
7 楼 duooluu 2009-07-22  
看着累死,我们现在就有这样的工具

妈的,看老代码真的想杀人!
8 楼 surpass 2009-07-22  
也在用String 拼sql的中。
9 楼 fffddd 2009-07-25  
楼主封装的不错。
10 楼 grandboy 2009-07-25  
我最感兴趣的已经After Where 的部分的处理。我现在的框架里就这个没有处理好。我想现在研究一下,把这个加进去。

但是这个拼装,估计还要造一下,用setparameter形式来处理才行。
11 楼 jamiesun 2009-07-25  
smilebug 写道
貌似LZ的这个封装里,order by 没有封装进来吧。


    /**      * 顺序排序      * @param field      */      public void setOrderByClauseAsc(String field) {          this.orderByClause = getFieldName(field) + " ASC";      }            /**      * 倒序排序      * @param field      */      public void setOrderByClauseDesc(String field) {          this.orderByClause = getFieldName(field) + " DESC";      }  
12 楼 luzl 2009-07-26  
duooluu 写道
看着累死,我们现在就有这样的工具

妈的,看老代码真的想杀人!

哈哈,是呀,好好的SQL不用,却要多加一层,看的时候你首先得看懂代码,然后再想象SQL是什么样子,建个bufferstring直接append不就行了吗?,这样也直观,简单就是幸福,简单就是快乐!
13 楼 zouzou 2009-08-11  
是挺不错,不实用
14 楼 kjj 2009-08-12  
luzl 写道
duooluu 写道
看着累死,我们现在就有这样的工具

妈的,看老代码真的想杀人!

哈哈,是呀,好好的SQL不用,却要多加一层,看的时候你首先得看懂代码,然后再想象SQL是什么样子,建个bufferstring直接append不就行了吗?,这样也直观,简单就是幸福,简单就是快乐!


严重同意,这种看着别扭,除了问题调试堆栈有多了几行而已!
15 楼 tangbo530 2009-08-12  
你这个比DBUtils好在哪里?
16 楼 jamiesun 2009-08-13  
kjj 写道
luzl 写道
duooluu 写道
看着累死,我们现在就有这样的工具

妈的,看老代码真的想杀人!

哈哈,是呀,好好的SQL不用,却要多加一层,看的时候你首先得看懂代码,然后再想象SQL是什么样子,建个bufferstring直接append不就行了吗?,这样也直观,简单就是幸福,简单就是快乐!


严重同意,这种看着别扭,除了问题调试堆栈有多了几行而已!


服了你们几个“大牛”,没有人喜欢无中生有的搞事,试想用一堆if else封装一个动态sql的情景吧。

17 楼 tikii 2009-08-17  
jamiesun 写道
kjj 写道
luzl 写道
duooluu 写道
看着累死,我们现在就有这样的工具

妈的,看老代码真的想杀人!

哈哈,是呀,好好的SQL不用,却要多加一层,看的时候你首先得看懂代码,然后再想象SQL是什么样子,建个bufferstring直接append不就行了吗?,这样也直观,简单就是幸福,简单就是快乐!


严重同意,这种看着别扭,除了问题调试堆栈有多了几行而已!


服了你们几个“大牛”,没有人喜欢无中生有的搞事,试想用一堆if else封装一个动态sql的情景吧。


jamiesun 说的没错.

"建个bufferstring直接append不就行了吗"

- 这样在每个需要拼接 sql 的地方就都需要拼接, 拼接逻辑重复了,
  并且没有进行更高层次的封装.
- 如果拼接逻辑有bug, 就要在多个地方改动, 别人要看懂你的代码,
  还是要看懂你的拼接逻辑, 并且还要看懂你每处的拼接逻辑, 因为不知道你每处的
  拼接逻辑是否是一样的;
- 把拼接逻辑封装起来, 减少了代码重复, 并且提高了拼接逻辑的可测试性;
- 应用程序内越一致地使用封装起来的sql拼接逻辑, 就越少让人看得头大的处处
  散落的拼接代码.
- 如果拼接逻辑需要根据应用需要的sql复杂性进行演进, 这只会在一处体现在API
  的变动上, API的变动很易于使用 IDE 的 重构功能来进行.

谢谢 jamiesun 提供这样的封装.
我正着手做这样一件事情, 正好用上了.


18 楼 CodingMouse 2009-09-29  
支持,这些ORM框架的SQL封装思路值得借鉴。
19 楼 mwmw 2009-09-29  
现在已经有很多这种util了吧,忘记叫做什么名字了。

其实用JDBC的时候,拼SQL也是很实惠的,简单明了,安全稳定, 容易检查。 但是不好管理。反正都被封装在DAO这一层。

不过楼主这样一封装,显得就fashion了很多。

ps,一个小问题,最近用substring的时候发现会有memory leak, 如果你要是在这么common的地方用的话,还是注意一点的,不然会有莫名其妙的gc的问题。



20 楼 NanguoCoffee 2009-10-18  
mwmw 写道
现在已经有很多这种util了吧,忘记叫做什么名字了。

其实用JDBC的时候,拼SQL也是很实惠的,简单明了,安全稳定, 容易检查。 但是不好管理。反正都被封装在DAO这一层。

不过楼主这样一封装,显得就fashion了很多。

ps,一个小问题,最近用substring的时候发现会有memory leak, 如果你要是在这么common的地方用的话,还是注意一点的,不然会有莫名其妙的gc的问题。





subString没有创建新的Char Array。和原有的String共有同一个Char Array。是不是这个原因导致的内存泄露?
21 楼 魔力猫咪 2009-10-18  
我在这里推荐我的“仓库猫”框架。
22 楼 Foxswily 2009-10-18  
如果用jdbc封装也就封装了,如果用iBatis完全不用,在xml里做判断比在代码里灵活也直观的多,话说iBatis是自带动态判断的。
23 楼 yuanhuiwu 2010-01-15  
wgx19830922 写道
用这种形式的话是不是如果参数是带有单引号或者双引号或者其他特殊字符串的时候会有转义错误的!
是不是应该用preparestatement来进行参数的设置呢?


LZ 应该考虑使用PrepareStatement来处理,同时order by 也需要

protected List<Sort> sortList;

Sort类至少有两个属性 String field,boolea asc

andEqualTo(String field,String value)中的value定义为Object value

public String toSql(){
...
}
改为
public PrepareStatement getPrepareStatement(){
...
}

另外

createCriteria().andEqualTo("org_code", "vvv")

这里的 "org_code" 写死了,万一数据库字段发生变化,将会很难修改到处使用的 "org_code"

建议使用一些生成工具,生成一个数据库字段的static 类



public class AAAA{

public static class Table1{

   public static String org_code = "org_code";
   ...
}

public static class Table2{

...
}

}

最后,写成 createCriteria().andEqualTo(AAAA.Table1.org_code, value)

数据库字段论怎样变,org_code变成 kao,eclipse会向你举起双手说:"LZ,AAAA.Table1.org_code已经从地球上消失了!"
24 楼 mycybyb 2010-01-15  
呵呵,前几天同事问问题,我就简单给他写了个思路
new Select("select * from user").where(new Condition("col1", EQUAL,  "1"))
  相关解决方案