【原创】JSR303与ApacheValidate性能测试

软件开发中涉及到这样一个问题,那就是关于后台系统的数据验证,任何系统的绕不过去的。

下面针对于各种方式的数据验证进行一个测试。

if else

结论:这种效率是无疑是最高效的验证代码,优势是效率高,缺点是可能返回状态忘记设置,可能if else判断太多,看代码很烦。

code:

		long currentTimeMillis = System.currentTimeMillis();
		try
		{
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("status", "y");
			resultMap.put("msg", "操作成功!");

			for (int i = 0; i < 300; i++)
			{
				PlatformDevelopers dev = new PlatformDevelopers();
				if (null == dev.getAddress() || dev.getAddress().length() == 0)
				{
					resultMap.put("status", "n");
					resultMap.put("msg", "Address 不能为空!");
					//这里按照正常流程走的话,应该是 return ;
					continue;
				}
			}
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			long l = System.currentTimeMillis();
			System.out.println(l - currentTimeMillis);
		}

程序执行300次,测试得到的平均时间为:32ms左右。

if else 太多的情况,如:

		StringBuilder builder = new StringBuilder(160);
		if (getDicMap().containsKey("id")) //如果包含id,则进行处理
		{
			builder.append(Str.tl(" and id in (:0) ", getMoreParameter("id")));
		} else if (this.getId() != null && !"".equals(this.getId()))
		{
			builder.append(" and id = " + this.getId());
		}
		if (getDicMap().containsKey("text")) //如果包含text,则进行处理
		{
			builder.append(Str.tl(" and text in (:0) ", getMoreParameter("text", true)));
		} else if (this.getText() != null && !"".equals(this.getText()))
		{
			builder.append(" and text like '%" + Str.filterSql(this.getText()) + "%'");
		}
		if (getDicMap().containsKey("realValue")) //如果包含realValue,则进行处理
		{
			builder.append(Str.tl(" and real_value in (:0) ", getMoreParameter("realValue", true)));
		} else if (this.getRealValue() != null && !"".equals(this.getRealValue()))
		{
			builder.append(" and real_value like '%" + Str.filterSql(this.getRealValue()) + "%'");
		}
		if (getDicMap().containsKey("fieldName")) //如果包含fieldName,则进行处理
		{
			builder.append(Str.tl(" and field_name in (:0) ", getMoreParameter("fieldName", true)));
		} else if (this.getFieldName() != null && !"".equals(this.getFieldName()))
		{
			builder.append(" and field_name like '%" + Str.filterSql(this.getFieldName()) + "%'");
		}
		if (getDicMap().containsKey("remark")) //如果包含remark,则进行处理
		{
			builder.append(Str.tl(" and remark in (:0) ", getMoreParameter("remark", true)));
		} else if (this.getRemark() != null && !"".equals(this.getRemark()))
		{
			builder.append(" and remark like '%" + Str.filterSql(this.getRemark()) + "%'");
		}
		if (getDicMap().containsKey("pid")) //如果包含pid,则进行处理
		{
			builder.append(Str.tl(" and pid in (:0) ", getMoreParameter("pid")));
		} else if (this.getPid() != null && !"".equals(this.getPid()))
		{
			builder.append(" and pid = " + this.getPid());
		}
		if (getDicMap().containsKey("pname")) //如果包含pname,则进行处理
		{
			builder.append(Str.tl(" and pname in (:0) ", getMoreParameter("pname", true)));
		} else if (this.getPname() != null && !"".equals(this.getPname()))
		{
			builder.append(" and pname like '%" + Str.filterSql(this.getPname()) + "%'");
		}
		if (getDicMap().containsKey("sort")) //如果包含sort,则进行处理
		{
			builder.append(Str.tl(" and sort in (:0) ", getMoreParameter("sort")));
		} else if (this.getSort() != null && !"".equals(this.getSort()))
		{
			builder.append(" and sort = " + this.getSort());
		}

Apache Validate

结论:这种判断效率比if else略低,优势是可以阻断程序继续往下执行,缺点是会抛出异常栈。

code:

		long currentTimeMillis = System.currentTimeMillis();
		try
		{
			for (int i = 0; i < 300; i++)
			{
				PlatformDevelopers dev = new PlatformDevelopers();
				Validate.notBlank(dev.getAddress(), "错误的参数!");
			}
		} catch (Exception e)
		{
			//e.printStackTrace();
		} finally
		{
			long l = System.currentTimeMillis();
			System.out.println(l - currentTimeMillis);
		}

程序执行300次,测试得到的平均时间为:47ms左右。

如:

java.lang.NullPointerException: Address 不能为空!     at org.apache.commons.lang3.Validate.notBlank(Validate.java:448)     at test.spring.boot.rest.TValidVsJSR.m2(TValidVsJSR.java:59)     at test.spring.boot.rest.TValidVsJSR.main(TValidVsJSR.java:29)

JSR303(Hibernate Validator 5.2.4.Final 提供支持)

结论:这种判断最简单,一个注解搞定,只需处理错误即可。优点是方便,功能强大,可读性,可配置强大,有社区支持,缺点是效率最低,比上面的验证结果慢了10倍有余。

long currentTimeMillis = System.currentTimeMillis();
		for (int i = 0; i < 300; i++)
		{
			PlatformDevelopers dev = new PlatformDevelopers();
			//jsr
			Map<String, String> validate = ValidateUtil.validate(dev);
			if (!validate.isEmpty())
			{
				//				System.out.println(validate);
			}

		}
		long l = System.currentTimeMillis();
		System.out.println(l - currentTimeMillis);

PlatformDevelopers.java

public class PlatformDevelopers 
{
	//id	
	private java.lang.Integer id;

	@NotBlank
	@Email
	//开发者email	
	private java.lang.String email;

	@NotBlank
	@Size(min = 6, max = 32)
	//登陆密码
	private java.lang.String password;
}

ValidateUtil.java

/**
 * 
 * 项目名称:ej 	<br><br>
 * 
 * 类名称:ValidateUtil 		<br><br>
 * 
 * 创建人:LinApex@163.com 	<br><br>
 * 
 * 创建时间:2014-2-26 下午1:10:03 	<br><br>
 * 
 * 版本:1.0					<br><br>
 * 
 * 功能描述:验证工具类,后台校验对象
 */
public class ValidateUtil
{
	static Validator validator;

	static
	{
		//消息国际化对象
		//		ReloadableResourceBundleMessageSource localMessageSource = new ReloadableResourceBundleMessageSource();
		//		localMessageSource.setBasename("classpath:i18n/messages");
		//		localMessageSource.setDefaultEncoding("UTF-8");
		//		localMessageSource.setCacheSeconds(60);

		LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
		localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
		//		localValidatorFactoryBean.setValidationMessageSource(localMessageSource);	//消息国际化对象
		localValidatorFactoryBean.afterPropertiesSet();
		validator = localValidatorFactoryBean.getValidator();
	}

	public static <T> Map<String, String> validate(T t)
	{
		Map<String, String> resultMap = new HashMap<String, String>(0);
		Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
		if (constraintViolations.size() > 0)
		{
			for (ConstraintViolation<T> constraintViolation : constraintViolations)
			{
				resultMap.put(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
			}
		}
		return resultMap;
	}

}

程序执行300次,测试得到的平均时间为:630ms左右。

有没有更优的解决方式?

你们在开发里一般使用什么方式?

有没有更有经验的朋友来分享一下你的看法?

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区