`
ry.china
  • 浏览: 139779 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Mybatis版PropertyFilter实现

    博客分类:
  • java
阅读更多
<!--前段时间看到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工具类实现,代码还有待改进

 

分享到:
评论

相关推荐

    比springside PropertyFilter增强灵活的FieldFilter,

    标题 "比springside PropertyFilter增强灵活的FieldFilter" 提示我们关注的是一个与SpringSide框架相关的过滤器组件,特别是关于属性过滤方面的增强。在Java开发中,PropertyFilter是SpringSide项目中的一个实用工具...

    SpringSide3的PropertyFilter条件过滤应用小结

    标题“SpringSide3的PropertyFilter条件过滤应用小结”指的是对SpringSide项目中PropertyFilter类的一个功能总结,这个类主要用于实现基于属性的条件过滤。在Java Web开发中,尤其是在使用Spring框架时,我们经常...

    Java_squigly Filter是一个Jackson JSON PropertyFilter,它使用Facebo.zip

    这种语法使得过滤规则易于理解和实现,特别适合于动态或者条件性的属性筛选。 在实际使用中,你需要首先在项目中引入Jackson库和Java_squigly Filter的相关依赖。接着,你可以创建一个`SimpleBeanPropertyFilter`...

    JSON死循环解决办法

    而对于复杂场景,可能需要使用PropertyFilter或JsonBeanProcessor来实现更灵活的控制。在选择解决方案时,还需要考虑代码的可维护性和性能影响。为了避免全局影响,通常推荐使用filter或processor,而不是直接修改...

    java与json之间的互操作.pdf

    - JSON-lib还支持自定义转换逻辑,通过实现`JsonValueProcessor`接口或使用`PropertyFilter`来定制序列化和反序列化过程。 5. XML与JSON的转换: - 使用`XMLSerializer`类,可以通过`toXML()`方法将JSON对象转换...

    改良版的json-lib2.4

    config.setJsonPropertyFilter(new PropertyFilter(){ public boolean apply(Object source, String name, Object value) { if(name.equals("parentGroup") || name.equals("childGroups")) { return true; } else {...

    json-lib 技术指南

    JSON-lib 提供了 `PropertyFilter` 接口,可以用来控制哪些 JavaBean 属性会被包含在 JSON 或 XML 中。这可以通过 `JsonConfig` 配置实现。另外,`JSONSerializer` 的 `prettyPrint()` 方法可以用于生成格式化的 ...

    Fastjson介绍

    - **自定义序列化规则**:通过实现`NameFilter`、`PropertyFilter`等接口来自定义序列化过程。 ```java public class User { @JSONField(name="ID") private int id; public int getId() { return id; } ...

    java与json之间的互操作

    可以通过`JsonConfig`类配置转换规则,例如定义自定义的`JsonValueProcessor`来处理特定类型的字段,或者使用`PropertyFilter`来过滤JSON序列化过程中不想包含的属性。 在实际应用中,除了JSON-lib之外,还有其他的...

    我积攒的java工具类 基本满足开发需要的工具类

    D:\002 我的工具类\011 对象\对象整体\PropertyFilter.java D:\002 我的工具类\011 对象\对象整体\valid.java D:\002 我的工具类\012 计算地球两个经纬度之间距离 D:\002 我的工具类\012 计算地球两个经纬度之间距离...

    Google Datastore for Java 文档摘录(一)

    最后,关于源码分析,Google Datastore 的 Java 客户端库提供了丰富的类和接口,如 `Datastore`, `Entity`, `Key`, `Query` 等,这些都是实现与 Datastore 交互的基础。深入研究这些源码可以帮助我们更好地理解其...

    java与json之间的互操作[参照].pdf

    6. **高级功能**:JSON-lib还支持更复杂的功能,例如自定义序列化和反序列化过程,通过实现`JsonValueProcessor`接口,你可以控制特定类型的对象如何被转换为JSON。另外,通过设置`JsonConfig`对象,可以指定属性...

    log4net 使用手册1

    5. PropertyFilter:当消息匹配指定的属性值时记录日志。 6. StringMathFilter:当消息包含指定字符串时记录日志。 **Layouts** Layouts决定了日志的输出格式,可以是线性的,也可以是XML。每个Appender只能有一个...

Global site tag (gtag.js) - Google Analytics