HQL构建DTO对象来来执行查询

  1. String hql = " select new  com.domain.MyUser(name,passwd) from Users";       
  2. Query query = session.createQuery(hql);    //默认查询出来的list里存放的是一个Object数组,但是在这里list里存放的不再是默认的Object数组了,而是MyUser对象了           
  3. List<MyUser> myUsers = query.list();  

 

使用HQL查询时,若是需要返回单张或多张表的部分信息,而不是返回全部信息时。

 

我们可以事先创建一个DTO(Data Transfer Object 数据传输对象),即一个中间实体类,用来存储我们查询出来的数据,通过 new XXX()这样的方式在HQL语句中使

 

用,前提是在XXX这个类中必须要有接受这些字段的构造方法才行,而且在new的时候必须使用类的全名。这样做的好处是不会暴露服务端表结构,同时返回的结果将不

 

在是一个Object[]数组,而是一个对象(可以通过get,set方便的取值和设值)。

 

创建的DTO:

package com.ezhiyang.shop.entity;

 

import java.io.Serializable;

 

public class HrAssets implements Serializable {

    private static final long serialVersionUID = -8908193318769896828L;

    private Long id;

    private Long totalCount;

    private Long spareCount;

    private Long yuCount;

    private String linkName;

    private String gname;

    private String agent;

    private Boolean isUsed;

 

//无参的构造方法

  public HrAssets() {

    }

//与HQL查询想匹配的构造方法,用来存储获得的数据

  public HrAssets(Long id,String linkName, String gname, String agent,Long totalCount, Long spareCount, Long yuCount) {

        this.id = id;

        this.linkName = linkName;

        this.gname = gname;

        this.agent = agent;

        this.totalCount = totalCount;

        this.spareCount = spareCount;

        this.yuCount = yuCount;

    }

 

    public String getAgent() {

        return agent;

    }

    public void setAgent(String agent) {

        this.agent = agent;

    }

    public Long getTotalCount() {

        return totalCount;

    }

    public void setTotalCount(Long totalCount) {

        this.totalCount = totalCount;

    }

    public Long getSpareCount() {

        return spareCount;

    }

    public void setSpareCount(Long spareCount) {

        this.spareCount = spareCount;

    }

    public Long getYuCount() {

        return yuCount;

    }

    public void setYuCount(Long yuCount) {

        this.yuCount = yuCount;

    }

  

    public Boolean getIsUsed() {

        return isUsed;

    }

    public void setIsUsed(Boolean isUsed) {

        this.isUsed = isUsed;

    }

    public Long getId() {

        return id;

    }

    public void setId(Long id) {

        this.id = id;

    }

    public String getLinkName() {

        return linkName;

    }

    public void setLinkName(String linkName) {

        this.linkName = linkName;

    }

    public String getGname() {

        return gname;

    }

    public void setGname(String gname) {

        this.gname = gname;

    }

}

 

调用的类

package com.ezhiyang.shop.dao.impl;

 

import java.math.BigInteger;

import javax.persistence.FlushModeType;

import javax.persistence.TypedQuery;

import org.apache.commons.lang.StringUtils;

import org.springframework.stereotype.Repository;

import com.ezhiyang.shop.commonentity.Page;

import com.ezhiyang.shop.commonentity.Pageable;

import com.ezhiyang.shop.dao.HrAssetsDao;

import com.ezhiyang.shop.dao.base.impl.BaseDaoImpl;

import com.ezhiyang.shop.entity.ElectronicCardExchangeCode;

import com.ezhiyang.shop.entity.FuliInOutRecord;

import com.ezhiyang.shop.entity.FuliInOutRecord.Type;

import com.ezhiyang.shop.entity.HrAssets;

import com.ezhiyang.shop.entity.Member;

import com.ezhiyang.shop.entity.MemberElectronicCardDetail;

 

@Repository("hrAssetsDaoImpl")

