自己参考hibernate的源代码,写了个大概能演示hibernate对对象熟悉延迟加载的几个类,用到了javassist 包。
调用的接口是这样的:
public class Test {
public static void main(String[] args) {
HibernateSeesion session = new HibernateSeesion();
Custerinform c1 = (Custerinform)session.load(Custerinform.class, "2");
//延迟加载对象上除了id以外的熟悉,无需连接数据库
System.out.println(c1.getId());
//正在需要用到其他熟悉时,再去数据库加载数据
System.out.println(c1.getFirstName());
//复用已经完全加载出来的对象,无需再连接数据库
System.out.println(c1.getLastName());
}
}
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class HibernateSeesion {
private static Map<String,Object> memDataBase = new HashMap<String,Object>(); //mock database
//一个标识接口,为每个被代理的对象都加上这个接口
private static Class<?>[] proxyInterfaces = {HibernateProxy.class};
//proxy工厂
private static Class<?> proxyFactory;
static{
Custerinform cust1 = new Custerinform();
cust1.setId("1");
cust1.setFirstName("张");
cust1.setLastName("阳");
Custerinform cust2 = new Custerinform();
cust2.setId("2");
cust2.setFirstName("张");
cust2.setLastName("梓琳");
memDataBase.put(Custerinform.class.getName() + cust1.getId(), cust1);
memDataBase.put(Custerinform.class.getName() + cust2.getId(), cust2);
//这里的写法,只是为了简单模拟一下hibernate的机制而已
proxyFactory = LazyInitializer.getProxyFactory(Custerinform.class,proxyInterfaces);
}
/**
* 返回proxy对象
* @param theClass
* @param id
* @return
*/
public Object load(Class<?> theClass, Serializable id){
return LazyInitializer.getProxy(proxyFactory, this, Custerinform.class.getName(),id);
}
/**
* 模拟从数据库中即使加载
* @param entityName
* @param id
* @return
*/
public Object immediateLoad(String entityName, Serializable id){
return memDataBase.get(entityName+id);
}
}
下面这个类是整个延迟加载的核心类容,
proxyfatory 和 proxy 都是在这里生成的,借助了 javassist 包提供的api。
import java.io.Serializable;
import java.lang.reflect.Method;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;
public class LazyInitializer implements MethodHandler {
private static final String INVOKE = "INVOKE";
private boolean constructed = false;
private boolean initialized = false;
private Serializable id;
private Object target;
private HibernateSeesion session;
private String entityName;
public LazyInitializer(final HibernateSeesion session, final String entityName, final Serializable id) {
this.id = id;
this.session = session;
this.entityName = entityName;
}
public static Class<?> getProxyFactory(final Class<?> persistentClass, Class<?>[] interfaces) {
try {
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(persistentClass);
factory.setInterfaces(interfaces);
return factory.createClass();
} catch (Throwable t) {
throw new RuntimeException("Javassist Enhancement failed: " + persistentClass.getName(), t);
}
}
public static HibernateProxy getProxy(final Class<?> factory, final HibernateSeesion session,
final String entityName, final Serializable id) {
final LazyInitializer instance = new LazyInitializer(session, entityName, id);
HibernateProxy proxy;
try {
proxy = (HibernateProxy) factory.newInstance();
} catch (Exception e) {
throw new RuntimeException("Javassist Enhancement failed: " + entityName, e);
}
((ProxyObject) proxy).setHandler(instance);
instance.constructed = true;
return proxy;
}
@Override
public Object invoke(Object proxy, Method thisMethod, Method proceed, Object[] args) throws Throwable {
if (this.constructed) {
Object result;
final Object returnValue;
result = this.invoke(thisMethod, args, proxy); //判断被调用的方法是不是getId
if (result == INVOKE) {
Object target = getInvoke(); //获取目标对象
returnValue = thisMethod.invoke(target, args); //在目标对象上调用方法
return returnValue == target ? proxy : returnValue;
} else {
return result;
}
} else {
return proceed.invoke(proxy, args);
}
}
public final Serializable getIdentifier() {
return id;
}
public final void setIdentifier(Serializable id) {
this.id = id;
}
public final Object getInvoke() {
initialize();
return target;
}
/**
* 拦截 getId 方法,如果只是请求这个方法的话,无需从数据库中加载数据
*/
private final Object invoke(Method method, Object[] args, Object proxy) {
String methodName = method.getName();
int params = args.length;
if (params == 0) {
if (methodName.equals("getId")) {
return getIdentifier();
}
}
return INVOKE;
}
/**
* 初始化代理对象的目标对象
*/
private final void initialize() {
if (!initialized) {
System.out.println("load data from database");
target = session.immediateLoad(entityName, id);
initialized = true;
} else {
checkTargetState();
}
}
private void checkTargetState() {
if (target == null) {
System.out.println("找不到数据");
}
}
}
public interface HibernateProxy {
}
public class Custerinform {
private String id;
private String firstName;
private String lastName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
分享到:
相关推荐
8. **延迟加载**:Hibernate的懒加载策略可以在需要时才加载关联对象,提高系统性能。 9. **事件监听器**:允许自定义事件监听器来扩展Hibernate的功能,如在对象保存或更新时触发某些操作。 10. **类型转换**:...
10. **性能优化**:通过对源码的学习,我们可以了解Hibernate是如何进行缓存管理、批处理和延迟加载等性能优化的,这对于提升应用程序的效率至关重要。 总之,深入研究"hibernate-jpa-2.0-api-1.0.1.Final-sources...
1. **延迟加载(Lazy Loading)增强**:Hibernate核心库已经支持延迟加载,但扩展可能提供了更精细的控制,例如按需加载关联的对象集合,减少内存占用和提高性能。 2. **批量操作**:批量插入、更新和删除功能可以...
从官方网站下载的Hibernate源代码,通常包含了最新的开发版本,这对于我们深入学习和调试Hibernate具有很高的价值。 在`hibernate-orm-master`这个压缩包中,我们可以找到以下关键部分: 1. **src/main/java**: 这...
通过深入学习和分析Hibernate ORM 5.0的源代码,开发者不仅能了解其实现原理,还能掌握如何优化性能,解决实际项目中的问题,提升开发效率。理解并熟练运用这些知识,将使你在Java ORM领域更上一层楼。
通过阅读和理解"hibernate-src-3.2.6"的源代码,开发者不仅可以学习到Hibernate的工作流程,还能掌握如何根据项目需求对其进行扩展和定制。同时,这也有助于提升数据库操作的效率,为开发高质量的Java应用打下坚实...
《精通Hibernate源代码》 Hibernate,作为Java领域中广受欢迎的对象关系映射(ORM)框架,使得开发者能够方便地在Java应用中操作数据库。通过深入理解Hibernate的源代码,开发者可以更好地掌握其工作原理,提高开发...
9. **延迟加载**(Lazy Loading):Hibernate支持延迟加载机制,当实体的一部分属性或关联对象没有立即使用时,不会立即加载,而是等到实际需要时再加载,从而优化性能。 10. **事件和监听器**:Hibernate允许...
在这个"hibernate学习源代码祝你提高"的资料包中,我们可以深入理解 Hibernate 的工作原理和设计模式,这对于初学者提升技能非常有帮助。该资源主要针对 Hibernate 3.x 版本,这是一个广泛使用的版本,包含了丰富的...
九、延迟加载与立即加载 Hibernate的懒加载机制允许关联对象在需要时才加载,降低内存占用。而立即加载则会在加载主对象时一并加载关联对象,适用于关联数据量不大的场景。 十、事件监听与拦截器 Hibernate提供事件...
- `src/`:源代码,对于学习和理解Hibernate的工作原理非常有帮助。 - `examples/`:示例程序,展示了如何在实际项目中使用Hibernate,是快速上手的好资源。 - `dist/`:包含构建后的可部署包,如jar文件,方便...
此外,书中还会涉及Hibernate的性能优化技巧,如延迟加载、批处理和连接池配置,这些都是实际项目中必不可少的知识。同时,作者可能还会讨论Hibernate与其他技术的集成,如Spring框架的整合,以及如何在分布式环境下...
Hibernate是一个开放源代码的ORM框架,它为Java开发者提供了在Java应用程序中操作数据库的强大工具。通过Hibernate,开发者可以使用面向对象的方式来处理数据,而无需直接编写SQL语句,大大简化了数据库操作。 2. ...
Hibernate ORM 4.3 是一个重要的Java持久化框架,它的源代码对于理解ORM(对象关系映射)机制、数据库交互以及Java开发有着深远的影响。这个版本的发布,为开发者提供了一个深入了解Hibernate内部工作原理的机会。 ...
深入学习Hibernate源代码,可以从以下几个方面入手: 1. **对象关系映射(ORM)基础**:理解Hibernate是如何将Java对象映射到数据库表的,包括注解或XML配置文件的使用,以及实体类和表之间的关系映射。 2. **配置...
此版本`hibernate-release-5.4.10.Final`提供了完整的Hibernate框架,包括源代码,为开发者提供了深入学习和自定义的机会。本文将围绕Hibernate 5.4.10.Final的特性、使用方法以及核心概念展开详细的讨论。 一、...
在学习Hibernate源代码的过程中,我们需要关注以下几个关键知识点: 1. **持久化机制**:Hibernate的核心功能是将Java对象与数据库表之间的映射关系进行管理,理解其持久化机制对于掌握框架至关重要。包括实体类的...
Hibernate采用懒加载策略,延迟加载关联对象,直到真正使用时才加载。这通过代理机制实现,例如,当访问一个设置了懒加载的一对多关系时,实际加载的是代理对象,只有在调用其属性时才会触发数据库查询。 七、事务...
《深入探索Hibernate源代码项目》 Hibernate,作为Java领域中著名的对象关系映射(ORM)框架,极大地简化了数据库操作,使得开发者可以专注于业务逻辑而不是底层的SQL语法。本项目旨在通过对Hibernate源代码的深入...
9. **延迟加载(Lazy Loading)**:Hibernate通过代理对象实现关联对象的懒加载,只在真正需要时才从数据库中获取数据。 10. **事件监听器**:Hibernate提供了预加载、加载、保存、更新、删除等事件监听机制,可以...