<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">今天做了一下测试,测试发现分页中存在一些问题:</span>
分页中的排序效果没有显示出来。首先看下排序中的一些注意的事项:
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order
by "111", 如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
下面的分页是一个关于贴吧的分页处理代码:
TopicController.java
package com.mogu.controller;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.jpush.api.utils.StringUtils;
import com.mogu.common.StatusCode;
import com.mogu.exception.TopicException;
import com.mogu.model.MoguData;
import com.mogu.model.MoguPageData;
import com.mogu.model.Topic;
import com.mogu.service.topic.ITopicService;
import com.mogu.util.Base64Handler;
import com.mogu.util.LoadOfBASE64;
import com.mogu.util.ObjectUtils;
import com.mogu.util.page.PageControlData;
/**
* 是发表文章的Controller类 ClassName:TopicController <br/>
* Date: 2015年3月21日下午3:48:00 <br/>
*
* @author 永文
* @version
* @see
*/
@Controller
@RequestMapping("/topic")
public class TopicController {
Logger logger = Logger.getLogger(Topic.class);
@Resource
ITopicService topicService;
@RequestMapping("/publish")
public @ResponseBody MoguData<Topic> publish(
@RequestBody MoguData<Topic> params) {
MoguData<Topic> moguData = new MoguData<Topic>();
Topic topic = params.getData();
try {
if (!StringUtils.isEmpty(topic.getContent())) {
topic.setContent(URLDecoder.decode(topic.getContent(), "UTF-8"));
}
topic.setPosttime(new Date());
// 对图片进行处理
if (!StringUtils.isEmpty(topic.getImgs())) {
String[] imgs = topic.getImgs().split(",");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < imgs.length; i++) {
if (!StringUtils.isEmpty(imgs[i])) {
String imgUrl = Base64Handler
.getInstance()
.convertBase64DataToImg(imgs[i],
"fileBbsImagePath", "SqlBbsImagePath");
sb.append(imgUrl + ",");
}
}
topic.setImgs(sb.toString());
}
int record = topicService.saveTopic(topic);
if (record > 0) {// 插入成功
moguData.setStatuscode(StatusCode.SUCCESS.value());
moguData.setMessage(StatusCode.errorMsg(StatusCode.SUCCESS
.value()));
}
} catch (TopicException e) {
moguData.setStatuscode(StatusCode.PUBLISH_FAIL.value());
moguData.setMessage(StatusCode.errorMsg(StatusCode.PUBLISH_FAIL
.value()));
return moguData;
} catch (UnsupportedEncodingException e) {
moguData.setStatuscode(StatusCode.PUBLISH_FAIL.value());
moguData.setMessage(StatusCode.errorMsg(StatusCode.PUBLISH_FAIL
.value()));
return moguData;
} catch (IOException e) {
moguData.setStatuscode(StatusCode.PUBLISH_FAIL.value());
moguData.setMessage(StatusCode.errorMsg(StatusCode.PUBLISH_FAIL
.value()));
return moguData;
}
return moguData;
}
/**
* 通过页码、文章类型等来获取数据 Function: TODO. <br/>
* Date: 2015年3月23日上午10:42:10 <br/>
*
* @author 永文
* @version
* @see
*/
@RequestMapping("/getTopicByPage")
public @ResponseBody MoguPageData<List<Topic>> getTopicByPage(
@RequestBody MoguPageData<Topic> params) {
MoguPageData<List<Topic>> moguPageData = new MoguPageData<List<Topic>>();
PageControlData<Topic> po = new PageControlData<Topic>();
Topic ppo = params.getData();
po.setPageSize(params.getPerPageCount());
po.setCurrentPage(params.getCurrentPage());
PageControlData<Topic> pageControlData = null;
try {
pageControlData = topicService.getTopicByPage(ppo, po);
} catch (TopicException e) {
e.printStackTrace();
moguPageData.setMessage(StatusCode
.errorMsg(StatusCode.GAIN_PAGING_FAIL.value()));
moguPageData.setStatuscode(StatusCode.GAIN_PAGING_FAIL.value());
return moguPageData;
}
moguPageData.setData(pageControlData.getResultList());
moguPageData.setStatuscode(StatusCode.SUCCESS.value());
moguPageData
.setMessage(StatusCode.errorMsg(StatusCode.SUCCESS.value()));
return moguPageData;
}
}
package com.mogu.service.topic.impl;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mogu.exception.TopicException;
import com.mogu.mapper.TopicMapper;
import com.mogu.model.Topic;
import com.mogu.model.User;
import com.mogu.service.topic.ITopicService;
import com.mogu.util.LoadOfBASE64;
import com.mogu.util.ObjectUtils;
import com.mogu.util.UrlUtil;
import com.mogu.util.page.PageControlData;
import com.mogu.util.page.PageParam;
@Service
public class TopicServiceImpl implements ITopicService {
Logger logger = Logger.getLogger(TopicServiceImpl.class);
@Resource
TopicMapper topicMapper;
/**
* 确保查询出记录同时更新记录的浏览次数的记录行
*/
@Override
@Transactional
public PageControlData<Topic> getTopicByPage(Topic ppo,
PageControlData<Topic> po) throws TopicException {
PageParam<Topic> pageParam = new PageParam<Topic>(ppo, po);
List<Topic> list = null;
try {
list = topicMapper.pageQuery(pageParam);
if(list.size() == 0){
return po;
}
int updateRecord = topicMapper.updateByTopics(list);
if(list.size() != updateRecord){//说明没有同步更新浏览次数
logger.info("贴吧记录更新失败");
throw new TopicException("贴吧记录更新失败");
}
} catch (SQLException e) {
e.printStackTrace();
logger.info("贴吧记录获取失败"+e.getMessage());
throw new TopicException("贴吧记录获取失败"+e.getMessage());
}
Iterator<Topic> iterator = list.iterator();
Topic topic = null;
User user = null;
UrlUtil urlUtil = UrlUtil.getInstance();
while(iterator.hasNext()){
topic = iterator.next();
String string = topic.getImgs();
StringBuffer sb= null;
if(ObjectUtils.validateString(string)){
sb = new StringBuffer();
String[] strArr = string.split(",");
for(int i = 0 ; i < strArr.length; i ++){
if(ObjectUtils.validateString(strArr[i])){
if(i ==strArr.length-1)
sb.append(urlUtil .getAbsoluteUrl(strArr[i]));
else
sb.append(urlUtil .getAbsoluteUrl(strArr[i])+",");
}
}
topic.setImgs(sb.toString());
}
//对用户图像进行处理
user = topic.getUser();
user.setImg(urlUtil.getAbsoluteUrl(user.getImg()));
}
po.setResultList(list);
return po;
}
@Override
public int saveTopic(Topic topic) throws TopicException {
try {
return topicMapper.insert(topic);
} catch (SQLException e) {
e.printStackTrace();
throw new TopicException("发表贴吧失败!"+e.getMessage());
}
}
}
PageControlData.java
package com.mogu.util.page;
import java.io.Serializable;
import java.util.List;
/**
* 版权所有:@copy; 2004 ZTE Corporation.版权所有.
* 文件编号:M00_PageControlData.java
* 文件名称:PageControlData.java
* 系统编号:Z0001001
* 系统名称:市场营销管理系统(系统用户)
* 模块编号:M02
* 模块名称:项目管理
* 设计文件:M02_PU02项目管理设计模型.cat,M02_PU02项目管理用例设计.cat
* 完成日期:
* 作 者:
* 内容摘要:项目管理基础页面类
*/
public class PageControlData<T> implements Serializable{
private static final long serialVersionUID = 1L;
//默认页面尺寸
private static final int DEFULT_PAGE_SIZE = 10;
/**
* 原始的结果的列表
*/
private List<T> resultList;
/**
* 页面总数
*/
private int pageCount;
/**
* 当前页面序号
*/
private int currentPage;
/**
* 总记录条数
*/
private int resultCount;
/**
* 页面尺寸
*/
private int pageSize = DEFULT_PAGE_SIZE;
/**
* 跳转到的页面序号
*/
private int changePageNumber;
/**
* 起始的记录序号
*/
private int startRowNum;
/**
* 终了记录序号
*/
private int endRowNum;
/**
* 描述:用于排序的对象
*/
private SortData sort;
public PageControlData() {
}
/**
* 方法名称: init
* 内容摘要: 初始化分页对象
*/
public void init()
{
//初始化页面总数
pageCount = 0;
//初始化当前页面序号
currentPage = 0;
//初始化总记录条数
resultCount = 0;
//初始化页面尺寸
pageSize = DEFULT_PAGE_SIZE;
}
/**
* Access method for the resultList property.
*
* @return the current value of the resultList property
*/
public List<T> getResultList()
{
return resultList;
}
/**
* Sets the value of the resultList property.
*
* @param aResultList the new value of the resultList property
*/
public void setResultList(List<T> aResultList)
{
resultList = aResultList;
}
/**
* Access method for the pageCount property.
*
* @return the current value of the pageCount property
*/
public int getPageCount()
{
//判断记录总数是否能整除页尺寸
if (resultCount % pageSize == 0)
{
//整除则直接取整相除
pageCount = (resultCount / pageSize);
}
else
{
//否则取整相除后加一
pageCount = (resultCount / pageSize) + 1;
}
return pageCount;
}
/**
* Sets the value of the pageCount property.
*
* @param aPageCount the new value of the pageCount property
*/
public void setPageCount(int aPageCount)
{
pageCount = aPageCount;
}
/**
* Access method for the currentPage property.
*
* @return the current value of the currentPage property
*/
public int getCurrentPage()
{
// 判断总记录数大于零且当前也是小于一的情况
if (currentPage < 1 && resultCount > 0)
{
currentPage = 1;
}
//判断当前页序号是否溢出
if (currentPage > getPageCount())
{
currentPage = pageCount;
}
return currentPage;
}
/**
* Sets the value of the currentPage property.
*
* @param aCurrentPage the new value of the currentPage property
*/
public void setCurrentPage(int aCurrentPage)
{
//设置当前页序号、小于零的情况忽略
if(aCurrentPage >= 0)
{
currentPage = aCurrentPage;
}
}
/**
* Access method for the resultCount property.
*
* @return the current value of the resultCount property
*/
public int getResultCount()
{
return resultCount;
}
/**
* Sets the value of the resultCount property.
*
* @param aResultCount the new value of the resultCount property
*/
public void setResultCount(int aResultCount)
{
//设置总记录条数
resultCount = aResultCount;
}
/**
* Access method for the pageSize property.
*
* @return the current value of the pageSize property
*/
public int getPageSize()
{
return pageSize;
}
/**
* Sets the value of the pageSize property.
*
* @param aPageSize the new value of the pageSize property
*/
public void setPageSize(int aPageSize)
{
pageSize = aPageSize;
}
/**
* Access method for the changePageNumber property.
*
* @return the current value of the changePageNumber property
*/
public int getChangePageNumber()
{
return changePageNumber;
}
/**
* Sets the value of the changePageNumber property.
*
* @param aChangePageNumber the new value of the changePageNumber property
*/
public void setChangePageNumber(int aChangePageNumber)
{
//设置跳转到的页面序号
changePageNumber = aChangePageNumber;
//设置当前页序号
setCurrentPage(changePageNumber);
}
/**
* Determines if the isFirstPage property is true.
*
* @return <code>true<code> if the isFirstPage property is true
*/
public boolean getIsFirstPage()
{
return currentPage <= 1 ? true : false;
}
/**
* Determines if the isLastPage property is true.
*
* @return <code>true<code> if the isLastPage property is true
*/
public boolean getIsLastPage()
{
return pageCount <= currentPage ? true : false;
}
/**
* Access method for the startRowNum property.
*
* @return the current value of the startRowNum property
*/
public int getStartRowNum()
{
//判断记录总数是否能整除页尺寸
if (currentPage > getPageCount())
{
currentPage = pageCount;
}
return ((currentPage - 1) * pageSize > 0 ? (currentPage - 1) * pageSize : 0);
}
/**
* Access method for the endRowNum property.
*
* @return the current value of the endRowNum property
*/
public int getEndRowNum()
{
//判断记录总数是否能整除页尺寸
if (currentPage > getPageCount())
{
currentPage = pageCount;
}
//如果当前页小于一则结束序号为页面大小,否则按公式计算
return (currentPage - 1) > 0 ? (currentPage - 1) * pageSize + pageSize : pageSize;
}
/**
* Sets the value of the startRowNum property.
*
* @param aStartRowNum the new value of the startRowNum property
*/
public void setStartRowNum(int aStartRowNum)
{
startRowNum = aStartRowNum;
}
/**
* Sets the value of the endRowNum property.
*
* @param aEndRowNum the new value of the endRowNum property
*/
public void setEndRowNum(int aEndRowNum)
{
endRowNum = aEndRowNum;
}
//获取当前页面记录数
public int getPageDataCount(){
if(resultList != null)
return resultList.size();
else
return 0;
}
public SortData getSort() {
return sort;
}
public void setSort(SortData sort) {
this.sort = sort;
}
}
/**
*
*/
package com.mogu.util.page;
import java.util.HashMap;
/**
* @author chenh
* @date 2013年9月3日
*/
@SuppressWarnings("serial")
public class PageParam<T> extends HashMap<String,Object>{
private static final String KEY_PO = "po";
private static final String KEY_PAGE = "page";
public PageParam(){
super();
}
public PageParam(Object t,PageControlData<T> page){
this.put(KEY_PO,t);
this.put(KEY_PAGE, page);
}
@SuppressWarnings("unchecked")
public T getParamObject(){
return (T)this.get(KEY_PO);
}
@SuppressWarnings("unchecked")
public PageControlData<T> getPage(){
return (PageControlData<T>)this.get(KEY_PAGE);
}
}
/**
*
*/
package com.mogu.util.page;
/**
* @author chenh
* @date 2013年9月5日
*/
public class MysqlPageHandler implements PageHandler{
public String handlerCountSql(String sql) {
return "select count(*) from ("+sql+") as total";
}
public String handlerPageSql(String sql) {
return sql+" limit ?,?";
}
}
/**
*
*/
package com.mogu.util.page;
/**
* @author chenh
* @date 2013年9月3日
*/
public class OraclePageHandler implements PageHandler{
public String handlerCountSql(String sql) {
return "SELECT COUNT(*) FROM ("+sql+")";
}
public String handlerPageSql(String sql) {
return "SELECT * FROM "
+ "(WITH RESULTTABLE AS ( "+sql+") SELECT ROWNUM AS ROW_NUM,R.* FROM RESULTTABLE R) PAGERESULT "
+ "WHERE PAGERESULT.ROW_NUM >? AND PAGERESULT.ROW_NUM <=?";
}
}
/**
*
*/
package com.mogu.util.page;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMapping.Builder;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.log4j.Logger;
/**
* @author chenh
* @date 2013年9月2日
*/
@Intercepts({@Signature(type= StatementHandler.class,method = "prepare",args = {Connection.class})})
@SuppressWarnings("unchecked")
public class PageInterceptor implements Interceptor{
private PageHandler pageHandler;
public static final Logger logger = Logger.getLogger(PageInterceptor.class);
public Object intercept(Invocation invocation) throws Throwable {
RoutingStatementHandler statementHandler = (RoutingStatementHandler)invocation.getTarget();
BoundSql boundSql = statementHandler.getBoundSql();
Object param = boundSql.getParameterObject();
if(param instanceof PageParam){
logger.debug("page query");
PageParam<Object> pageParam =(PageParam<Object>)param;
PageControlData<Object> page = pageParam.getPage();
//ReflectUtil.setFieldValue(boundSql, "parameterObject", pageParam.getParamObject());
Connection connection = (Connection)invocation.getArgs()[0];
String sql = boundSql.getSql();
String sqlCount = pageHandler.handlerCountSql(sql);
logger.debug("sqlCount: "+sqlCount);
//通过反射获取到当前RoutingStatementHandler对象的delegate属性
StatementHandler delegate = (StatementHandler)ReflectUtil.getFieldValue(statementHandler, "delegate");
//通过反射获取delegate父类BaseStatementHandler的mappedStatement属性
MappedStatement mappedStatement = (MappedStatement)ReflectUtil.getFieldValue(delegate, "mappedStatement");
//通过BoundSql获取对应的参数映射
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//利用Configuration、查询记录数的Sql语句countSql、参数映射关系parameterMappings和参数对象page建立查询记录数对应的BoundSql对象。
BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), sqlCount, parameterMappings, param);
//通过mappedStatement、参数对象page和BoundSql对象countBoundSql建立一个用于设定参数的ParameterHandler对象
ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, param, countBoundSql);
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = connection.prepareStatement(sqlCount);
parameterHandler.setParameters(pstmt);
// 之后就是执行获取总记录数的Sql语句和获取结果了。
rs = pstmt.executeQuery();
if (rs.next()) {
int totalRecord = rs.getInt(1);
logger.debug("page query count: "+totalRecord);
page.setResultCount(totalRecord);
}
} catch (SQLException e) {
logger.error(e.getMessage());
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Configuration configuration = (Configuration)ReflectUtil.getFieldValue(delegate, "configuration");
if(!(parameterMappings instanceof ArrayList)){
parameterMappings = new ArrayList<ParameterMapping>();
ReflectUtil.setFieldValue(boundSql, "parameterMappings", parameterMappings);
}
parameterMappings.add(new Builder(configuration, "page.startRowNum", Object.class).build());
//parameterMappings.add(new Builder(configuration, "page.endRowNum", Object.class).build());
parameterMappings.add(new Builder(configuration, "page.pageSize", Object.class).build());
String sqlPage = pageHandler.handlerPageSql(sql);
logger.debug("sqlPage: "+sqlPage);
//利用反射设置当前BoundSql对应的sql属性为我们建立好的分页Sql语句
ReflectUtil.setFieldValue(boundSql, "sql", sqlPage);
}
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
String pageHandlerClass = (String)properties.get("pageHandler");
logger.info("use page handler: "+pageHandlerClass);
try {
pageHandler = (PageHandler)Class.forName(pageHandlerClass).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error(e.getMessage());
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error(e.getMessage());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error(e.getMessage());
}
}
}
package com.mogu.util.page;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.springframework.util.StringUtils;
public class SortData implements Iterable<SortData.OrderData>,Serializable{
private static final long serialVersionUID = 1L;
public static final Direction DEFAULT_DIRECTION = Direction.DESC;
private final List<OrderData> orders;
/**
* @param orders 不能是 null。
*/
public SortData(OrderData... orders) {
this(Arrays.asList(orders));
}
/**
* @param orders 不能是 null,也不能包含 null。
*/
public SortData(List<OrderData> orders) {
if (null == orders || orders.isEmpty()) {
throw new IllegalArgumentException("你必须提供至少一个排序属性!");
}
this.orders = orders;
}
/**
* @param properties 不能是 null,也不能包含 null。
*/
public SortData(String... properties) {
this(DEFAULT_DIRECTION, properties);
}
/**
* @param direction 当direction为null时,默认为DEFAULT_DIRECTION
* @param properties 不能是 null,也不能包含 null或空串
*/
public SortData(Direction direction, String... properties) {
this(direction, properties == null ? new ArrayList<String>() : Arrays.asList(properties));
}
/**
* @param direction
* @param properties
*/
public SortData(Direction direction, List<String> properties) {
if (properties == null || properties.isEmpty()) {
throw new IllegalArgumentException("你必须提供至少一个排序属性!");
}
this.orders = new ArrayList<OrderData>(properties.size());
for (String property : properties) {
this.orders.add(new OrderData(direction, property));
}
}
/**
* 返回由当前Sort与给定sort取并集后的新的Sort。
*
* @param sort 可以为null
* @return
*/
public SortData and(SortData sort) {
if (sort == null) {
return this;
}
ArrayList<OrderData> these = new ArrayList<OrderData>(this.orders);
for (OrderData order : sort) {
these.add(order);
}
return new SortData(these);
}
/**
* 返回给定property的Order对象
*
* @param property
* @return
*/
public OrderData getOrderFor(String property) {
for (OrderData order : this) {
if (order.getProperty().equals(property)) {
return order;
}
}
return null;
}
/*
* (non-Javadoc)
* @see java.lang.Iterable#iterator()
*/
public Iterator<OrderData> iterator() {
return this.orders.iterator();
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof SortData)) {
return false;
}
SortData that = (SortData) obj;
return this.orders.equals(that.orders);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int result = 17;
result = 31 * result + orders.hashCode();
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return StringUtils.collectionToCommaDelimitedString(orders);
}
/**
* 排序方向的枚举类型
*/
public static enum Direction {
ASC, DESC;
/**
* 根据给定值返回相应枚举实例。
*
* @param value
* @return
*/
public static Direction fromString(String value) {
try {
return Direction.valueOf(value.toUpperCase(Locale.US));
} catch (Exception e) {
throw new IllegalArgumentException(String.format("非法的值 '%s' ! 合法的值只能是 “desc”或“asc”(大小写不敏感)。", value), e);
}
}
}
/**
* 排序属性
*/
public static class OrderData implements Serializable {
private static final long serialVersionUID = 1L;
private final Direction direction;
private final String property;
/**
* @param direction 当direction是null时,默认为DEFAULT_DIRECTION
* @param property 不能是null或空串
*/
public OrderData(Direction direction, String property) {
if (!StringUtils.hasText(property)) {
throw new IllegalArgumentException("属性不能是null或空串!");
}
this.direction = direction == null ? DEFAULT_DIRECTION : direction;
this.property = property;
}
/**
* @param property 不能是null或空串
*/
public OrderData(String property) {
this(DEFAULT_DIRECTION, property);
}
/**
* 获得当前属性的排序方向。
*
* @return
*/
public Direction getDirection() {
return direction;
}
/**
* 获得当前排序属性的字符串表示。
*
* @return
*/
public String getProperty() {
return property;
}
/**
* 返回当前排序属性是否是增序排序。
*
* @return
*/
public boolean isAscending() {
return this.direction.equals(Direction.ASC);
}
/**
* 根据给定的Direction返回一个新的Order.
*
* @param order
* @return
*/
public OrderData with(Direction order) {
return new OrderData(order, this.property);
}
/**
* 根据给定的properties返回一个新的Sort
*
* @param properties
* @return
*/
public SortData withProperties(String... properties) {
return new SortData(this.direction, properties);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int result = 17;
result = 31 * result + direction.hashCode();
result = 31 * result + property.hashCode();
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof OrderData)) {
return false;
}
OrderData that = (OrderData) obj;
return this.direction.equals(that.direction) && this.property.equals(that.property);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("%s: %s", property, direction);
}
}
public static void main(String[] args) {
SortData sort = new SortData("abc", "kkk", "III");
System.out.println(sort);
}
}
<resultMap type="com.mogu.model.Topic" id="ExtendBaseResultMap">
<association property="user" column="userid" select="selectUser" javaType="com.mogu.model.User"></association>
</resultMap>
<sql id="Base_Column_List" >
id, title, content, imgs, type, userId, posttime, ipAddr, location, phoneType, commentCount,
browseCount, praiseCount, parentId, status, create_time, create_user, update_time,
update_user
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from mogu_user_topic
where id = #{id,jdbcType=INTEGER}
</select>
<!-- 分页查询 -->
<select id="pageQuery" resultMap="ExtendBaseResultMap">
SELECT * FROM mogu_user_topic
<where>
<if test="po.createTime != null">
AND create_time=#{bo.createTime,jdbcType=TIMESTAMP}
</if>
<if test="po.updateTime != null">
AND update_time=#{bo.updateTime,jdbcType=TIMESTAMP}
</if>
</where>
<if test="page.sort != null ">
<foreach collection="page.sort" index="index" item="order">
ORDER BY #{order.property,jdbcType=VARCHAR} #{order.direction,jdbcType=VARCHAR}
</foreach>
</if>
</select>
<select id="selectUser" resultType="com.mogu.model.User" parameterType="java.lang.Integer">
SELECT * FROM mogu_user
WHERE id = #{id,jdbcType=INTEGER}
</select>1.种
<if test="page.sort != null ">
<foreach collection="page.sort" index="index" item="order"> <pre name="code" class="java"> ORDER BY #{order.property,jdbcType=VARCHAR} #{order.direction,jdbcType=VARCHAR} </foreach></if>
<pre name="code" class="java"> <if test="page.sort != null ">
<foreach collection="page.sort" index="index" item="order"> <pre name="code" class="java"> ORDER BY #{order.property} #{order.direction} </foreach></if>
2.种
<if test="page.sort != null ">
<foreach collection="page.sort" index="index" item="order">
ORDER BY ${order.property} ${order.direction}
</foreach>
</if>2015-04-01 17:00:07,736 [main] DEBUG org.mybatis.spring.SqlSessionUtils -Creating a new SqlSession 2015-04-01 17:00:07,743 [main] DEBUG org.mybatis.spring.SqlSessionUtils -Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3fe45b09] 2015-04-01 17:00:07,843 [main] DEBUG ing.transaction.SpringManagedTransaction -JDBC Connection [jdbc:mysql://120.24.245.201:3306/mogubrothers?useUnicode=true&characterEncoding=utf8, UserName=root@113.116.86.173, MySQL-AB JDBC Driver] will be managed by Spring 2015-04-01 17:00:07,850 [main] DEBUG com.mogu.mapper.TopicMapper.pageQuery -ooo Using Connection [jdbc:mysql://120.24.245.201:3306/mogubrothers?useUnicode=true&characterEncoding=utf8, UserName=root@113.116.86.173, MySQL-AB JDBC Driver] 2015-04-01 17:00:07,857 [main] DEBUG com.mogu.util.page.PageInterceptor -page query 2015-04-01 17:00:07,857 [main] DEBUG com.mogu.util.page.PageInterceptor -sqlCount: select count(*) from (SELECT * FROM mogu_user_topic ORDER BY ? ?) as total 2015-04-01 17:00:07,858 [main] DEBUG com.mogu.mapper.TopicMapper.pageQuery -==> Preparing: select count(*) from (SELECT * FROM mogu_user_topic ORDER BY ? ?) as total 2015-04-01 17:00:07,930 [main] DEBUG com.mogu.mapper.TopicMapper.pageQuery -==> Parameters: null, null 2015-04-01 17:00:07,935 [main] ERROR com.mogu.util.page.PageInterceptor -You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) as total' at line 5 com.mysql.jdbc.exceptions.jdbc4.M
2015-04-01 16:55:43,580 [main] DEBUG org.mybatis.spring.SqlSessionUtils -Creating a new SqlSession 2015-04-01 16:55:43,588 [main] DEBUG org.mybatis.spring.SqlSessionUtils -Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2a1e41f9] 2015-04-01 16:55:43,686 [main] DEBUG ing.transaction.SpringManagedTransaction -JDBC Connection [jdbc:mysql://120.24.245.201:3306/mogubrothers?useUnicode=true&characterEncoding=utf8, UserName=root@113.116.86.173, MySQL-AB JDBC Driver] will be managed by Spring 2015-04-01 16:55:43,693 [main] DEBUG com.mogu.mapper.TopicMapper.pageQuery -ooo Using Connection [jdbc:mysql://120.24.245.201:3306/mogubrothers?useUnicode=true&characterEncoding=utf8, UserName=root@113.116.86.173, MySQL-AB JDBC Driver] 2015-04-01 16:55:43,699 [main] DEBUG com.mogu.util.page.PageInterceptor -page query 2015-04-01 16:55:43,699 [main] DEBUG com.mogu.util.page.PageInterceptor -sqlCount: select count(*) from (SELECT * FROM mogu_user_topic ORDER BY posttime DESC) as total 2015-04-01 16:55:43,701 [main] DEBUG com.mogu.mapper.TopicMapper.pageQuery -==> Preparing: select count(*) from (SELECT * FROM mogu_user_topic ORDER BY posttime DESC) as total 2015-04-01 16:55:43,771 [main] DEBUG com.mogu.mapper.TopicMapper.pageQuery -==> Parameters: 2015-04-01 16:55:43,792 [main] DEBUG com.mogu.util.page.PageInterceptor -page query count: 19 2015-04-01 16:55:43
原文地址:http://blog.csdn.net/u011218159/article/details/44808957