Mybatis版PropertyFilter实现

<!--前段时间看到hibernate的PropertyFilter工具类,感觉思想挺不错,项目中用的mybatis,所以
实现了一个mybatis版的PropertyFilter,仅限思想,代码运行可能有错,需要调试-->
    
  <select id="selectInfoPage" resultType="hashmap" parameterType="com.utils.MybatisPropertyFilter" >
 SELECT                                                                                     
*                 
 FROM art_info art
  left join artist artist on art.artist_id = artist.id 
    <include refid="SqlMapper.Example_Where_Clause_None_Order"/>
  </select>
 

 

	
	<sql id="Example_Where_Clause_None_Order">
		<where>
			<foreach collection="oredCriteria" item="criteria" separator="or">
				<if test="criteria.valid">
					<trim prefix="(" suffix=")" prefixOverrides="and">
						<foreach collection="criteria.criteria" item="criterion">
							<choose>
								<when test="criterion.noValue">
									and ${criterion.condition}
								</when>
								<when test="criterion.singleValue">
									and ${criterion.condition} #{criterion.value}
								</when>
								<when test="criterion.betweenValue">
									and ${criterion.condition} #{criterion.value} and
									#{criterion.secondValue}
								</when>
								<when test="criterion.listValue">
									and ${criterion.condition}
									<foreach collection="criterion.value" item="listItem"
										open="(" close=")" separator=",">
										#{listItem}
									</foreach>
								</when>
							</choose>
						</foreach>
					</trim>
				</if>
			</foreach>
		</where>
	</sql>

 

/**
*Mybatis 版 PropertyFilter
*/
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

/**
 * @author Administrator
 *
 */
public class MybatisPropertyFilter {

  private static final Logger logger = LoggerFactory.getLogger(MybatisPropertyFilter.class);

  protected String orderByClause;

  protected boolean distinct;

  protected List<Criteria> oredCriteria;

  public MybatisPropertyFilter(){
    oredCriteria = new ArrayList<Criteria>();
  }


  /**
   * 从HttpRequest中创建PropertyFilter列表
   * PropertyFilter命名规则为Filter属性前缀_比较类型属性类型_属性名.
   *
   * eg.
   * filter_EQS_name
   * filter_LIKES_name_OR_email
   */
  public static MybatisPropertyFilter buildFromHttpRequest(final HttpServletRequest request, final String filterPrefix) {
      MybatisPropertyFilter filter = new MybatisPropertyFilter();
    Map<String, Object> filterParamMap = ServletUtils.getParametersStartingWith(request, filterPrefix + "_");
    for(Map.Entry<String, Object> entry : filterParamMap.entrySet()) {
      String filterName = entry.getKey();
      Object value = entry.getValue();
      String firstPart = StringUtils.substringBefore(filterName, "_");
      String matchTypeCode = StringUtils.substring(firstPart, 0, firstPart.length() - 1);
      String propertyTypeCode = StringUtils.substring(firstPart, firstPart.length() - 1, firstPart.length());
      MatchType matchType = null;
      try {
        matchType = Enum.valueOf(MatchType.class, matchTypeCode);
      } catch(RuntimeException e) {
        throw new IllegalArgumentException("filter名称" + filterName + "没有按规则编写,无法得到属性比较类型.", e);
      }
      Class propertyClass = null;
      try {
        propertyClass = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
      } catch(RuntimeException e) {
        throw new IllegalArgumentException("filter名称" + filterName + "没有按规则编写,无法得到属性值类型.", e);
      }
      if(value instanceof String[]) {
          filter.addCriterion(filterName, value, matchType);
      }else if(StringUtils.isNotBlank((String)value)) {
          filter.addCriterion(filterName, value, matchType);
      }
    }
    return filter;
  }
  /**
   * 向第一组查询条件增加条件
   * @param propertyName 列名称
   * @param propertyValue 列的值
   * @param matchType 条件类型
   */
  public void addCriterion(final String propertyName, final Object propertyValue, final MatchType matchType) {
    addCriterion(propertyName, propertyValue, matchType, 0);
  }
  /**
   * @param propertyFilter
   * @param index 条件所在的组
   */
  public void addCriterion(final String propertyName, final Object propertyValue, final MatchType matchType, int index) {
    if(oredCriteria.size() == 0 || oredCriteria.size()<index || null == oredCriteria.get(index)){
      oredCriteria.add(index, createCriteriaInternal());
    }

    String[] propertyNameStr = StringUtils.splitByWholeSeparator(propertyName, PropertyFilter.OR_SEPARATOR);
    if(propertyNameStr.length>1) {
      Criterion criterion = buildCriterion(propertyName, propertyValue, matchType);
      oredCriteria.get(index).getCriteria().add(criterion);
    }
    else {//如果是OR条件
      StringBuffer sb = new StringBuffer();
      for(String param : propertyNameStr) {
        Criterion criterion = buildCriterion(param, propertyValue, matchType);
        sb.append(" or ").append(criterionToString(criterion)).append(" ");
      }
      if(sb.length() > 0) {
        Criterion criterion = new Criterion(sb.delete(0, 4).insert(0, "( ").append(") ").toString());
        oredCriteria.get(index).getCriteria().add(criterion);
      }
    }

  }

  public enum LikeType {
    /** 左边% */
    LL,
    /** 右边% */
    RL;
  }
  
