懒加载_缓存_批量更新


懒加载 _session.load懒加载_一对一懒加载_one-to-many(元素)懒加载_many-to-one(元素)懒加载_many-to-many(元素)懒加载:

缓存_一级缓存,Session级共享_二级缓存_配置_ 查看缓存信息_清除二级缓存_分布式二级缓存_分布式缓存和中央缓存。

 批量更新

 

asm和cglib两个包实现;Domian是非final的

1.session.load懒加载

一般用在关联数据时。

    session = HibernateUtil.getSession();
   idCard = (IdCard) session.load(IdCard.class, id);
   employee.setDepartment(idCard);

2.一对一懒加载

懒加载只对从对象出现,主对象使用时,不会出现懒加载

必须同事满足下面三个条件时才能实现懒加载

(主表不能有constrained=true,所以主表没有懒加载)

lazy!=false(默认lazy="proxy",使用代理)  2)constrained=true 3)fetch=select (默认)

 

3.one-to-many(元素)懒加载:

 1.lazy!=false 2.fetch=select

 

4.many-to-one(元素)懒加载:

 1.lazy!=false 2.fetch=select

 

5.many-to-many(元素)懒加载:

 1.lazy!=false 2.fetch=select

 

6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,

  访问这些懒加载对象(代理对象)的属性(getId和getClass除外)

Hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象:

如:

	public Employee query(int empId, boolean includeDepart) {
		Session session = null;
		Employee employee = null;
		try {
			session = HibernateUtil.getSession();
			employee = (Employee) session.get(Employee.class, empId);
		/********************初始化代理对象********************************/
			if (includeDepart) {
				Hibernate.initialize(employee.getDepartment());
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return employee;
	}


 

当相关联的session关闭后,再访问懒加载的对象将出现异常

 

 

缓存

缓存的作用主要用来提高性能,可以简单的理解成一个Map;

使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。

 

 

一级缓存,Session级共享

save,update,saveOrUpdate,load,get,list,iterate,lock,这些方法都会将对象放在一级缓存中,

※一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;

可以用evict,clear方法清楚缓存中的内容

session.evict(user);
session.clear();


 

二级缓存_配置



1、配置 hibernate.cfg.xml

		<!-- 设置使用缓存,默认就是启用的 -->
		<property name="cache.use_second_level_cache">true</property>
		<!-- 使用那种缓存,以及使用的包 -->
		<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>


		<!-- 配置缓存的类,也可以在类的配置文件中配置(根据DTD规范加载mapping后面) -->
		<class-cache usage="read-only" class="com.dwt1220.Employee" />



<class-cache class="com.dwt.Employee" usage="read-write"/>中

usage 值 

    read-only 这个类只读取,不修改

    read-write 读取和修改

    nonstrict-read-write 不严谨的读取和修改,如:可能会吞帖。

    transactional 使用事物回滚功能,(一般没有这功能)

 

2.、添加缓存框架使用的配置文件(放入Classpath中)

                        这里使用的是OS缓存。添加

                       oscache.properties 文件

                        缓存文件中有默认属性,需要配置的是cache.capacity=1000 缓存的对象数

 

3、类的映射文件中配置类缓存

在ID标签前添加<cache usage="read-write"/>

	<class name="Employee">
		<cache usage="read-write" />
		<id name="id">
			<generator class="hilo" />
		</id>
		<property name="name" />
	</class>


 查看缓存信息

在hibernate.cfg.xml中添加 hibernate.generate_statistics

<property name="hibernate.generate_statistics">true</property>

 

Test.java中

Statistics statistics= HibernateUtil.getSessionFactory().getStatistics();
System.out.println("Hit:"+statistics.getSecondLevelCacheHitCount());
System.out.println("Put:"+statistics.getSecondLevelCachePutCount());
System.out.println("Miss:"+statistics.getSecondLevelCacheMissCount());


清除二级缓存

evict()方法

HibernateUtil.getSessionFactory().evict(user.class);
HibernateUtil.getSessionFactory().evict(user.class,id);


分布式缓存

配置(oscache.properties)

 #cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;mcast_send_buf_size=150000;mcast_recv_buf_size=80000):PING(timeout=2000;num_initial_members=3):MERGE2(min_interval=5000;max_interval=10000):FD_SOCK:VERIFY_SUSPECT(timeout=1500):pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800):pbcast.STABLE(desired_avg_gossip=20000):UNICAST(timeout=5000):FRAG(frag_size=8096;down_thread=false;up_thread=false):pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)


中央缓存。

使用缓存的条件
1.读取大于修改。
2.数据量不能超过内存容量。
3.对数据要有独享的控制。
4.可以容忍出现无效数据。

 

 

批量更新

 
flush时将一级缓存与数据库同步
 
大批处理

  大量操作数据时可能造成内存溢出,解决办法如下:

  1.清除session中的数据

  for(int i=0;i<100000;i++)session.save(obj);

  for(int i=0;i<100000;i++){

  session.save(obj);

  if(i% 50 == 0){session.flush();  session.clear();}

  }

  2.用StatelessSession接口:它不和一级缓存、二级缓存交互,也不触发任何事件、监听器、拦截器,通过该接口的操作会立刻发送给数据库,与JDBC的功能一样。

  StatelessSession s = sessionFactory.openStatelessSession();该接口的方法与Session类似。

 

 3.Query.executeUpdate()执行批量更新,会清除相关联的类二级缓存(sessionFactory.evict(class)),也可能会造成级联,和乐观锁定出现问题

你可能感兴趣的:(thread,数据库,Hibernate,session,Class,statistics)