`
zy8643954
  • 浏览: 23784 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

学习hibernate的源代码-------对象属性延迟加载

阅读更多

自己参考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;
	}
}
分享到:
评论

相关推荐

    hibernate-release-5.2.10

    8. **延迟加载**:Hibernate的懒加载策略可以在需要时才加载关联对象,提高系统性能。 9. **事件监听器**:允许自定义事件监听器来扩展Hibernate的功能,如在对象保存或更新时触发某些操作。 10. **类型转换**:...

    hibernate-jpa-2.0-api-1.0.1.Final-sources

    10. **性能优化**:通过对源码的学习,我们可以了解Hibernate是如何进行缓存管理、批处理和延迟加载等性能优化的,这对于提升应用程序的效率至关重要。 总之,深入研究"hibernate-jpa-2.0-api-1.0.1.Final-sources...

    hibernate-extensions-2.1.3

    1. **延迟加载(Lazy Loading)增强**:Hibernate核心库已经支持延迟加载,但扩展可能提供了更精细的控制,例如按需加载关联的对象集合,减少内存占用和提高性能。 2. **批量操作**:批量插入、更新和删除功能可以...

    hibernATE的源代码

    从官方网站下载的Hibernate源代码,通常包含了最新的开发版本,这对于我们深入学习和调试Hibernate具有很高的价值。 在`hibernate-orm-master`这个压缩包中,我们可以找到以下关键部分: 1. **src/main/java**: 这...

    hibernate-orm-5.0源代码

    通过深入学习和分析Hibernate ORM 5.0的源代码,开发者不仅能了解其实现原理,还能掌握如何优化性能,解决实际项目中的问题,提升开发效率。理解并熟练运用这些知识,将使你在Java ORM领域更上一层楼。

    hibernate-src-3.2.6.rar

    通过阅读和理解"hibernate-src-3.2.6"的源代码,开发者不仅可以学习到Hibernate的工作流程,还能掌握如何根据项目需求对其进行扩展和定制。同时,这也有助于提升数据库操作的效率,为开发高质量的Java应用打下坚实...

    精通Hibernate源代码

    《精通Hibernate源代码》 Hibernate,作为Java领域中广受欢迎的对象关系映射(ORM)框架,使得开发者能够方便地在Java应用中操作数据库。通过深入理解Hibernate的源代码,开发者可以更好地掌握其工作原理,提高开发...

    hibernate-release-5.4.21.Final.zip

    9. **延迟加载**(Lazy Loading):Hibernate支持延迟加载机制,当实体的一部分属性或关联对象没有立即使用时,不会立即加载,而是等到实际需要时再加载,从而优化性能。 10. **事件和监听器**:Hibernate允许...

    hibernate学习源代码祝你提高

    在这个"hibernate学习源代码祝你提高"的资料包中,我们可以深入理解 Hibernate 的工作原理和设计模式,这对于初学者提升技能非常有帮助。该资源主要针对 Hibernate 3.x 版本,这是一个广泛使用的版本,包含了丰富的...

    hibernate_orm-master

    九、延迟加载与立即加载 Hibernate的懒加载机制允许关联对象在需要时才加载,降低内存占用。而立即加载则会在加载主对象时一并加载关联对象,适用于关联数据量不大的场景。 十、事件监听与拦截器 Hibernate提供事件...

    hibernate-distribution-3.3.2.GA-dist.zip

    - `src/`:源代码,对于学习和理解Hibernate的工作原理非常有帮助。 - `examples/`:示例程序,展示了如何在实际项目中使用Hibernate,是快速上手的好资源。 - `dist/`:包含构建后的可部署包,如jar文件,方便...

    精通Hibernate+源代码

    此外,书中还会涉及Hibernate的性能优化技巧,如延迟加载、批处理和连接池配置,这些都是实际项目中必不可少的知识。同时,作者可能还会讨论Hibernate与其他技术的集成,如Spring框架的整合,以及如何在分布式环境下...

    hibernate-release-5.0.12.Final.rar

    Hibernate是一个开放源代码的ORM框架,它为Java开发者提供了在Java应用程序中操作数据库的强大工具。通过Hibernate,开发者可以使用面向对象的方式来处理数据,而无需直接编写SQL语句,大大简化了数据库操作。 2. ...

    hibernate-orm-4.3.zip

    Hibernate ORM 4.3 是一个重要的Java持久化框架,它的源代码对于理解ORM(对象关系映射)机制、数据库交互以及Java开发有着深远的影响。这个版本的发布,为开发者提供了一个深入了解Hibernate内部工作原理的机会。 ...

    深入浅出Hibernate源代码.rar

    深入学习Hibernate源代码,可以从以下几个方面入手: 1. **对象关系映射(ORM)基础**:理解Hibernate是如何将Java对象映射到数据库表的,包括注解或XML配置文件的使用,以及实体类和表之间的关系映射。 2. **配置...

    hibernate-release-5.4.10.Final.zip

    此版本`hibernate-release-5.4.10.Final`提供了完整的Hibernate框架,包括源代码,为开发者提供了深入学习和自定义的机会。本文将围绕Hibernate 5.4.10.Final的特性、使用方法以及核心概念展开详细的讨论。 一、...

    深入浅出hibernate源代码

    在学习Hibernate源代码的过程中,我们需要关注以下几个关键知识点: 1. **持久化机制**:Hibernate的核心功能是将Java对象与数据库表之间的映射关系进行管理,理解其持久化机制对于掌握框架至关重要。包括实体类的...

    hibernate源代码的zip文件

    Hibernate采用懒加载策略,延迟加载关联对象,直到真正使用时才加载。这通过代理机制实现,例如,当访问一个设置了懒加载的一对多关系时,实际加载的是代理对象,只有在调用其属性时才会触发数据库查询。 七、事务...

    Hibernate源代码项目

    《深入探索Hibernate源代码项目》 Hibernate,作为Java领域中著名的对象关系映射(ORM)框架,极大地简化了数据库操作,使得开发者可以专注于业务逻辑而不是底层的SQL语法。本项目旨在通过对Hibernate源代码的深入...

    hibernate项目源代码

    9. **延迟加载(Lazy Loading)**:Hibernate通过代理对象实现关联对象的懒加载,只在真正需要时才从数据库中获取数据。 10. **事件监听器**:Hibernate提供了预加载、加载、保存、更新、删除等事件监听机制,可以...

Global site tag (gtag.js) - Google Analytics