public class HrAssetsDaoImpl extends BaseDaoImpl<ElectronicCardExchangeCode, Long>

        implements HrAssetsDao {

 

    public Page<HrAssets> findPageList(Pageable pageable,String linkName,String name,String agentName) {

        // TODO Auto-generated method stub

 

        // 多表关联查询

        if (pageable == null) {

            pageable = new Pageable();

        }

        StringBuffer sql = new StringBuffer(

                "SELECT COUNT(1) FROM "

                        + "( SELECT     e.id,COUNT(a.id) AS totals, "

                                + "COUNT(    CASE WHEN a.is_used = 0 THEN a.id END ) AS weishiyong, "

                                + "COUNT( CASE WHEN a.is_used = 1 THEN a.id    END) AS yishiyong "

                                +

                                "from  zy_electronic_card_exchange_code a "

                                + " LEFT JOIN zy_electronic_card b on a.electronic_card=b.id "

                                + " LEFT JOIN zy_electronic_card_member c on c.electronic_card =a.electronic_card  and c.electronic_card=b.id"

                                + " LEFT JOIN xx_member d on c.member =d.id "

                                + " LEFT JOIN xx_hr e on d.hr=e.id "

                                + " LEFT JOIN zy_agent f on e.agent=f.id"

                                + " WHERE  b.activity_type=0 ");

 

        if(!StringUtils.isEmpty(linkName)){

            sql=sql.append(" and e.link_name like '%" + linkName + "%'");

        }

 

        if(!StringUtils.isEmpty(name)){

            sql=sql.append(" and e.name like '%" + name + "%'");

        }

 

        if(!StringUtils.isEmpty(agentName)){

            sql=sql.append(" and f.m_name like '%" + agentName + "%'");

        }

 

        sql.append("  GROUP BY e.id ) a ");    

 

        Object con = entityManager.createNativeQuery(sql.toString()).setFlushMode(FlushModeType.COMMIT).getSingleResult();

        BigInteger total = (BigInteger) con;

        int totalPages = (int) Math.ceil((double) total.doubleValue()

                / (double) pageable.getPageSize());

        if (totalPages < pageable.getPageNumber()) {

            pageable.setPageNumber(totalPages);

        }

        sql = new StringBuffer(

                " SELECT  new com.ezhiyang.shop.entity.HrAssets( " +

                "e.id,e.linkName,e.name as gname,f.mName as agent,count(a.id) as totalCount ,sum(case WHEN a.isUsed = 0 THEN 1 else 0 END) as spareCount" +

                ",sum(case WHEN a.isUsed = 1 THEN 1 else 0 END) as yuCount ) from "

                        + "ElectronicCardExchangeCode a,ElectronicCard b,MemberElectronicCard c,Member d,HR e "

                        + "left join e.agent as f "

                        + " where a.electronicCard=c.electronicCard and a.electronicCard=b.id " +

                        "  and c.electronicCard=b.id "

                        + "and  c.member =d.id and d.hr=e.id and b.activityType=0 ");

        if(!StringUtils.isEmpty(linkName)){

            sql=sql.append(" and e.linkName like '%" + linkName + "%'");

        }

 

        if(!StringUtils.isEmpty(name)){

            sql=sql.append(" and e.name like '%" + name + "%'");

        }

 

        if(!StringUtils.isEmpty(agentName)){

            sql=sql.append(" and f.mName like '%" + agentName + "%'");

        }

        sql.append("  GROUP BY e.id ");        

        TypedQuery<HrAssets> query = entityManager.createQuery(sql.toString(),

                HrAssets.class).setFlushMode(FlushModeType.COMMIT);

        query.setFirstResult((pageable.getPageNumber() - 1)* pageable.getPageSize());

        query.setMaxResults(pageable.getPageSize());

        return new Page<HrAssets>(query.getResultList(), total.longValue(),

                pageable);

 

    }

}

 

注:1、用StringBuffer方便语句拼接,便于添加条件;

   2、对于count和sum的数据,在构造方法中一定在注意其类型,此处为Long若使用int或者Integer则会报错;

   3、HQL是面相对象的,直接使用SQL中的case when 语句HQl是无法识别。可以使用如下方法解决。当然使用join也可以弄,这里使用CASE WHEN代码仅用一句SQL:

select 班级,count(case when 分数>=60 then 分数 else null end),count(case when 分数<60 then 分数 else null end)from 表 group by 班级;
    这是问题来了,明明在MYSQL中能够正常得出结果,但是弄到HQL就不行了,会出错!
    后面找了半天终于找到一个解决方法:
 HQL:

   select 班级,sum(case when 分数>=60 then 1 else 0end),sum(case when 分数<60 then 1 else 0 end) from 表group by 班级;

 4、HQL使用left join的方式与SQL是不同的

         from Cat as cat   join cat.mate as mate    left join cat.kittens as kitten

    此处Cat为何实体类,mate为Cat实体类中定义的与其关联的另一个对象,也是一个实体类通过 join  A.B的方式进行关联。还可以通过with增加更过的过滤条件:

       from Cat as cat     left join cat.kittens as kitten         with kitten.bodyWeight > 10.0

 引自: http://www.cnblogs.com/cyjch/archive/2012/03/14/2395340.html

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值