论坛中关联的地址:
http://www.iteye.com/topic/397854
直接上代码比较能说明问题。
首先是一个工具类SpringContextTool.java,getIdValue方法原本其他工具类中的方法,挪过来放在一起说方便。虽然是JDK 1.5的编程风格,但是主要技巧同样适用于JDK 1.4。
public class SpringContextTool implements ApplicationContextAware {
/**Spring应用上下文环境*/
private static ApplicationContext applicationContext;
/**实现ApplicationContextAware接口的回调方法,设置上下文环境
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextTool.applicationContext = applicationContext;
}
public static SessionFactory getSessionFactory() {
Assert.notNull(applicationContext, "applicationContext is null,请确保spring容器正常启动");
return (SessionFactory) applicationContext.getBean("sessionFactory");
}
public static ClassMetadata getClassMetadata(Class<?> cls) {
return getSessionFactory().getClassMetadata(cls);
}
/**得到一个model的id的值,可以直接获得id而不触发sql的产生,适合ManyToOne的场景
* @param model 有可能是CGLib增强之后的对象
* @return id
*/
public static String getIdValue(BaseModel model) {
if (model instanceof HibernateProxy) {
return (String) ((HibernateProxy) model).getHibernateLazyInitializer().getIdentifier();
}
return (String) getClassMetadata(model.getClass()).getIdentifier(model, EntityMode.POJO);
}
}
1.这里的applicationContext属性是static的,觉得奇怪吧,没办法啊,为了追求getIdValue是static的,因为Model中或者是BaseModel中实现HashCode或者是equals最好是能调用static的方法,而不是有状态的。
2.getIdValue方法中,参数model可以是Object类型,其中实现方法可以看到,如果是代理对象HibernateProxy,可直接得到他的ID,如果是非代理对象,通过配置信息一样可以得到ID。传入参数可以改成Object类型,返回类型也可以根据需要修改成Object。
下面是我写的BaseModel中的应用(注意hashCode方法的实现,我这里规定ID是String类型的,其他类型的ID一样可以借鉴),仅供参考:
public abstract class BaseModel<E> implements Cloneable, Serializable {
public int hashCode() {
String idStr = SpringContextTool.getIdValue(this);
return idStr == null ? super.hashCode() : idStr.hashCode();
}
public boolean equals(Object other) {
if (other == null) {
return false;
}
if (other == this) {
return true;
}
/*因为字节码增强的关系,getClass()不能用作判断的依据*/
if (getClass().getPackage() != other.getClass().getPackage()) {
return false;
}
if (hashCode() == other.hashCode()) {
return true;
}
return false;
}
/**日志对象*/
protected final Logger log = Logger.getLogger(getClass());
/**覆盖toString方法,ToStringStyle取值为ToStringStyle.SHORT_PREFIX_STYLE
* ,调试的时候注意会自动取所有引用的值,会触发所有的Hibernate的延迟加载,
* 如果遇到性能问题,必须覆盖这个默认的toString方法的实现,或者避免调用这个默认的toString方法。
* @return String
*/
public String toString() {
ToStringBuilder tsb = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
for (Field field : getClass().getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
String name = field.getName();
if ("log".equals(name) || "serialVersionUID".equals(name)) {
continue;
}
Object obj = ModelUtils.getProperty(this, name);
if (obj instanceof AbstractPersistentCollection) {
continue;
}
if (obj instanceof Calendar) {
obj = DateTimeUtils.calendar2StrDateTime((Calendar) obj);
}
tsb.append(name, obj);
}
return tsb.toString();
}
/**提供默认的clone方法的实现,不支持深层复制
* @return Object
*/
public E clone() {
try {
return (E) super.clone();
} catch (CloneNotSupportedException ex) {
throw new IllegalArgumentException(ex.getMessage());
}
}
/**提供simple的clone方法的实现,不复制Hibernate代理对象
* @return Object
*/
public Object cloneSimple() {
Object obj = ModelUtils.newInstance(getClass());
Field[] fields = getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (Modifier.isStatic(fields[i].getModifiers())) {
continue;
}
String name = fields[i].getName();
if ("serialVersionUID".equals(name)) {
continue;
}
Object fieldObj = ModelUtils.getProperty(this, name);
if (fieldObj instanceof AbstractPersistentCollection ||
fieldObj instanceof BaseModel) {
continue;
}
ModelUtils.setProperty(obj, name, fieldObj);
}
return obj;
}
}
分享到:
相关推荐
JAVA的hibernate手动获取session的方法
HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao 通用HibernateDao ...
DAo.hibernate3不是泛型的通用DAo我在网上找了好多都是泛型的,需要继承才能用,本人比较懒,找了好久才找到了这么个,不需要继承可以直接用的hibernate dao
Hibernate实时获取数据库更新记录jar包, 内含:c3p0-0.9.1.2.jar,hibernate-c3p0-4.2.0.Final.jar,mchange-commons-java-0.2.3.4.jar
使用Hibernate编写通用数据库操作代码
使用hibernate封装方法,显现使用一个dao,service,impl来关联两个表的操作,实现,增删改查基本操作
使用hibernate框架,面向接口进行dao层的设计,是通用的底层架构.
hibernate通用分页 方便好用 hibernate通用分页 方便好用
hibernate中文API,hibernate中文参考手册,hibernate API
NULL 博文链接:https://xieyongqiu-163-com.iteye.com/blog/438210
struts+spring+hibernate通用分页方法.rar 博文链接:https://igogogo9.iteye.com/blog/97692
hibernate_中文乱码hibernate_中文乱码hibernate_中文乱码hibernate_中文乱码hibernate_中文乱码hibernate_中文乱码
注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。 你不能使用一个IdentifierGenerator产生组合关键字。一个应用程序必须分配它自己的标识符。 使用<composite-id> 标签(并且内嵌元素...
Hibernate基本数据操作方法 java struts hibernate
Hibernate 中文文档Hibernate 中文文档Hibernate 中文文档Hibernate 中文文档
spring集成hibernate通用dao,泛型,server都可以调用
hibernate中文文档hibernate中文文档hibernate中文文档hibernate中文文档
自己写的一个通用分页工具.是基于hibernate mysql struts2 写的.直接可以部署到tomcat 运行 欢迎指正