QueryHelper.java 的代码如下:
package com.ninebot.ad.util;
import java.util.ArrayList;
import java.util.List;
import com.ninebot.ad.core.Dao.BaseDao;
import com.ninebot.ad.page.PageResult;
import com.opensymphony.xwork2.ActionContext;
public class QueryHelper {
//from子句
private String fromClause=""; // FROM子句
//where子句
private String whereClause = ""; // Where子句
//order by子句
private String orderByClause = ""; // OrderBy子句
private List<Object> parameters = new ArrayList<Object>(); // 参数列表
//排序顺序
public static String ORDER_BY_DESC = "DESC";//降序
public static String ORDER_BY_ASC = "ASC";//升序
/**
* 生成From子句
*
* @param clazz 实体类
* @param alias 实体类对应的别名
*/
public QueryHelper(Class clazz, String alias) {
fromClause = "FROM " + clazz.getSimpleName() + " " + alias;
}
/**
* 拼接Where子句
*
* @param condition 查询条件语句;例如:i.title like ?
* @param params 查询条件语句中?对应的查询条件值;例如:
*/
public QueryHelper addCondition(String condition, Object... params) {
// 拼接
if (whereClause.length() > 1) {//非第一个查询条件
whereClause += " AND " + condition;
} else {//第一个查询条件
whereClause = " WHERE " + condition;
}
//设置查询条件值到查询条件值集合中
if (params != null) {
for (Object p : params) {
parameters.add(p);
}
}
return this;
}
/**
* 如果第一个参数为true,则拼接Where子句
*
* @param append
* @param condition
* @param params
*/
public QueryHelper addCondition(boolean append, String condition, Object... params) {
if (append) {
addCondition(condition, params);
}
return this;
}
/**
* 拼接OrderBy子句
*
* @param propertyName
* 参与排序的属性名
* @param order
* 排序
*/
public QueryHelper addOrderProperty(String property, String order) {
if (orderByClause.length() > 1) {
orderByClause += ", " + property +" "+order;
} else {
orderByClause = " ORDER BY " + property +" "+order;
}
return this;
}
/**
* 如果第一个参数为true,则拼接OrderBy子句
*
* @param append 判断是否可以追加的条件
* @param propertyName 属性名
* @param order 排序
*/
public QueryHelper addOrderProperty(boolean append, String propertyName, String order) {
if (append) {
addOrderProperty(propertyName, order);
}
return this;
}
/**
* 获取生成的用于查询数据列表的HQL语句
*
* @return
*/
public String getQueryListHql() {
return fromClause + whereClause + orderByClause;
}
/**
* 获取生成的用于查询总记录数的HQL语句
*
* @return
*/
public String getQueryCountHql() {
return "SELECT COUNT(*) " + fromClause + whereClause;
}
/**
* 获取HQL中的参数值列表
*
* @return
*/
public List<Object> getParameters() {
return parameters;
}
/**
* 查询分页信息,并放到值栈栈顶
*
* @param service //baseDao
* @param pageNum //页数
* @param pageSize //每页数量
*/
public void preparePageBean(BaseDao<?> service, int pageNum, int pageSize) {
PageResult pageResult = service.getPageResult( this,pageNum, pageSize);
ActionContext.getContext().getValueStack().push(pageResult);
}
}
以下三个代码是baseDao中的代码
@Override
public List<T> findObjects(QueryHelper queryHelper) {
Query query = getSession().createQuery(queryHelper.getQueryListHql());
List<Object> parameters = queryHelper.getParameters();
if(parameters != null){
for(int i = 0; i < parameters.size(); i++){
query.setParameter(i, parameters.get(i));
}
}
return query.list();
}
@Override
public long count(QueryHelper queryHelper) {
Query countQuery = getSession().createQuery(queryHelper.getQueryCountHql());
List<Object> parameters = queryHelper.getParameters();
if(parameters != null){
for(int i = 0; i < parameters.size(); i++){
countQuery.setParameter(i, parameters.get(i));
}
}
System.out.println(countQuery+"baseDaoImpl");
return (Long) countQuery.uniqueResult(); // 执行查询;
}
@Override
public PageResult getPageResult(QueryHelper queryHelper, int currentPage, int pageSize) {
System.out.println("-------> DaoSupportImpl.getPageBean( int pageNum, int pageSize, QueryHelper queryHelper )");
// 参数列表
List<Object> parameters = queryHelper.getParameters();
// 查询本页的数据列表
Query listQuery = getSession().createQuery(queryHelper.getQueryListHql()); // 创建查询对象
if (parameters != null) { // 设置参数
for (int i = 0; i < parameters.size(); i++) {
listQuery.setParameter(i, parameters.get(i));
}
}
listQuery.setFirstResult((currentPage - 1) * pageSize);
listQuery.setMaxResults(pageSize);
List list = listQuery.list(); // 执行查询
// 查询总记录数量
Query countQuery = getSession().createQuery(queryHelper.getQueryCountHql());
if (parameters != null) { // 设置参数
for (int i = 0; i < parameters.size(); i++) {
countQuery.setParameter(i, parameters.get(i));
}
}
Long count = (Long) countQuery.uniqueResult(); // 执行查询
return new PageResult(currentPage, pageSize, count, list);
}
问题解惑
对于queryhelper的代码不做过多的讲解,针对自己做的过程中犯得一些疑惑做讲解
1)i.title like ?中它是参照着数据库SQL语句写的还是针对entity对象写的?
答:经过测试是针对entity对象写的
自己在编写软件的时候,所编写的代码如下:
queryHelper.addCondition("i.bus.busId = ?", busId)
.addCondition("i.idate = ?", new SimpleDateFormat("yyyy-MM-dd").parse(idate));
if(inspect!=null && inspect.getInspectId()!=null){//如果不为空就添加查询项
queryHelper.addCondition("i.inspectId != ?",inspect.getInspectId());
}
x = inspectService.count(queryHelper); //获得查询值
2)QueryHelper中的parameters有什么用,没看到类里用它呀?既然没用为什么还要写入代码里?
答:不是没用,而是很有用,QueryHelper是基于query来做的,在SSH框架里,不用QueryHelper,我们在dao层中也需要写入如下代码,以便从数据库中查询出数据来:
Query query = getSession().createQuery(//
"FROM Department WHERE parent_id = ?")//
.setParameter(0, id);
其中就包含setParameter(0, id);
所以在QueryHelper存在parameters,用来存放一段SQL代码中所有的参数,并通过for循环逐个写出。
3)在某些分页显示的过程中没有看到往前端传递列表,分页就实现了,这是为什么?
答:并不是没有传递列表,只是隐含起来了,你没看到,action中的代码你确实看不到,你可以看看baseAction
action中的代码(注:action这段代码是从别的地方拷贝的,其特点就是写的很多,隐藏了传递列表的情况,比较典型)
new QueryHelper(Topic.class, "t")//
// 过滤条件
.addCondition("t.forum=?", forum)//
.addCondition((viewType == 1), "t.type=?", Topic.TYPE_BEST) // 1 表示只看精华帖
// 排序条件
.addOrderProperty((orderBy == 1), "t.lastUpdateTime", asc) // 1 表示只按最后更新时间排序
.addOrderProperty((orderBy == 2), "t.postTime", asc) // 2 表示只按主题发表时间排序
.addOrderProperty((orderBy == 3), "t.replyCount", asc) // 3 表示只按回复数量排序
.addOrderProperty((orderBy == 0), "(CASE t.type WHEN 2 THEN 2 ELSE 0 END)", false)//
.addOrderProperty((orderBy == 0), "t.lastUpdateTime", false) // 0 表示默认排序(所有置顶帖在前面,并按最后更新时间降序排列)
.preparePageBean(topicService, pageNum, pageSize);
这个是BaseAction中的代码
public abstract class BaseAction extends ActionSupport {
protected String[] selectedRow;
protected PageResult pageResult;
protected int pageNum = 1;
protected int pageSize = 10;
//下面是get和set方法 略
看到了吗?通过BaseAction中的pageResult将七个参数传递过去了。
下面是PageResult 的代码,主要就是返回给前端页面结果用的,都隐藏在这里了。
public PageResult( int currentPage,int pageSize, long recordCount,List items) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.recordCount = recordCount;
this.items = items;
// 计算总页码
totalPageCount = (int)((recordCount + pageSize - 1) / pageSize);
// 计算 beginPageIndex 和 endPageIndex
// >> 总页数不多于10页,则全部显示
if (totalPageCount <= 10) {
beginPageIndex = 1;
endPageIndex = totalPageCount;
}
// >> 总页数多于10页,则显示当前页附近的共10个页码
else {
// 当前页附近的共10个页码(前4个 + 当前页 + 后5个)
beginPageIndex = currentPage - 4;
endPageIndex = currentPage + 5;
// 当前面的页码不足4个时,则显示前10个页码
if (beginPageIndex < 1) {
beginPageIndex = 1;
endPageIndex = 10;
}
// 当后面的页码不足5个时,则显示后10个页码
if (endPageIndex > totalPageCount) {
endPageIndex = totalPageCount;
beginPageIndex = totalPageCount - 10 + 1;
}
}
}
PageResult.java的目的就是将送入进去的四个参数,计算出剩余的三个参数。这样就可以通过获得PageResult来获取这七个涉及分页的参数了,其中就包括显示页面内容的list,你没看到,只是隐藏起来了而已。