Hibernate使用原生的动态sql实现带条件的查询分页功能

背景

最近在做项目的时候需要使用到分页功能,项目用的框架是JPA,老实说SpringDataJpa的带条件的分页查询功能真的难用。。。所以想到用hibernate的动态SQL来实现算了。

实现步骤

1.在hibernate的配置文件中加实体类(移动要配置,如果没有配置,不会报错,但是就是查询不出来数据)
2.编写dao和daoimpl类(关键)
3.编写2个dto类
4.调用

详细实现步骤

在hibernate的配置文件中加实体类

hibernate在使用中一般会和hibernate整合,整合之后要配置实体类有两种实现方案

1.通过在hibernate.cfg.xml中配置的方式

applicationContext.xml

id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocations">
            <list>
                classpath*:hibernate/**/hibernate.cfg.xml
            list>
        property>

hibernate.cfg.xml




<hibernate-configuration>
    <session-factory>
        <mapping class="com.nantian.man.busi.domain.TCardInfo"/>

    session-factory>
hibernate-configuration>

2.直接在applicationContext.xml配置

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="annotatedClasses"> 
            <list> 
            <value>com.nantian.man.busi.domain.TCardInfovalue> 
            list> 
        property>

编写三个dto

PageModel(包装当前页数和每页显示条数的pojo)

public class PageModel{

    private int pageNo = 1;//当前页
    private int pageSize = 3;//每页显示条数
    //get set方法
}

HibernateQueryModel(包装查询条件,查询实体名字,排序等的POJO)

public class HibernateQueryModel {

    private String tableName;//实体名字

    private Map map;//查询条件

    private String orderColumn;//排序字段

    private String orderType;//排序方式,比如:desc,asc

    private PageModel pageModel;//包装了当前页码和每页显示条数
    //get set方法
}

ReturnPageModel(包装了返回数据的POJO)

public class ReturnPageModel<T> implements Serializable  {
    private static final long serialVersionUID = 1L;
    private int count;//总数
    private int end;//结束的行数
    private long pages;//页数
    private int pageSize;//每页显示行数
    private List list; //返回数据
    private int start;//开始行数
    private long currentPage;//当前页
    //get set方法
}

编写dao和daoimpl类(关键)

dao

public interface HibernateQueryDao {

    ReturnPageModel getByConditionAndPage(HibernateQueryModel hqm);
}

daoimpl

@Repository
public class HibernateQueryDaoImpl<T> extends HibernateDaoSupport implements HibernateQueryDao<T> {

    @Resource  
    public void setMySessionFactory(SessionFactory sessionFactory){  
        super.setSessionFactory(sessionFactory);  
    }  

    /**
     * 条件查询
     *
     */
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public ReturnPageModel getByConditionAndPage(HibernateQueryModel hqm){

        ReturnPageModel page=new ReturnPageModel();

        String sql="from "+hqm.getTableName()+" t where 1=1 ";
        StringBuilder sb=new StringBuilder();

        List paramList=new ArrayList();
        Map querymap = hqm.getMap();
        if(!querymap.isEmpty()){
            for(String key : querymap.keySet()){
                if(StringUtil.isNotEmpty(querymap.get(key))){
                    paramList.add(querymap.get(key));
                    sb.append("and t."+key+"=? ");
                }
            }
        }
        final Object[] objectArr=paramList.toArray();
        final String hql=sql+sb.toString()+"order by t."+hqm.getOrderColumn()+" "+hqm.getOrderType();
        final String sqlcount="select count(*) "+hql;

        logger.info("查询语句为:  ["+hql+"]");
        logger.info("获取数量的查询语句为:["+sqlcount+"]");
        final int pageNo=hqm.getPageModel().getPageNo();
        final int pageSize=hqm.getPageModel().getPageSize();

        //得到总数据
        List list=this.getHibernateTemplate().executeFind(new HibernateCallback(){
            public Object doInHibernate(Session session)
                    throws HibernateException, SQLException {
                Query query=session.createQuery(hql);
                query.setFirstResult((pageNo-1)*pageSize);
                query.setMaxResults(pageSize);
                for(int i=0;ireturn query.list();
        }});

        //得到总条数
        List longlist=this.getHibernateTemplate().executeFind(new HibernateCallback(){
            public Object doInHibernate(Session session)
                    throws HibernateException, SQLException {
                Query query=session.createQuery(sqlcount);
                for(int i=0;ireturn query.list();
        }});

        int count = longlist.get(0).intValue();
        page.setList(list);
        page.setPageSize(pageSize);
        page.setStart(pageNo);
        page.setCount(count);
        int end = (pageNo - 1) * pageSize + pageSize;
        if (count < end) {
            page.setEnd(count);
        } else {
            page.setEnd((pageNo - 1) * pageSize + pageSize);
        }
        return page;
    }
} 
  

如何调用

public void test(){
    //1、判断页码是否正确
    int currentPage = Integer.parseInt(this.getDictionary().getDataMapValue(msgBean.getDataMap(),FieldConfigConstant.CURRENTPAGE));
    int pageSize = Integer.parseInt(this.getDictionary().getDataMapValue(msgBean.getDataMap(),FieldConfigConstant.PAGESIZE));
    if(currentPage<=0){
        currentPage = 1;
    }
    if(pageSize<=0){
        pageSize = 10;
    }
    HibernateQueryModel model = new HibernateQueryModel();
    Map conditionMap = new HashMap();
    PageModel pageModel=new PageModel(currentPage,pageSize);

    Field[] field = TCardInfoPKDto.class.getDeclaredFields();
    for(Field fi:field){
        String name = fi.getName();
        String caseName = name.substring(0,1).toUpperCase()+name.substring(1); //将属性的首字符大写,方便构造
        Method m = tc.getClass().getMethod("get"+caseName);
        Object value = m.invoke(tc);
           if(StringUtil.isNotEmpty(value)){
            conditionMap.put("id."+name, value);
           }
    }

    model.setTableName(TCardInfo.class.getName());
    model.setOrderColumn("id.value");
    model.setOrderType("asc");
    model.setMap(conditionMap);
    model.setPageModel(pageModel);

    ReturnPageModel page = hibernateQueryDaoImpl.getByConditionAndPage(model);
}

你可能感兴趣的:(框架专栏)