相信大家在使用hibernate(我这里使用的是3.6,因为我偏爱spring,但是hibernate4.x系以后和spring很多重复的地方,而且,spring也认为,hibernate4.x是一个很完善的框架了,spring3.x以后废弃掉了很多hibernate的支持类,所以我就不升级hibernate了)的时候都有这样的困惑,就是在配置hibernate映射文件的时候,如果有一对多(或者多对多)属性的时候,hinernate提供了一个优化机制,lazy属性,但是问题在于,配置文件是一次性配置,假如我项目中有的地方需要延迟加载,有的地方不需要延迟加载,这样的话就必须强制lazy=false,这样的话 这个优化机制就失去了他的意义.
经过一段时间的经验积累,终于相处了一套可行性比较强的方案:
项目中所有的lazy属性默认为true,不再设置为false.在项目中添加了一个commonService,提供了两个方法,一个是查询单个对象,一个是查询列表:
[java]
@Override
public Object findById(Class< > Objclass, Class< > idClass,Object id,String[] fields) {
Object o = dao.findById(Objclass, (Serializable) idClass.cast(id));
if(fields!=null){
for(String field:fields){
String targetMethod = "get"+upperFirstWord(field);
Method[] methods = Objclass.getDeclaredMethods();
for (Method m : methods) {
if(m.getName().equals(targetMethod)){
try {
Hibernate.initialize(m.invoke(o));
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return o;
}
@Override
public Object findById(Class< > Objclass, Class< > idClass,Object id,String[] fields) {
Object o = dao.findById(Objclass, (Serializable) idClass.cast(id));
if(fields!=null){
for(String field:fields){
String targetMethod = "get"+upperFirstWord(field);
Method[] methods = Objclass.getDeclaredMethods();
for (Method m : methods) {
if(m.getName().equals(targetMethod)){
try {
Hibernate.initialize(m.invoke(o));
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return o;
}
Objclass 需要查询的对象的class
idClass id字段的类型
id id的值
fields 需要初始化的字段
[java]
public List< > find(Class< > entityClazz, QueryParameterSetter paraSetter, Sorter sorter, Page page,String[] fields) {
DetachedCriteria dc = DetachedCriteria.forClass(entityClazz);
if (paraSetter != null)
paraSetter.setParameters(dc);
if (sorter != null && sorter.getOrder() != null)
dc.addOrder(sorter.getOrder());
List< > l = findPageListByCriteria(dc, page.getPageSize(), page.getRecordStartIndex());
lazyInitialize(entityClazz,l,fields);
return l;
}
private void lazyInitialize(Class< > entityClazz,List< > l ,String[] fields){
if(fields!=null){
for(String field:fields){
String targetMethod = "get"+upperFirstWord(field);
Method[] methods = entityClazz.getDeclaredMethods();
for (Method m : methods) {
if(m.getName().equals(targetMethod)){
try {
for(Object o:l){
Hibernate.initialize(m.invoke(o));
}
} catch (Exception e) {
e.printStackTrace();
}