zoukankan      html  css  js  c++  java
  • 二级缓存&批量处理&管理session

    二级缓存

    package helloworld;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
    import org.hibernate.service.ServiceRegistryBuilder;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    public class TestHello {
    	
    	private SessionFactory sessionFactory;
    	private Session sess;
    	private Transaction trans;
    	
    	@Before
    	public void before(){
    		Configuration configuration = new Configuration().configure();
    		ServiceRegistry registry = new ServiceRegistryBuilder()
    										.applySettings(configuration.getProperties())
    										.buildServiceRegistry();
    		sessionFactory = configuration.buildSessionFactory(registry);
    		sess = sessionFactory.openSession();
    		trans = sess.beginTransaction();
    	}
    	
    	@After
    	public void after(){
    		trans.commit();
    		sess.close();
    		sessionFactory.close();
    	}
    	/**1,二级缓存使用方法(helloworld)
    	 * 导入对应的ehcache的jar包
    	 * 写ehcache.xml
    	 * 在cfg.xml中配置(三条)
    	 * <property name="hibernate.cache.use_second_level_cache">true</property>
    	 * <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    	 * <class-cache usage="read-write" class="helloworld.Employee"/><!-- 这条也可以在对应hbm.xml中配置<cache usage="read-write"/> -->
    	 * 
    	 * 
    	 * 类级别的缓存
    	 * */
    	@Test
    	public void testSecondCache() {
    		Employee e = (Employee) sess.get(Employee.class, 2);
    		System.out.println(e.getName());
    		
    		trans.commit();
    		sess.close();
    		sess = sessionFactory.openSession();
    		trans = sess.beginTransaction();
    		
    		Employee e2 = (Employee) sess.get(Employee.class, 2);
    		System.out.println(e2.getName());
    	}
    	
    	/**
    	 * 集合级别的缓存(需要建立在集合中的元素的类在二级缓存中的前提上,否则只是缓存了对应的id,会多出n多条查询)
    	 * 
    	 * */
    	@Test
    	public void testCollectionCache() {
    		Department d = (Department) sess.get(Department.class, 1);
    		System.out.println(d.getSet().size());
    		
    		trans.commit();
    		sess.close();
    		sess = sessionFactory.openSession();
    		trans = sess.beginTransaction();
    		
    		Department d2 = (Department) sess.get(Department.class, 1);
    		System.out.println(d2.getSet().size());
    	}
    	
    	/**
    	 * 查询缓存
    	 * 默认情况下, 设置的缓存对 HQL 及 QBC 查询时无效的, 但可以通过以下方式使其是有效的
    
    		I.  在 hibernate 配置文件中声明开启查询缓存
    
    		<property name="cache.use_query_cache">true</property>
    
    		II. 调用 Query 或 Criteria 的 setCacheable(true) 方法
    
    		III. 查询缓存依赖于二级缓存
    	 * */
    	@Test
    	public void testQueryCache() {
    		
    	}
    	/**
    	 * 时间戳缓存
    	 * */
    	
    	
    	
    	/**
    	 * Query 接口的 iterate() 方法
    	 * */
    }
    

    ehcache.xml

    <ehcache>
    
        <!-- Sets the path to the directory where cache .data files are created.
    
             If the path is a Java System Property it is replaced by
             its value in the running VM.
    
             The following properties are translated:
             user.home - User's home directory
             user.dir - User's current working directory
             java.io.tmpdir - Default temp file path -->
        <!-- 当二级缓存需要存放在硬盘上时,在硬盘上存放的位置
        	 当sessionFactory关闭是硬盘上的缓存也会删除	
         -->
        <diskStore path="D:/temp"/>
    
    
        <!--Default Cache configuration. These will applied to caches programmatically created through
            the CacheManager.
    
            The following attributes are required for defaultCache:
    
            maxInMemory       - Sets the maximum number of objects that will be created in memory
            eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                                is never expired.
            timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                                if the element is not eternal. Idle time is now - last accessed time
            timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                                if the element is not eternal. TTL is now - creation time
            overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                                has reached the maxInMemory limit.
    
            -->
        <!-- 设置缓存的 默认 数据过期策略  -->
        <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            />
    
        <!--Predefined caches.  Add your cache configuration settings here.
            If you do not have a configuration for your cache a WARNING will be issued when the
            CacheManager starts
    
            The following attributes are required for defaultCache:
    
            name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
            maxInMemory       - Sets the maximum number of objects that will be created in memory
            eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                                is never expired.
            timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                                if the element is not eternal. Idle time is now - last accessed time
            timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                                if the element is not eternal. TTL is now - creation time
            overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                                has reached the maxInMemory limit.
    
            -->
    
        <!-- Sample cache named sampleCache1
            This cache contains a maximum in memory of 10000 elements, and will expire
            an element if it is idle for more than 5 minutes and lives for more than
            10 minutes.
    
            If there are more than 10000 elements it will overflow to the
            disk cache, which in this configuration will go to wherever java.io.tmp is
            defined on your system. On a standard Linux system this will be /tmp"
            -->
        <!-- 
        	设定具体的命名缓存的数据过期策略。
        	每个命名缓存 代表一个缓存区域
        	
        	缓存区域(region):一个具有名称的缓存块,可以给每一个缓存块设置不同的缓存策略。
        						如果没有设置任何的缓存区域,则所有被缓存的对象,都将使用默认的缓存策略。
        						即:<defaultCache.../>
    		Hibernate在不同的缓存区域保存不同的类/集合。
    			对于类而言,区域的名称是类名。如:helloworld.Department
    			对于集合而言,区域的名称是类名加属性名。如:helloworld.Department.set
        	
         -->
        <cache name="helloworld.Department"
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="300"
            timeToLiveSeconds="600"
            overflowToDisk="true"
            />
    
        <!-- Sample cache named sampleCache2
            This cache contains 1000 elements. Elements will always be held in memory.
            They are not expired. -->
            
        <!--name 设置缓存的名字,它的取值为类的全限定名或类的集合的名字  -->
        <!--maxElementsInMemory 在内存中可以存放的最大条数 -->
        <!--eternal 设置对象是否为永久的,true表示永不过期,此时将忽略timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false  -->
        <!--timeToIdleSeconds 设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态。  -->
        <!--timeToLiveSeconds 设置对象生存最长时间,超过这个时间,对象过期。如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值 -->
        <!--overflowToDisk 设置基于内存的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中  -->
       
            
        <cache name="helloworld.Department.set"
            maxElementsInMemory="1000"
            eternal="true"
            timeToIdleSeconds="0"
            timeToLiveSeconds="0"
            overflowToDisk="false"
            />
    
    	 <cache name="helloworld.Employee"
            maxElementsInMemory="1"
            eternal="false"
            timeToIdleSeconds="300"
            timeToLiveSeconds="600"
            overflowToDisk="true"
            />
        <!-- Place configuration for your caches following -->
    
    </ehcache>
    

    管理session

    HibernateUtil

    package manageSession;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
    import org.hibernate.service.ServiceRegistryBuilder;
    
    public class HibernateUtil {
    	private HibernateUtil() {
    	}
    
    	private static HibernateUtil instance = new HibernateUtil();
    
    	public static HibernateUtil getInstance() {
    		return instance;
    	}
    
    	private SessionFactory sessionFactory;
    
    	public SessionFactory getSessionFactory() {
    		if (sessionFactory == null) {
    			Configuration configuration = new Configuration().configure();
    			ServiceRegistry registry = new ServiceRegistryBuilder()
    					.applySettings(configuration.getProperties())
    					.buildServiceRegistry();
    			sessionFactory = configuration.buildSessionFactory(registry);
    		}
    		return sessionFactory;
    	}
    	public Session getSession(){
    		return instance.getSessionFactory().getCurrentSession();
    	}
    }
    

    EmployeeDao

    package manageSession;
    
    import org.hibernate.Session;
    
    import helloworld.Employee;
    
    public class EmployeeDao {
    	/**
    	 * 内部获取 Session 对象
    	 * 获取和当前线程绑定的 Session 对象
    	 * 1. 不需要从外部传入 Session 对象
    	 * 2. 多个 DAO 方法也可以使用一个事务!
    	 * */
    	public void save(Employee emp){
    		Session session = HibernateUtil.getInstance().getSession();
    		System.out.println(session.hashCode());
    		
    		session.save(emp);
    	}
    }
    

    TestManageSession

    package manageSession;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import helloworld.Department;
    import helloworld.Employee;
    
    public class TestManageSession {
    
    	@Test
    	public void test() {
    		Session session = HibernateUtil.getInstance().getSession();
    		System.out.println("##"+session.hashCode());
    		Transaction transaction = session.beginTransaction();
    		
    		EmployeeDao dao = new EmployeeDao();
    		
    		Employee e = new Employee();
    		Department dep = new Department();
    		dep.setId(1);
    		e.setDepartment(dep);
    		e.setName("jyf");
    		e.setSalary(50000);
    		
    		dao.save(e);
    		dao.save(e);
    		dao.save(e);
    		
    		//若 Session 是由 thread 来管理的, 则在提交或回滚事务时, 已经关闭 Session 了. 
    		System.out.println(session.isOpen());
    		transaction.commit();
    		System.out.println(session.isOpen());
    	}
    
    }
    

    cfg.xml

    <!-- 配置管理session的方式 -->
    <property name="current_session_context_class">thread</property>
    

    批量处理(建议使用原生的connection进行)

    package batch;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.jdbc.Work;
    import org.hibernate.service.ServiceRegistry;
    import org.hibernate.service.ServiceRegistryBuilder;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    public class TestBatch {
    
    	private SessionFactory sessionFactory;
    	private Session sess;
    	private Transaction trans;
    
    	@Before
    	public void before() {
    		Configuration configuration = new Configuration().configure();
    		ServiceRegistry registry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
    				.buildServiceRegistry();
    		sessionFactory = configuration.buildSessionFactory(registry);
    		sess = sessionFactory.openSession();
    		trans = sess.beginTransaction();
    	}
    
    	@After
    	public void after() {
    		trans.commit();
    		sess.close();
    		sessionFactory.close();
    	}
    
    	/**
    	 * 
    	 * 
    	 * */
    	@Test
    	public void testBatch() {
    		sess.doWork(new Work() {
    			// 最推荐使用原生的JDBC进行批量操作
    			@Override
    			public void execute(Connection connection) throws SQLException {
    				PreparedStatement preparedStatement = connection
    						.prepareStatement("insert into EMPLOYEES (SALARY, NAME, DEPARTMENT_ID)  values (?, ?, ?)");
    				preparedStatement.setInt(1, 1);
    				preparedStatement.setString(2, "JI_BATCH");
    				preparedStatement.setInt(3, 1);
    				preparedStatement.addBatch();
    				preparedStatement.setInt(1, 2);
    				preparedStatement.setString(2, "YUN_BATCH");
    				preparedStatement.setInt(3, 2);
    				preparedStatement.addBatch();
    				preparedStatement.setInt(1, 3);
    				preparedStatement.setString(2, "FEI_BATCH");
    				preparedStatement.setInt(3, 1);
    				preparedStatement.addBatch();
    				preparedStatement.executeBatch();
    			}
    		});
    	}
    }
    

      

      

      

      

      

      

      

  • 相关阅读:
    HDU 3949 XOR
    [JXOI2018]游戏
    树状数组 Binary Indexed Tree/Fenwick Tree
    Java 多线程编程
    概率算法
    最长回文子串 Manacher算法
    动态规划-最长上升子序列 LIS
    流水作业调度
    多机调度问题
    A*搜索算法
  • 原文地址:https://www.cnblogs.com/feifeiyun/p/6485492.html
Copyright © 2011-2022 走看看