  protected Criterion buildCriterion(final String propertyName, final Object propertyValue, final MatchType matchType) {
    Assert.hasText(propertyName, "属性名称为空");
    Criterion criterion = null;
    switch(matchType) {
      case EQ:
        if(propertyValue instanceof List<?>) {
          criterion = new Criterion(propertyName + " in ", propertyValue);
        }else if(propertyValue instanceof Object[]) {
          criterion = new Criterion(propertyName + " in ", propertyValue);
        }else {
          criterion = new Criterion(propertyName + " = ", propertyValue);
        }
        break;
      case NE:
        if(propertyValue instanceof List<?>) {
          criterion = new Criterion(propertyName + " not in ", propertyValue);
        }
        else {
          criterion = new Criterion(propertyName + " != ", propertyValue);
        }
        break;
      case LIKE:
        String likePart = StringUtils.substringBefore(propertyName, "_");
        try {
          LikeType likeType = LikeType.valueOf(likePart);
          switch(likeType) {
            case LL:
              criterion = new Criterion(propertyName + " LIKE '%" + propertyValue + "' ");
              break;
            case RL:
              criterion = new Criterion(propertyName + " LIKE '" + propertyValue + "%' ");
              break;
            default:
              criterion = new Criterion(propertyName + " LIKE '%" + propertyValue + "%'");
              break;
          }
        }
        catch(Exception e) {
          logger.debug("{}", e);
          criterion = new Criterion(propertyName + " LIKE '%" + propertyValue + "%'");
        }
        break;
      case LE:
        criterion = new Criterion(propertyName + " <= ", propertyValue);
        break;
      case LT:
        criterion = new Criterion(propertyName + " < ", propertyValue);
        break;
      case GE:
        criterion = new Criterion(propertyName + " >= ", propertyValue);
        break;
      case GT:
        criterion = new Criterion(propertyName + " > ", propertyValue);
    }
    return criterion;
  }

  protected String criterionToString(final Criterion criterion) {
    if(criterion == null)
      return "";
    StringBuffer sb = new StringBuffer();
    if(criterion.isNoValue()) {
      sb.append(" ").append(criterion.getCondition()).append(" ");
    }
    else if(criterion.isSingleValue()) {
      sb.append(" ").append(criterion.getCondition()).append(convert(criterion.getValue())).append(" ");
    }
    else if(criterion.isListValue()) {
      StringBuffer values = new StringBuffer();
      if(criterion.getValue() instanceof List<?>) {
        for(Object obj : (List<?>)criterion.getValue()) {
          values.append(convert(obj)).append(", ");
        }
        if(values.length() > 0) {
          values.delete(values.length() - 2, values.length()).insert(0, "(").append(")");
        }
        sb.append(" ").append(criterion.getCondition()).append(values).append(" ");
      }
      else {
        sb.append(" ").append(criterion.getCondition()).append(convert(criterion.getValue())).append(" ");
      }
    }
    else if(criterion.isBetweenValue()) {
      sb.append(" ").append(criterion.getCondition()).append(convert(criterion.getValue())).append(" and ").append(convert(criterion.getSecondValue())).append(" ");
    }
    return sb.toString();
  }

  protected static String convert(Object obj) {
    if(obj  instanceof String){
      return "'"+obj+"'";
    }else if(obj instanceof Date){
      return "'"+DateFormatUtils.format((Date)obj, "yyyy-MM-dd HH:mm:ss")+"'";
    }
    return ConvertUtils.convert(obj);
  }

  public void setOrderByClause(String orderByClause) {
    this.orderByClause = orderByClause;
  }

  public String getOrderByClause() {
    return orderByClause;
  }

  public void setDistinct(boolean distinct) {
    this.distinct = distinct;
  }

  public boolean isDistinct() {
    return distinct;
  }

  public List<Criteria> getOredCriteria() {
    return oredCriteria;
  }

  public void or(Criteria criteria) {
    oredCriteria.add(criteria);
  }

  public Criteria or() {
    Criteria criteria = createCriteriaInternal();
    oredCriteria.add(criteria);
    return criteria;
  }

  public Criteria createCriteria() {
    Criteria criteria = createCriteriaInternal();
    if(oredCriteria.size() == 0) {
      oredCriteria.add(criteria);
    }
    return criteria;
  }

  protected Criteria createCriteriaInternal() {
    Criteria criteria = new Criteria();
    return criteria;
  }

  public void clear() {
    oredCriteria.clear();
    orderByClause = null;
    distinct = false;
  }
  /**
   * 属性比较类型枚举<p>
   *
   * @author 
   */
  public enum MatchType {
    /** 等于 */
    EQ,
    /** 不等于 */
    NE,
    /** 小于 */
    LT,
    /** 大于 */
    GT,
    /** 小于等于 */
    LE,
    /** 大于等于 */
    GE,
    /** 模糊匹配 */
    LIKE;
  }

  /**
   * 属性数据类型枚举<p>
   *
   * @author 
   */
  public enum PropertyType {
    /** String */
    S(String.class),
    /** Integer */
    I(Integer.class),
    /** Long */
    L(Long.class),
    /** Double */
    N(Double.class),
    /** Date */
    D(Date.class),
    /** Boolean */
    B(Boolean.class);

    private Class<?> clazz;

    private PropertyType(Class<?> clazz) {
      this.clazz = clazz;
    }

    public Class<?> getValue() {
      return this.clazz;
    }
  }
  
}

 使用mybatis时参照hibernate的propertyFilter工具类实现,代码还有待改进

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值