• Rhythmk 学习 Hibernate 02


    by:rhythmk.cnblogs.com

    1、Hibernate 三种状态:

        1.1、三种定义(个人理解,不一定准确):

             瞬时状态(transient):    被session接管,且不存在数据库中的对象的状态,类似于新New一个对象

             离线状态 (detached):    数据库中存在而不被session接管

             持久化状态(persistent): 对象被session管理且数据库中存在此对象

        1.2、 状态之间转换关系图

    2 、状态转换以及Hibernate数据库执行过程详解:

       2.1  瞬时状态 转换为 持久化对象

       

    	/* 
    		 * 瞬时状态转换成序列化状态
    		 * */
    		
    	
    		Session session = null;
    		try {
    			session = HibernateUtil.getSessionFactory().openSession();
    			session.beginTransaction();
    			User user=new  User();
    			user.setCreateTime(new Date());
    			user.setName("rhythmk");
    			user.setOpenId(10);
    			user.setType("admin");
    			// 此时User为瞬时对象
    			session.save(user);
    			//  通过save方法 user已经转变为持久化对象
    			session.getTransaction().commit();
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (session != null)
    				session.close();
    
    		}
    		
    	}
    

      

     当一个 瞬时对象被转成持久化对象后 ,只要此session会话没有关闭,该对象属性值再发生变化,session提交时候都会去对比该对象于保存时候是否被修改过。

    如果被修改,则将该对象最终结果同步到数据库。

       参考代码如下,进过在转变为持久化对象后进过多次调用update方法,最终生成的SQL语句依然只会有一个Insert与一条Update:

    	@Test
    	public void test2()
    	{
    		
    		Session session = null;
    		try {
    			session = HibernateUtil.getSessionFactory().openSession();
    			session.beginTransaction();
    			User user=new  User();
    			user.setCreateTime(new Date());
    			user.setName("rhythmk");
    			user.setOpenId(10);
    			user.setType("admin");
    			// 此时User为瞬时对象
    			session.save(user);
    			//  通过save方法 user已经转变为持久化对象
    			
    			user.setName("updatename");
    			session.update(user);
    			
    			user.setName("updatename2");
    			session.update(user);
    			
    			user.setName("updatename3");
    			session.update(user);
    			
    			
    			session.getTransaction().commit();
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (session != null)
    				session.close();
    
    		}
    		
    	}
    

      输出:

         Hibernate: insert into user (openId, type, name, createTime) values (?, ?, ?, ?)

            Hibernate: update user set openId=?, type=?, name=?, createTime=? where userId=?

     2.2 、当一个离线对象 通过session.delete方法转换成瞬时对象,此时瞬时对象的值发生变化将不生成同步SQL

           

    @Test
    	public void test3() 
    	{
    
    		Session session = null;
    		try {
    			session = HibernateUtil.getSessionFactory().openSession();
    			session.beginTransaction();
    			User user = new User();
    			user.setCreateTime(new Date());
    			user.setName("rhythmk");
    			user.setOpenId(10);
    			user.setType("admin");
    
    			user.setUserId(12);
    
    			session.delete(user);
    //此时 user成为瞬时状态 以后其属性值的改变不会再生成SQL语句
    			
    			user.setName("updatename");
    			
    			user.setName("updatename3");
    	
    			session.getTransaction().commit();
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (session != null)
    				session.close();
    
    		}
    	}
    		
    		
    

      输出:

             Hibernate: delete from user where userId=?  

    当一个离线状态转换成瞬时状态时,改对象属性值发生变化尽管设定了改对象主键值,再调用session.save方法生成的Insert语句将不关注此主键ID

       

    @Test
    		public void test4() {
    
    			Session session = null;
    			try {
    				session = HibernateUtil.getSessionFactory().openSession();
    				session.beginTransaction();
    				User user = new User();
    				user.setCreateTime(new Date());
    				user.setName("rhythmk");
    				user.setOpenId(9);
    				user.setType("admin");
    
    				user.setUserId(9);
    
    				session.delete(user);
    
    				user.setName("updatename");
    				session.save(user);
    
    				user.setName("updatename3");
    				session.update(user);
    				user.setName("updatename32");
    				session.update(user);
    				user.setName("updatename33");
    				session.update(user);
    				session.getTransaction().commit();
    
    			} catch (Exception e) {
    				e.printStackTrace();
    			} finally {
    				if (session != null)
    					session.close();
    
    			}
    
    	}
    

      

    输出:

    Hibernate: delete from user where userId=?
    Hibernate: insert into user (openId, type, name, createTime) values (?, ?, ?, ?)
    Hibernate: update user set openId=?, type=?, name=?, createTime=? where userId=?

    参考方法:

     session.saveOrupdate(object)

          根据object对象的主键ID判断如果,数据库存在记录则更新,否则添加

    session.merge(object)

          如果session回话中已经存在某主键ID的对象,如果此时再添加一个同主键的新对象进如回话状态,将出现异常  ,

         此情况则可以调用merge方法对session回话中以存在对象进行覆盖:

       如:

            

    session = HibernateUtil.openSession();
                session.beginTransaction();
                //u1已经是持久化状态
                User u1 = (User)session.load(User.class, 3);
                System.out.println(u1.getUsername());
                //u2是离线状态
                User u2 = new User();
                u2.setId(3);
                u2.setPassword("123456789");
                //此时u2将会变成持久化状态,在session的缓存中就存在了两份同样的对象,在session中不能存在两份拷贝,否则会抛出异常
    //            session.saveOrUpdate(u2);
                //merge方法会判断session中是否已经存在同一个对象,如果存在就将两个对象合并
                session.merge(u2);
                //最佳实践:merge一般不用
                session.getTransaction().commit();
    

      

            

    参考:

    http://www.cnblogs.com/xiaoluo501395377/p/3380270.html

  • 相关阅读:
    [iOS微博项目
    [iOS微博项目
    [iOS微博项目
    [iOS微博项目
    [iOS微博项目
    [iOS微博项目
    [iOS微博项目
    COS Javascript 上传图片putObject成功后没有返回ETag?
    模拟一个在线音乐播放程序(socket + 数据库)
    python 基础(while 循环、格式化输出、运算符、编码初识)
  • 原文地址:https://www.cnblogs.com/rhythmK/p/3702894.html
Copyright © 2020-2023  润新知