.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}
weed的github地址
因为工作中需要进行数据对比,所以经常需要在代码的增删改查操作中嵌入一些对比类。我们都知道开闭原则:对修改关闭,对扩展开放。所以每次修改的时候都需要新增一个类,然后再通知用到了原始类的同事一起同步修改代码。如果方法涉及到的模块少,还可以比较轻松的解决,但是如果用到的地方比较多,那需要协调的地方也会增多。
偷懒是人类文明发展的驱动力
于是,为了解决新增数据对比方法的苦恼,也为了尽量使用少侵入的模式,在工作之余,我也开始思考是不是把放进去的代码再抽出来。思考再三,决定用注解模式解决这个问题,于是乎,就有了weed这一个工具的出现。
当然,现在只是一块不到一千行代码,解决不了绝大多数问题的小工具包。
目前可以公开的情报
- 1、contrastSourceFundByBean方法专门用来对比两个类对象的信息,类中可以包含任意类 ,但是要记得在类中类加注解。
- 2、getListupdateOnly方法专门用来对比两个集合的信息,集合中不可包含类,只能是纯基础对象的集合,以后会慢慢更新。
- 3、judgeArray方法用来比较两个数组之间的信息,数组可以是任意类。
- 4、注解默认都是可以不加的,需要加的时候是需要用到的时候。
- 5、这个项目是因为日常给后台人员提供信息对比类的时候想到的,就写出来应该有一点用吧?大家就不用重复造轮子了。
- 6、weed代表着我第一个十连出了温蒂,第二个十连就出了可莉,第三个十连出了卢姥爷, 其实我挺难受的,香菱60出了可莉,可莉70、武器也70,一整套魔女的时候出了卢姥爷,哎。。。不想要火C了
设计思路
既然决定使用少侵入的模式,那么使用注解的方法就是一个不错的解决方式。
因为网上都有如何使用自定义注解的教程,我这里也就不再班门弄斧,主要展示一下我大概的设计思路。
代码语言:javascript复制@Target(java.lang.annotation.ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckField {
/**
* 字段最小长度
*/
int minlen() default 0;
/**
* 字段最大长度
*/
int maxlen() default Short.MAX_VALUE;
/**
* 字段是否需要校验
*/
Check check() default Check.unchecks;
/**
* 字段名(用于后期获取)
*/
String name() default "";
/**
* 字段类型
*/
Check type() default Check.basics;
}
校验字段枚举类,这里也主要体现的是一种思路,也是目前提供的解决方案:无论你是基础类型,还是对象、数组,亦或是集合,目前都有办法进行对比,也能拿到所需要的数据。
代码语言:javascript复制public enum Check {
/**
* 检查
*/
checks,
/**
* 不检查
*/
unchecks,
/**
* 对象
*/
beans,
/**
* 数组
*/
arrays,
/**
* 集合
*/
sets,
/**
* 基础数据类型
*/
basics,
}
最后就是其中的一个方法了,看过我过去文章的同学能够发现,这个方法是在之前的基础上进行了改动,加大了对注解的应用。
代码语言:javascript复制/**
* @param oldBean 原始数据
* @param newBean 新数据
* @return 根据传入的对象返回变化值
*/
public static String contrastSourceFundByBean(Object oldBean, Object newBean) {
StringBuilder str = new StringBuilder();
Object pojo1 = (Object) oldBean;
Object pojo2 = (Object) newBean;
if (!(pojo1.getClass()==pojo2.getClass())){
return "对象类型不一致";
}
try {
Class clazz = pojo1.getClass();
Field[] fields = pojo1.getClass().getDeclaredFields();
Class chkField = CheckField.class;
int i = 1;
for (Field field : fields) {
CheckField cf = field.getAnnotation(chkField);
if (field.isAnnotationPresent(chkField)) {
//获取字段是否填写(不校验,空,非空)
if (cf.check().equals(Check.unchecks)&&cf.type().equals(Check.basics)) {
continue;
}
//同意对private字段取值
field.setAccessible(true);
Object fValue = null;
try {
fValue = field.get(pojo1);
} catch (Exception e) {
return "获取字段值异常!";
}
//获取最大值
int max = cf.maxlen();
//获取配置最小值
int min = cf.minlen();
int flength = 0;
//为空时判断
if (fValue != null) {
try {
String strVal = fValue.toString();
flength = strVal.length();
} catch (Exception e) {
}
}
if (max < flength) {
return cf.name() "长度不能大于" max "!";
}
if (min > flength) {
return cf.name() "长度不能小于" min "!";
}
}
//获取对象具体信息
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
Method getMethod = pd.getReadMethod();
//对象间比较
Object o1 = getMethod.invoke(pojo1);
Object o2 = getMethod.invoke(pojo2);
if (o2 == null) {
continue;
} else if (o1 == null) {
if (filterCheck(cf)) {
continue;
}
String getName = cf.name();
str.append(getName).append(":新增值:").append(o2);
i ;
} else {
if (filterCheck(cf)){
String otto = contrastSourceFundByBean(o1, o2);
String getName = cf.name();
str.append("|").append(getName).append("{").append("[").append(otto).append("]").append("}");
}else if(filterChecksets(cf)){
String list =getListupdateOnly((List)o1,(List)o2);
String getName = cf.name();
str.append("|").append(getName).append("{").append("[").append(list).append("]").append("}");
}else if(filterCheckarray(cf)){
String array =judgeArray(o1,o2);
String getName = cf.name();
str.append("|").append(getName).append("{").append("[").append(array).append("]").append("}");
}else{
if (!o1.equals(o2)) {
if (filterCheck(cf)) {
continue;
}
if (i != 1) {
str.append("|");
}
String getName = cf.name();
str.append(getName).append(":旧值:").append(o1).append(",新值:").append(o2);
i ;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return str.toString();
}
/**
* 对传入的状态进行判断
* @param cf
* @return
*/
private static boolean filterChecksets(CheckField cf){
return cf.type().equals(Check.sets);
}
private static boolean filterCheck(CheckField cf){
return cf.type().equals(Check.beans);
}
private static boolean filterCheckarray(CheckField cf){
return cf.type().equals(Check.arrays);
}
}
然后对方法进行一下小小的测试,输出如下:
其余的部分,大家去我的GitHub地址看看吧~,在给大家发一遍 weed的github地址
希望能够一起完善weed~