Erh*_*mir 21 java entity javabeans
说我有一个java bean /一个有100个字段的实体(在这种情况下继承或不相关).更新操作后 - 在事务中,我想确定修改哪些字段以跟踪CVS等更新.最简单的方法是什么?任何框架建议?我应该制作这个对象的两个实例并迭代所有字段并匹配字段的值吗?在这种情况下,最好的等于方法怎么样呢?以下equals()似乎很尴尬:
return (field1.equals(o.field1)) &&
(field2.equals(o.field2)) &&
(field3.equals(o.field3)) &&
...
(field100.equals(o.field100));
Run Code Online (Sandbox Code Playgroud)
t3c*_*ris 30
您可以使用Apache Commons Beanutils.这是一个简单的例子:
package at.percom.temp.zztests;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.PropertyUtilsBean;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class Main {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Main main = new Main();
main.start();
}
public void start() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
SampleBean oldSample = new SampleBean("John", "Doe", 1971);
SampleBean newSample = new SampleBean("John X.", "Doe", 1971);
SampleBean diffSample = (SampleBean) compareObjects(oldSample, newSample, new HashSet<>(Arrays.asList("lastName")), 10L);
}
public Object compareObjects(Object oldObject, Object newObject, Set<String> propertyNamesToAvoid, Long deep) {
return compareObjects(oldObject, newObject, propertyNamesToAvoid, deep, null);
}
private Object compareObjects(Object oldObject, Object newObject, Set<String> propertyNamesToAvoid, Long deep,
String parentPropertyPath) {
propertyNamesToAvoid = propertyNamesToAvoid != null ? propertyNamesToAvoid : new HashSet<>();
parentPropertyPath = parentPropertyPath != null ? parentPropertyPath : "";
Object diffObject = null;
try {
diffObject = oldObject.getClass().newInstance();
} catch (Exception e) {
return diffObject;
}
BeanMap map = new BeanMap(oldObject);
PropertyUtilsBean propUtils = new PropertyUtilsBean();
for (Object propNameObject : map.keySet()) {
String propertyName = (String) propNameObject;
String propertyPath = parentPropertyPath + propertyName;
if (!propUtils.isWriteable(diffObject, propertyName) || !propUtils.isReadable(newObject, propertyName)
|| propertyNamesToAvoid.contains(propertyPath)) {
continue;
}
Object property1 = null;
try {
property1 = propUtils.getProperty(oldObject, propertyName);
} catch (Exception e) {
}
Object property2 = null;
try {
property2 = propUtils.getProperty(newObject, propertyName);
} catch (Exception e) {
}
try {
if (property1 != null && property2 != null && property1.getClass().getName().startsWith("com.racing.company")
&& (deep == null || deep > 0)) {
Object diffProperty = compareObjects(property1, property2, propertyNamesToAvoid,
deep != null ? deep - 1 : null, propertyPath + ".");
propUtils.setProperty(diffObject, propertyName, diffProperty);
} else {
if (!Objects.deepEquals(property1, property2)) {
propUtils.setProperty(diffObject, propertyName, property2);
System.out.println("> " + propertyPath + " is different (oldValue=\"" + property1 + "\", newValue=\""
+ property2 + "\")");
} else {
System.out.println(" " + propertyPath + " is equal");
}
}
} catch (Exception e) {
}
}
return diffObject;
}
public class SampleBean {
public String firstName;
public String lastName;
public int yearOfBirth;
public SampleBean(String firstName, String lastName, int yearOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.yearOfBirth = yearOfBirth;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getYearOfBirth() {
return yearOfBirth;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Paw*_*zyk 17
嘿看看Javers,它正是你所需要的 - 对象审计和差异框架.使用Javers,您可以javers.commit()在每次更新后通过一次调用持久保存对域对象所做的更改.当您持续进行某些更改时,您可以轻松地阅读它们javers.getChangeHistory,例如
public static void main(String... args) {
//get Javers instance
Javers javers = JaversBuilder.javers().build();
//create java bean
User user = new User(1, "John");
//commit current state
javers.commit("author", user);
//update operation
user.setUserName("David");
//commit change
javers.commit("author", user);
//read 100 last changes
List<Change> changes = javers.getChangeHistory(instanceId(1, User.class), 100);
//print change log
System.out.printf(javers.processChangeList(changes, new SimpleTextChangeLog()));
}
Run Code Online (Sandbox Code Playgroud)
输出是:
commit 2.0, author:author, 2015-01-07 23:00:10
changed object: org.javers.demo.User/1
value changed on 'userName' property: 'John' -> 'David'
commit 1.0, author:author, 2015-01-07 23:00:10
new object: 'org.javers.demo.User/1
Run Code Online (Sandbox Code Playgroud)
您可以使用反射来加载字段,然后在每个对象上调用它们并比较结果.
示例源代码可能如下所示:
public static <T> void Compare(T source, T target) throws IllegalArgumentException, IllegalAccessException {
if(source == null) {
throw new IllegalArgumentException("Null argument not excepted at this point");
}
Field[] fields = source.getClass().getFields();
Object sourceObject;
Object targetObject;
for(Field field : fields){
sourceObject = field.get(source);
targetObject = field.get(target);
//Compare the object
}
}
Run Code Online (Sandbox Code Playgroud)
仅供参考,此代码仅适用于为类声明的公共字段.
| 归档时间: |
|
| 查看次数: |
22521 次 |
| 最近记录: |