Mat*_*uis 7 java hibernate jpa
每天,数据通过Web服务导入.
我知道我可以浏览pojos上的所有字段,并检查空值,并在适当的地方更新,但我更愿意让hibernate执行此操作,如果它能够,因为它会减少我添加字段和忘记将其添加到此手动合并过程中.
休眠可以执行上面的第4步吗?
Sea*_*oyd 11
不,Hibernate(或JPA)不提供开箱即用的功能,但使用JavaBeans机制(或许多提供抽象层的库之一)并不难实现.
这是一个方法,使用标准的JavaBeans 机制将所有属性复制beanA
到beanB
null(如果它们为null):beanB
Introspector
public static void copyBeanProperties(
final Object beanA, final Object beanB){
if(beanA.getClass() != beanB.getClass()){
// actually, this may be a problem, because beanB may be a
// cglib-created subclass
throw new IllegalArgumentException();
}
try{
for( final PropertyDescriptor pd :
Introspector
.getBeanInfo(beanB.getClass(), Object.class)
.getPropertyDescriptors()){
if(pd.getReadMethod().invoke(beanB)==null){
pd.getWriteMethod().invoke(beanB,
pd.getReadMethod().invoke(beanA)
);
}
}
} catch(IntrospectionException e){
throw new IllegalStateException(e);
} catch(IllegalAccessException e){
throw new IllegalStateException(e);
} catch(InvocationTargetException e){
throw new IllegalStateException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
当然这只是一个快速而肮脏的实现,但它应该让你开始.
这是一个使用Commons/BeanUtils的稍微优雅的版本.它会隐藏您的反射并提供基于地图的属性访问:
public static void copyBeanProperties(final Object beanA, final Object beanB){
try{
@SuppressWarnings("unchecked") // this should be safe
final Map<String, Object> beanAProps = PropertyUtils.describe(beanA);
@SuppressWarnings("unchecked") // this should be safe
final Map<String, Object> beanBProps = PropertyUtils.describe(beanB);
if(!beanAProps.keySet().containsAll(beanBProps.keySet())){
throw new IllegalArgumentException("Incompatible types: "
+ beanA + ", " + beanB);
}
for(final Entry<String, Object> entryA : beanAProps.entrySet()){
if(beanBProps.get(entryA.getKey()) == null){
PropertyUtils.setMappedProperty(beanB, entryA.getKey(),
entryA.getValue());
}
}
} catch(final IllegalAccessException e){
throw new IllegalStateException(e);
} catch(final InvocationTargetException e){
throw new IllegalStateException(e);
} catch(final NoSuchMethodException e){
throw new IllegalStateException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用Spring BeanWrapper
接口的另一个版本(它是最简洁的,因为Spring提供了一个抽象,超过了所有的反射,并且它自己进行了异常处理),但遗憾的BeanWrapper
是,该技术仅适用于Spring IOC容器(当然,这只是不幸的.你不使用容器):
public static void copyBeanProperties(final Object beanA, final Object beanB){
final BeanWrapper wrapperA = new BeanWrapperImpl(beanA);
final BeanWrapper wrapperB = new BeanWrapperImpl(beanB);
try{
for(final PropertyDescriptor descriptor : wrapperB
.getPropertyDescriptors()){
final String propertyName = descriptor.getName();
if(wrapperB.getPropertyValue(propertyName) == null){
wrapperB.setPropertyValue(propertyName,
wrapperA.getPropertyValue(propertyName));
}
}
} catch(final /* unchecked */ InvalidPropertyException e){
throw new IllegalArgumentException("Incompatible types: " + beanA
+ ", " + beanB, e);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5196 次 |
最近记录: |