本人最近有一个问题比较烦恼.
做一个数据查询,必须用到一句复杂的HQL语句查询.(SSH)
1.如果说Service只管对业务逻辑的处理,那么这句复杂的HQL就要写到DAO层,DAO本来只是进行数据读写,现在等于掺入了复杂的业务逻辑查询语句.很不符合DAO本来的作用.
2.如果说DAO层有一个方法,接受String型的HQL,然后在DAO层仅仅执行该HQL,那么HQL就要写到Service层,而Service层又出现了查询数据库的HQL语句.很不符合Service本来的作用.本人现在就是不知道如何是好,应该把这句HQL写到哪里呢?求解决方案!想要批评OO,AOP思想的人请不要发言了!我只想听听大家的意见,认为应该如何处理这件事?HQL应该写到哪一层?

解决方案 »

  1.   

    HQL  当然要写在  DAO 里面了
    直接跟db打交道的 写在 DAO里面比较好
    不管你怎么复杂的 hql 语句,他的返回结果 无非就只有那几种,怎么能说不符合dao的作用呢?
      

  2.   

    想要批评OO,AOP思想的人请不要发言了!
    建议楼主把这个限制给去了,很可能会得到其他意想不到的收获哦。
    目前我也是把扩展的hql/sql写到service层,让service来调用dao。看楼下前辈们的意见。
      

  3.   

    hql放dao出现需要用hql语句来解决业务层问题的话先看看设计是否合理
      

  4.   

    Service层经过复杂的逻辑处理后才出现你要执行的HQL语句,所以HQL语句应该在Service层里面,然后通过调用Dao层的查询方法接收你的HQL语句进行查询,最后再将查询到的结果返回给Service层。
    Service层出现了查询数据库的HQL语句并不说明什么,因为对数据库进行增删改查都在dao层中进行,这时候的HQL语句只是一个字符串而已。如果HQL语句是固定的,不通过Service层的逻辑处理后才确定的话,那么就将HQL语句直接放在Dao层中。个人意见,仅供参考。
      

  5.   

    不是让你接受HQL语句再执行查询 把HQL语句放到方法内部根据参数决定如何查询不是很好么 没有该做什么或者不该做什么 你觉得哪里方便就放到哪里吧 写代码你当是升旗啊 那么多规矩...
      

  6.   

    对了 补充一小下 写到这两个地方  以后有类似的地方是 全都按照这次做的决定统一来 别一会写SERVICE一会写DAO 写哪不重要 重要的是得统一
      

  7.   


    编写上层代码得时候应该有种思想就是:上层是不知道下层具体是怎么实现的,它只知道下层的接口和应该实现的功能。
    这样就能达到各层之间解耦的目的,即使你把下层实现换掉了,上层也无须任何更改,这也是分层的目的。
    如果service层生成了hql语句就说明service层依赖了持久化hibernate,它知道dao层是使用hibernate进行持久的。
    那用不用dao层都毫无意义了,因为当你替换dao持久话机制的化(比如换成ibatis),你还得去修改serivce代码。
      

  8.   

    那就把Hql的条件(wherestr)在service里组装好,再调用dao
      

  9.   


    但是这样的话我就找不到Service层存在的意义了 之前我一直都认为他是负责将视图数据与后台数据转换的场所(SQL语句我也写到这里了) 那大哥您通常都是咋用这个层的呢?
    DAO的话坦白说已经不存在了(如果他只负责接个参数然后查询的话)
      

  10.   

    领域驱动模型中有四层,UI,应用层,领域层,基础层,
    SSH架构通常Spring都与领域层相关的,但JDON上的BANQ说得没错,这样的组合就是面向过程和面向数据库狼狈为奸.
    在领域层里有模型,服务,可能需要一个,工厂构造对象,这些不管它,
    里面有一个叫存储的东西Repository,这负责查询,包装对象,给外面的使用,但不涉及业务.它与DAO这样的基础层交互.
    而领域层的服务Service,DDD里说它不是业务.不管它是不是,它从Repository里得到东西,然后再供应用层,UI调用.
    不管是不是按领域驱动模型设计的,如果这里需要缓存的话,也是在Repository差不多的地方控制.但如果没有缓存,无聊查出这么多东西,然后聚合成一个胖对象,浪费.分层是必要的,分得越细,也越不容易控制,如果OO思想不够,随时都会进入死胡同,自己把自己杀死.总结一句:老板没说改,系统能运行,天塌下来也不用管.
      

  11.   

    我有一个问题。先不管sql语句出现在哪。 面对查询,大家是怎么做的? 假如sql出现在service层,那一个查询应对service里的一个方法吗? 如果是这样,查询的情况太多了。比如:User有三个属性 User.id,  User.name,  User.lastLoginTime  有些时候我们只想使用id查到一个user 那在service里定义一个方法 
    findUserById(Integer id); 有些时候我们又想通过name来找到一个user  于是又有了
    findUserByName(String name);而通过name来查找的时候,有时候希望是精确查找,有时候又希望是模糊(like)查找,又该怎么办?再定义一个方法?
    findUserByLikeName(String name);有些时候我们想找用户最后登录时间大于某个时间的用户:
    findUserByLastLoginTime(lastLoginTime);有些时候我们又想找最后登录时间再一个时间范围的用户,是不是又要加一个查询啊?
    findUserByLastLoginTime(beginTime, endTime);这样是不是太恶心了? 面对各式各样的查询,该怎么设计?
      

  12.   

    我是这样做的:service层把Hql语句需要的元素传给dao,dao把这些元素拼成hql执行,写了个测试代码,大家指正一下:
    package junit;import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;public class MyMap { private List<Map<String, String>> list = new ArrayList<Map<String, String>>();

    public void put(String name, String sign, String value){
    Map<String, String> map = new HashMap<String, String>();
    map.put("name", name);
    map.put("sign", sign);
    map.put("value", value);
    list.add(map);
    }

    public void put(String name, String value){
    this.put(name, "=", value);
    }

    public List<Map<String, String>> getList(){
    return list;
    }

    //dao 层
    public void dao(String jpql,MyMap myMap){
    //generator jpql
    List<Map<String, String>> list = myMap.getList();
    StringBuffer sb = new StringBuffer();
    sb.append(jpql).append(" where ");
    for(Map<String, String> map:list){
    String name = map.get("name");
    String sign = map.get("sign");
    String value = map.get("value");
    sb.append(name).append(" ");
    sb.append(sign).append(" ");
    sb.append(value).append(" ");
    sb.append("and ");
    }
    sb.delete(sb.length()-4, sb.length());
    String jpqlOK = sb.toString();
    System.out.println(jpqlOK);
    }

    //service 层
    public void service(){

    String jpql = "select u from Users u";
    //查询条件
    MyMap myMap = new MyMap();
    myMap.put("address","a");
    myMap.put("name","like","%www%");

    //调用 DAO
    this.dao(jpql,myMap);

    }

    //test
    public static void main(String[] args) {
    MyMap myMap = new MyMap();
    myMap.service();
    }}