Hiberante(九) 二级缓存(自己加入缓存)

 

使用二级缓存的步骤
		1、hibernate并没有提供相应的二级缓存的组件,所以需要加入额外的二级缓存包,常用的二级缓存包是ECHcache
		2、在hibernate.cfg.xml中配置开启二级缓存
		<!-- 设置二级缓存为true -->
				<property name="hibernate.cache.use_second_level_cache">true</property>
				<!-- 设置二级缓存所提供的类 -->
				<property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
				<!-- 在hibernate4.0之后需要设置facotory_class -->
				<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
		3、设置相应的ehcache.xml文件,在这个文件中配置二级缓存的参数,并且将文件在cfg文件中配置
		<!-- 说明ehcache的配置文件路径 -->
				<property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>
		4、开启二级缓存
			在xml的配置中设置
			<cache usage="read-only"/>
		5、二级缓存缓存的是对象,它是把所有的对象缓存到内存中,一定注意是基于对象的缓存
		
		6、查询缓存是针对HQL语句的缓存,查询缓存仅仅只会缓存id而不会缓存对象

  

@Test
	public void test01() {
		Session session = null;
		try {
			/**
			 * 此时会发出一条sql取出所有的学生信息
			 */
			session = HibernateUtil.openSession();
			Student stu = (Student)session.load(Student.class, 1);
			System.out.println(stu.getName()+",---");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
		try {
			session = HibernateUtil.openSession();
			session.beginTransaction();
			/**
			 *此时session已经关闭了,但是Student在二级缓存中,所以也不会发出SQL语句
			 */
			Student stu = (Student)session.load(Student.class, 1);
			//会报错,因为二级缓存设置为read-only
//			stu.setName("abc");
			System.out.println(stu.getName()+",---");
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
	}
	
	
	@Test
	public void test03() {
		Session session = null;
		try {
			/**
			 * 此时会发出一条sql取出所有的学生信息
			 */
			session = HibernateUtil.openSession();
			List<Student> ls = session.createQuery("from Student")
					.setFirstResult(0).setMaxResults(50).list();
			Iterator<Student> stus = ls.iterator();
			for(;stus.hasNext();) {
				Student stu = stus.next();
				System.out.println(stu.getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
		
		try {
			session = HibernateUtil.openSession();
			session.beginTransaction();
			/**
			 *此时session已经关闭了,但是Student在二级缓存中,所以也不会发出SQL语句
			 */
			Student stu = (Student)session.load(Student.class, 1);
			//会报错,因为二级缓存设置为read-only
//			stu.setName("abc");
			System.out.println(stu.getName()+",---");
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
	}
	
	@Test
	public void test04() {
		Session session = null;
		try {
			/**
			 * 此时会发出一条sql取出所有的学生信息
			 */
			session = HibernateUtil.openSession();
			List<Object[]> ls = session.createQuery("select stu.id,stu.name from Student stu")
					.setFirstResult(0).setMaxResults(50).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
		
		try {
			session = HibernateUtil.openSession();
			session.beginTransaction();
			/**
			 *以上代码仅仅取了id和name,而二级缓存是缓存对象的,所以上一段代码不会将对象加入二级缓存
			 *此时就是发出相应的sql
			 */
			Student stu = (Student)session.load(Student.class, 1);
			//会报错,因为二级缓存设置为read-only
//			stu.setName("abc");
			System.out.println(stu.getName()+",---");
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
	}
	
	@Test
	public void test05() {
		Session session = null;
		try {
			/**
			 * 此时会发出一条sql取出所有的学生信息
			 */
			session = HibernateUtil.openSession();
			List<Object[]> ls = session.createQuery("select stu from Student stu")
					.setFirstResult(0).setMaxResults(50).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
		
		try {
			session = HibernateUtil.openSession();
			/**
			 * 由于学生的对象已经缓存在二级缓存中了,此时再使用iterate来获取对象的时候,首先会通过一条
			 * 取id的语句,然后在获取对象时去二级缓存中,如果发现就不会再发SQL,这样也就解决了N+1问题
			 * 而且内存占用也不多
			 */
			Iterator<Student> stus = session.createQuery("from Student")
					.setFirstResult(0).setMaxResults(50).iterate();
			for(;stus.hasNext();) {
				Student stu = stus.next();
				System.out.println(stu.getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
	}
	
	@Test
	public void test06() {
		Session session = null;
		try {
			/**
			 * 此时会发出一条sql取出所有的学生信息
			 */
			session = HibernateUtil.openSession();
			List<Object[]> ls = session.createQuery("select stu from Student stu")
					.setFirstResult(0).setMaxResults(50).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
		
		try {
			session = HibernateUtil.openSession();
			/**
			 * 使用List会发出两条一模一样的sql,此时如果希望不发sql就需要使用查询缓存
			 */
			List<Student> ls = session.createQuery("select stu from Student stu")
					.setFirstResult(0).setMaxResults(50).list();
			Iterator<Student> stus = ls.iterator();
			for(;stus.hasNext();) {
				Student stu = stus.next();
				System.out.println(stu.getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateUtil.close(session);
		}
	}
	

 

你可能感兴趣的:(二级缓存)