该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-09-01
我最早都是用得QBC,很好用
后来用公司框架后改用HQL了 |
|
返回顶楼 | |
发表时间:2008-09-01
主要是还是公司过分得封装,使得代码的灵活性变差了
|
|
返回顶楼 | |
发表时间:2008-09-01
zrq 写道 Hibernate 的Cirteria 本意是好的,但在实际项目中,最好别用它,因为实际项目中的查询大部分是复杂查询。我给大家介绍一个我认为最好的方法,iBatis 还是太难用了。
1 要用HQL或者 native SQL; 2.要解决参数的占位符问题; 3.要解决动态HQL或SQL问题; 4.要解决数据库表到对象的映射问题。 第二条方案 用named parameter,need to prprocess the sql statement. 第三条方案,用Velocity 或者FreeMarker 模板解决。 第四条方案,用JAVA Reflection 自动映射。 例子: SELECT FIRST_NAME firstName ,LAST_NAME lastName from users u where 1=1 #if($firstName) and u.first_name like #{firstName} #end #if($lastName) and u.last_name like #{lastName} #end Java code: Map map=new HashMap(); map.put("firstName",u.firstName); map.put("lastName", u.lastName); List<UserVO> userList=dao.findList(map, "yourSQLName",UserVO.class); 用模板还是等于封装了一层,换汤不换药,而且得不到IDE良好的支持,编译期检查也没有。感觉这个复杂度用动态语言或者未来的Java7降低,效果能更好一点,我指代码的开发、调试和修改效率。其实在Java里用几个if没啥不好,很多情况,每个if中处理都是不太一样的,一定要刻意的提炼成一套东西(相当于再封装一层)实在没有太大必要。 |
|
返回顶楼 | |
发表时间:2008-09-01
ray_linn 写道 movingboy 写道 ray_linn 写道 浪费这么多行代码,做的都是无用功。
能否请你说明一下为何你认为这么做是浪费,是做无用功?对于文中提到的问题,你会怎么解决呢? 连基本的查询方式in range, (26<会员.age<35)都没办法做到,是不是毫无价值? 要解决这个问题很简单,我写个HSQLTemplate <dynamic-query name="memberList"> from Member m where [#Mix<m.age<#Max] and (m.salary>#salary) and [m.city in (@city)] and m.gender=#gender </dynamic-query> # 代表变量, @代表集合,[] 代表若变量为null,则该条件被忽略。俺只需要把HSQLTemplate注入DAO中,接受一个Map作为参数就可以完成HSQL的自动拼装。 这样的HSQL生成器不难吧? 这样的查询不过分吧?包括了in range和in list 你的QBE根本就做不到,就是做到了也是麻烦得不得了。 受教了,多谢指点。 |
|
返回顶楼 | |
发表时间:2008-09-02
Quake Wang 写道 根据用户输入,动态创建查询是很常见的需求,但是Query By Example只能解决简单的属性对比,正如同你说的,between查询或者一个in查询都是很麻烦的。
Query By Criterion是解决这种需求的最好方法,你需要实现的只是一个将用户输入转化成动态创建Criterion的通用方法,能够将map或者list之类容器中的值转化即可: ["eq", "propertyName", "abc"], ["between", "propertyName", "lo", "hi"], ["in", "propertyName", [1, 2, 3]] => Restrictions.eq and Restrictions.between and Restrictions.in Restrictions只是对各种Criterion实现的提供了静态方法调用,你也可以直接实现一个map/list => criterion的转化方法。 /** * 根据Map获得多个SizeExpression */ public static List<SizeExpression> map(Map<String, Object> map, String op) { List<SizeExpression> list = new ArrayList<SimpleExpression>(); for (String key : map.keySet()) { list.add(new SizeExpression(key, map.get(key), op)); } return list; } |
|
返回顶楼 | |
发表时间:2008-09-02
ice123456 写道 Quake Wang 写道 根据用户输入,动态创建查询是很常见的需求,但是Query By Example只能解决简单的属性对比,正如同你说的,between查询或者一个in查询都是很麻烦的。
Query By Criterion是解决这种需求的最好方法,你需要实现的只是一个将用户输入转化成动态创建Criterion的通用方法,能够将map或者list之类容器中的值转化即可: ["eq", "propertyName", "abc"], ["between", "propertyName", "lo", "hi"], ["in", "propertyName", [1, 2, 3]] => Restrictions.eq and Restrictions.between and Restrictions.in Restrictions只是对各种Criterion实现的提供了静态方法调用,你也可以直接实现一个map/list => criterion的转化方法。 /** * 根据Map获得多个SizeExpression */ public static List<SizeExpression> map(Map<String, Object> map, String op) { List<SizeExpression> list = new ArrayList<SimpleExpression>(); for (String key : map.keySet()) { list.add(new SizeExpression(key, map.get(key), op)); } return list; } 你这段代码是打算实现“一个map/list => criterion的转化方法”吗?我有三个疑问: 1.按照Quake Wang的建议,这个map或list中的每一项都包含一个操作符、一个属性名称及一或多个操作数,但你的代码中针对该map中所有项都使用了同一个操作符 2.你的代码中有一行 List<SizeExpression> list = new ArrayList<SimpleExpression>(); SizeExpression和SimpleExpression是不同的类型,ArrayList<SimpleExpression>可以转型为List<SizeExpression>吗?个人猜测代码中的SizeExpression应该都换成SimpleExpression,不知道对不对? 3.按照你的思路,似乎还是无法解决between和in操作的问题(我看了SimpleExpression的源码,看不出来它支持这两种操作) |
|
返回顶楼 | |
发表时间:2008-09-03
ray_linn 写道 movingboy 写道 ray_linn 写道 浪费这么多行代码,做的都是无用功。
能否请你说明一下为何你认为这么做是浪费,是做无用功?对于文中提到的问题,你会怎么解决呢? 连基本的查询方式in range, (26<会员.age<35)都没办法做到,是不是毫无价值? 要解决这个问题很简单,我写个HSQLTemplate <dynamic-query name="memberList"> from Member m where [#Mix<m.age<#Max] and (m.salary>#salary) and [m.city in (@city)] and m.gender=#gender </dynamic-query> # 代表变量, @代表集合,[] 代表若变量为null,则该条件被忽略。俺只需要把HSQLTemplate注入DAO中,接受一个Map作为参数就可以完成HSQL的自动拼装。 这样的HSQL生成器不难吧? 这样的查询不过分吧?包括了in range和in list 你的QBE根本就做不到,就是做到了也是麻烦得不得了。 很早就尝试过将ibates中拼接SQL的代码提取出来,集成到hibernate中做HQL的拼接.貌似ray_linn这个做法也是从ibates中获得的灵感吧.有点古老了,不必以此打击楼主. |
|
返回顶楼 | |
发表时间:2008-09-03
wym0291 写道 很早就尝试过将ibates中拼接SQL的代码提取出来,集成到hibernate中做HQL的拼接.貌似ray_linn这个做法也是从ibates中获得的灵感吧.有点古老了,不必以此打击楼主. 我打击的他的方案,而不是打击他本人。方案得经得住别人的chanllenge。 若是连这点chanllenge都经不住,就不用来论坛发贴了。 ps: 我只返回一个namedparam给hibernate,设参数的工作还是让hibernate自己去完成。 |
|
返回顶楼 | |
发表时间:2008-09-03
qbc是不是不能实现having子句?
我以前问过 一直没人回答 |
|
返回顶楼 | |
发表时间:2008-09-03
laiseeme 写道 qbc是不是不能实现having子句?
我以前问过 一直没人回答 不能,100%肯定。请用HQL。 3.2.6之后的版本我不知道。 |
|
返回顶楼 | |