General paging of hibernate

Keywords: Mobile Session Java SQL Hibernate

First of all, look at a business requirement: fuzzy query data by book name and paging function. Usually, you can write the query method as follows, but it is troublesome if there are many query dimensions.

A new BaseDao is written to deal with this problem. The BaseDao code is as follows:

package com.zking.eight.util;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.Session;
import org.hibernate.query.Query;

/**
*/
public class BaseDao {

/**
 * How to assign a value to query
 * @param query
 * @param map
 */
private void setParamter(Query query,Map<String, Object> map) {
	if(map==null||map.size()==0) {//Return directly if no query criteria are passed
		return;
	}
	
	Object value=null;
	for (Entry<String, Object> entry : map.entrySet()) {//Otherwise, the map set is traversed to assign a value to the named parameter
		value=entry.getValue();
		if(value instanceof Collection) {//If the value passed is a set
			query.setParameterList(entry.getKey(), (Collection) value);
		}
		else if(value instanceof Object[]) {//If the value passed is an array
			query.setParameterList(entry.getKey(), (Collection) value);
		}
		else {//If the value passed is of another type
			query.setParameter(entry.getKey(), value);
		}
	}
}

/**
 * How to get the hql statement that queries the total number of records
 * @param hql
 * @return
 */
private String getCountHql(String hql) {
	/*
	 * Because the hql statement might be: select * from Book
	 * 		      Or: select * From Book
	 * Therefore, you need to first change a whole sentence hql to lowercase or uppercase, find the location of from, and then cut down the content after from to assemble the required statement
	 */
	int indexOf = hql.toLowerCase().indexOf("from");
	return "select count(1) from "+hql.substring(indexOf);
}

/**
 * Method to call
 * @param hql
 * @param pageBean
 * @param map
 * @param session
 * @return
 */
public List executeQuery(String hql,PageBean pageBean,Map<String, Object> map,Session session) {
	if(pageBean!=null&&pageBean.isPagination()) {//If paging is required
		String countHql = getCountHql(hql);//hql statement to get the total number of records queried
		Query countQuery = session.createQuery(countHql);
		this.setParamter(countQuery, map);//Assign a value to query
		String total =countQuery.getSingleResult().toString();//Find out the result
		pageBean.setTotal(total);//Assign the result to the total attribute of pageBean
		
		Query pageQuery = session.createQuery(hql);
		this.setParamter(pageQuery, map);
		pageQuery.setFirstResult(pageBean.getStartIndex());
		pageQuery.setMaxResults(pageBean.getRows());
		return pageQuery.list();//Return the result after paging
	}
	else {//If paging is not required
		Query query = session.createQuery(hql);
		this.setParamter(query, map);
		return query.list();
	}
}	

}
PageBean code is as follows:

package com.zking.eight.util;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**

  • Paging tool class

*/
public class PageBean {

private int page = 1;// Page number

private int rows = 2;// Page size

private int total = 0;// Total number of records

private boolean pagination = true;// Paging
// Get all parameters submitted by foreground to background
private Map<String, String[]> parameterMap;
// Get the url of the last visit to the background
private String url;

/**
 * Initialize pagebean
 * 
 * @param req
 */
public void setRequest(HttpServletRequest req) {
	this.setPage(req.getParameter("page"));
	this.setRows(req.getParameter("rows"));
	// Only when pagination=false is filled in the jsp page, pagination is not allowed
	this.setPagination(!"fasle".equals(req.getParameter("pagination")));
	this.setParameterMap(req.getParameterMap());
	this.setUrl(req.getRequestURL().toString());
}

public int getMaxPage() {
	return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows + 1;
}

public int nextPage() {
	return this.page < this.getMaxPage() ? this.page + 1 : this.getMaxPage();
}

public int previousPage() {
	return this.page > 1 ? this.page - 1 : 1;
}

public PageBean() {
	super();
}

public int getPage() {
	return page;
}

public void setPage(int page) {
	this.page = page;
}

public void setPage(String page) {
	this.page = StringUtils.isBlank(page) ? this.page : Integer.valueOf(page);
}

public int getRows() {
	return rows;
}

public void setRows(int rows) {
	this.rows = rows;
}

public void setRows(String rows) {
	this.rows = StringUtils.isBlank(rows) ? this.rows : Integer.valueOf(rows);
}

public int getTotal() {
	return total;
}

public void setTotal(int total) {
	this.total = total;
}

public void setTotal(String total) {
	this.total = Integer.parseInt(total);
}

public boolean isPagination() {
	return pagination;
}

public void setPagination(boolean pagination) {
	this.pagination = pagination;
}

public Map<String, String[]> getParameterMap() {
	return parameterMap;
}

public void setParameterMap(Map<String, String[]> parameterMap) {
	this.parameterMap = parameterMap;
}

public String getUrl() {
	return url;
}

public void setUrl(String url) {
	this.url = url;
}

/**
 * Get the subscript of the starting record
 * 
 * @return
 */
public int getStartIndex() {
	return (this.page - 1) * this.rows;
}

@Override
public String toString() {
	return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
			+ ", parameterMap=" + parameterMap + ", url=" + url + "]";
}

}
The StringUtils code is as follows:

package com.zking.eight.util;

public class StringUtils {
//Private constructor, protection class cannot be instantiated externally
private StringUtils() {
}

/**
 * Returns true if the string is equal to null or equal to '' after space removal, false otherwise
 * 
 * @param s
 * @return
 */
public static boolean isBlank(String s) {
	boolean b = false;
	if (null == s || s.trim().equals("")) {
		b = true;
	}
	return b;
}

/**
 * Returns true if the string is not equal to null or is not equal to '' after space removal, false otherwise
 * 
 * @param s
 * @return
 */
public static boolean isNotBlank(String s) {
	return !isBlank(s);
}

}
Then you can inherit BaseDao to make the call

    /**
 * Optimized
 * @param book
 * @param pageBean
 * @return
 */
public List list2(Book book,PageBean pageBean) {
	Session session = SessionFactoryUtil.getSession();
	Transaction transaction = session.beginTransaction();
	String hql="from Book where 1=1";
	Map<String, Object> map=new HashMap<String, Object>();
	if(StringUtils.isNotBlank(book.getBookName())) {
		hql+=" and bookName like :bookName";
		map.put("bookName", "%"+book.getBookName()+"%");
	}
	
	List list = super.executeQuery(hql, pageBean, map, session);
	
	transaction.commit();
	SessionFactoryUtil.closeSession();
	return list;
}

In this way, the code is much simpler.

Using native SQL statements in hibernate

For the functions that hql can't realize, you can consider using native SQL, such as the joint table query of three or more tables. If you use hql, it's not only difficult to configure the relationship, but also to turn SQL into hql, so it's more convenient to use native SQL directly. When you use it, you can call the createSQLQuery(hql) method.

    public List list3() {
	Session session = SessionFactoryUtil.getSession();
	Transaction transaction = session.beginTransaction();
	String hql="select b.book_name,o.order_no,oi.product_id from t_hibernate_book b,t_hibernate_order o,t_hibernate_order_item oi";
	List list = session.createSQLQuery(hql).list();
	
	transaction.commit();
	SessionFactoryUtil.closeSession();
	return list;
}

Posted by kporter.porter on Mon, 09 Dec 2019 16:28:17 -0800