在以前的工作中,要好多东西虽然不明白怎么回事,但是感觉很方便,很神奇,例如,spring中的@service,@controller,@requestmapping等就特别的方便,下面我就记录一下我对注解的理解以及运用方法。
- 首先,我们怎么才能吧注解加到我们的类中呢?我们需要先创建注解的类,也就是@interface的类
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.FIELD)
public @interface QueryField {
LogicType logicType() default AND;
Operator operator() default LIKE;
String fieldName();
String[] paramName();
Type type() default STRING;
boolean ignoreCase() default true;
MatchType matchType() default ANYWHERE;
public enum MatchType {
ANYWHERE(MatchMode.ANYWHERE), EXACT(MatchMode.EXACT), START(
MatchMode.START), END(MatchMode.END);
MatchMode matchModel;
/**
* @param matchModel
*/
private MatchType(MatchMode matchModel) {
this.matchModel = matchModel;
}
/**
* @return the matchModel
*/
public MatchMode getMatchModel() {
return matchModel;
}
}
}
@Retention用来声明注解的保留策略,有CLASS、RUNTIME和SOURCE这三种,分别表示注解保存在类文件、JVM运行时刻和源代码中。只有当声明为RUNTIME的时候,才能够在运行时刻通过反射API来获取到注解的信息。@Target用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。
这个类里面的属性,就是注解中锁添加的参数。
- 然后,我们就要调用这个注解了,因为这个注解的target为field,所以我们要在属性上面去加这个注解
@Scope("prototype")
@QueryEntity(WsJcxxGrlxfsb.class)//基础信息-个人联系方式
public class QueryObjectDemo implements QueryObject,Serializable{
/**
*
*/
private static final long serialVersionUID = -8361090782068743413L;
@QueryField(fieldName="xnzjhm" ,paramName="xnzjhm",operator=Operator.LIKE,matchType=MatchType.ANYWHERE)
private String xnzjhm;//校内证件号码
@QueryField(fieldName="sj",paramName="sj",operator=Operator.EQ )
private String sj; // 手机
@QueryField(fieldName="xgsj" ,paramName="xgsjArr",operator=Operator.BETWEEN)
private Date[] xgsjArr; // 修改时间(记录记录生成或最后一次修改的时间)
private Date xgsj1;
private Date xgsj2;
@Override
public void beforeBuildCriteria() {
xgsjArr = new Date[] {xgsj1,xgsj2};
}
@Override
public Criteria afterBuildCriteria(Criteria cr) {
cr.addOrder(Order.desc("xgsj"));
return cr;
}
/**
* @return the xnzjhm
*/
public String getXnzjhm() {
return xnzjhm;
}
/**
* @param xnzjhm the xnzjhm to set
*/
public void setXnzjhm(String xnzjhm) {
this.xnzjhm = xnzjhm;
}
/**
* @return the sj
*/
public String getSj() {
return sj;
}
/**
* @param sj the sj to set
*/
public void setSj(String sj) {
this.sj = sj;
}
/**
* @return the xgsjArr
*/
public Date[] getXgsjArr() {
return xgsjArr;
}
/**
* @param xgsjArr the xgsjArr to set
*/
public void setXgsjArr(Date[] xgsjArr) {
this.xgsjArr = xgsjArr;
}
/**
* @return the xgsj1
*/
public Date getXgsj1() {
return xgsj1;
}
/**
* @param xgsj1 the xgsj1 to set
*/
public void setXgsj1(Date xgsj1) {
this.xgsj1 = xgsj1;
}
/**
* @return the xgsj2
*/
public Date getXgsj2() {
return xgsj2;
}
/**
* @param xgsj2 the xgsj2 to set
*/
public void setXgsj2(Date xgsj2) {
this.xgsj2 = xgsj2;
}
}
- 好了。现在我们都已经把注解都加好了,那么我们加了这些到底有什么用呢,大家接着往下看
public class QueryObjectHelper {
public static <T extends QueryObject> Criteria buildCriteria( T qo,Session session) {
qo.beforeBuildCriteria();
QueryEntity annQo = qo.getClass().getAnnotation(QueryEntity.class);
Criteria criteria = session.createCriteria(annQo.value());
Field[] fieldArr = qo.getClass().getDeclaredFields();
for (Field field : fieldArr) {
Annotation fieldAnn = field.getAnnotation(QueryField.class);
field.setAccessible(true);
try {
if (fieldAnn == null || fieldAnn.equals("") || field.get(qo) == null || field.get(qo).equals("")) {
continue;
}
Criterion exp = buildExpression(field, qo);
criteria.add(exp);
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
field.setAccessible(false);
}
criteria = qo.afterBuildCriteria(criteria);
return criteria;
}
private static <T extends QueryObject> Criterion buildExpression(
Field field, T qo) throws IllegalArgumentException,
IllegalAccessException {
Param firstParam = null;
Param secondParam = null;
Param likeParam = null;
QueryField ann = field.getAnnotation(QueryField.class);
switch (ann.operator()) {
case BETWEEN:
firstParam = Param.getCommonParam(ann.paramName()[0],
((Object[]) field.get(qo))[0], ann.type());
secondParam = Param.getCommonParam(ann.paramName()[1],
((Object[]) field.get(qo))[1], ann.type());
return Between.between(ann.logicType(), ann.fieldName(),
firstParam, secondParam);
case NOT_BETWEEN:
firstParam = Param.getCommonParam(ann.paramName()[0],
((Object[]) field.get(qo))[0], ann.type());
secondParam = Param.getCommonParam(ann.paramName()[1],
((Object[]) field.get(qo))[1], ann.type());
return Between.notBetween(ann.logicType(), ann.fieldName(),
firstParam, secondParam);
case EQ:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return Compare.eq(ann.logicType(), ann.fieldName(), firstParam);
case NE:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return Compare.ne(ann.logicType(), ann.fieldName(), firstParam);
case LT:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return Compare.lt(ann.logicType(), ann.fieldName(), firstParam);
case LE:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return Compare.le(ann.logicType(), ann.fieldName(), firstParam);
case GT:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return Compare.gt(ann.logicType(), ann.fieldName(), firstParam);
case GE:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return Compare.ge(ann.logicType(), ann.fieldName(), firstParam);
case LIKE:
likeParam = Param.getVarcharParam(ann.paramName()[0],
field.get(qo), ann.ignoreCase(), ann.matchType()
.getMatchModel());
return Like.like(ann.logicType(), ann.fieldName(), likeParam);
case NOT_LIKE:
likeParam = Param.getVarcharParam(ann.paramName()[0],
field.get(qo), ann.ignoreCase(), ann.matchType()
.getMatchModel());
return Like.notLike(ann.logicType(), ann.fieldName(), likeParam);
case IN:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return In.in(ann.logicType(), ann.fieldName(), firstParam);
case NOT_IN:
firstParam = Param.getCommonParam(ann.paramName()[0],
field.get(qo), ann.type());
return In.notIn(ann.logicType(), ann.fieldName(), firstParam);
case IS_NULL:
return JudgeNull.isNull(ann.logicType(), ann.fieldName());
case IS_NOT_NULL:
return JudgeNull.isNotNull(ann.logicType(), ann.fieldName());
default:
break;
}
return null;
}
}
我们可以看到,我们是通过我们的注解,以及注解中的参数,把我们需要的数据拿了过来重新组装成我们需要的东西,这样看来,很多相似的东西我们就可以这样做,从实现的原理上我们参考的是封装,而从根本实现是基于java的反射机制,通过反射,以及我们对规则的掌握,我们就可以通过注解的方式去实现很多重复的方法,其中不同的东西,我们也是靠参数传到注解里面了,这样我们的代码看着就很整洁,而且会减少我们没有必要的冗余代码,从实现与框架上都是一个不错的选择,我们可以通过这个写一套自己的SPRING框架!就是这么简单!