Hibernate学习笔记之Session-API实现CRUD以及get&load&merge方法

本文主要介绍以下三个方面:
1.使用Session-API CRUD操作
2.get()/load()的区别
3.saveOrUpdate()/merge()的区别

1.session.save(obj)
a.当前对象如果是持久态,执行save方法,会发送update语句;
b.当前对象如果是瞬时态,执行save方法,会发送insert语句,对象会从瞬时态转为持久态。

    /*session.save(obj);
             * 当前对象是持久态时,执行save方法,会执行Update语句
             * 当前对象是瞬时态时,执行save方法,会执行insert语句,从瞬时态转换为持久态 
             * */
@Test
    public void testSave() {

        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        try {

              Students s = new Students();          
              //s为瞬时态
              s.setSname("lisi");
              session.save(s);//会执行insert语句,s变成持久态

            //Students s = (Students)session.get(Students.class, 1);
            //get到的s为持久态

            Students s = new Students();

            s.setSid(1);
            s.setSname("zhangsan2");            
            session.save(s);

            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }   
    }   
@Test
    public void testSave() {

        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        try {

            Students s = (Students)session.get(Students.class, 1);
            //get到的s为持久态

            s.setSid(1);
            s.setSname("zhangsan2");            
            session.save(s);//此时执行update语句

            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }   
    }   

2.get()和load()的区别
a.get方法创建对象时首先查询session缓存,没有的话查询二级缓存,最后查询数据库;load方法创建对象时首先查询session缓存,没有的话就创建代理,实际使用数据时才查询二级缓存和数据库;
b.如果找不到符合条件的记录,get方法返回null,而load方法抛出异常(ObjectNotFoundException);
c.使用load方法,一般都是假定你要取得的对象肯定是存在的,而get方法则会去尝试,如果对象不存在,就返回null。

@Test
    public void testGet(){
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        try {

            //执行get后,变成持久态,立刻发送SQL语句            
            //Students s = (Students)session.get(Students.class, 1);
            Students s1 = (Students)session.get("PersistenceClass.Students", 0);
            System.out.println("学号:"+s1.getSid()+"姓名:"+s1.getSname());

            //由于s2和s1生成的对象相同,故直接查找session缓存,不再发送SQL语句
            Students s2 = (Students)session.get("PersistenceClass.Students", 0);
            System.out.println("学号:"+s2.getSid()+"姓名:"+s2.getSname());

            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }       
    }

这里写图片描述
这里写图片描述

@Test
    public void testLoad(){

        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        try {

            //执行load后,生成代理对象,当用到对象的属性或者方法时,才发送SQL语句         
            //Students s = (Students)session.get(Students.class, 1);
            Students s1 = (Students)session.load("PersistenceClass.Students", 0);
            System.out.println("学号:"+s1.getSid()+"姓名:"+s1.getSname());

            //由于s2和s1生成的对象相同,故直接查找session缓存,不再发送SQL语句
            Students s2 = (Students)session.load("PersistenceClass.Students", 0);
            System.out.println("学号:"+s2.getSid()+"姓名:"+s2.getSname());

            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }       
    }

这里写图片描述
这里写图片描述

总结:
a.从两种方法的调试情况可以看出,get每次生成的都是持久态对象,load每次生成的都是代理对象(Students_$$_javassist_0);
b.虽然最后的执行结果相同,但是,load方法只有在使用到对象的属性和方法时,才会发送SQL语句,而get在创建对象时就立刻发送SQL语句。

3.Update()
a.瞬时态不能执行update();
b.持久态和托管态可以执行update();
c.代理对象在session对象关闭后不能执行update()。

@Test
    public void testUpdate(){
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Students s = null;
        try {

            /*瞬时态对象不能调用update方法
             * Students s = new Students();
             * s.setSid(2);
             * s.setSname("lisi");
             * session.update(s);
             * */


            /*持久化对象可以调用update
             * Students s = (Students)session.load("PersistenceClass.Students", 1);
            s.setSname("lisi");
            session.update(s);*/

            s = (Students)session.get(Students.class, 1);

            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }   

        /*getCurrentSession()可以在执行try...catch...语句后自动关闭session,此时s变为托管状态*/
        //下面重新开启一个session
         session = sessionFactory.getCurrentSession();
         tx = session.beginTransaction();
         s.setSname("wanglaowu");
         session.update(s); //s重新变成了持久态     
         tx.commit();

    }

4.从瞬时态转换为持久态,不确定是否存在主键冲突,推荐使用saveOrUpdate()。

@Test
    public void testSaveOrUpdate(){

        //测试SaveOrUpdate时需要将数据库的主键生成策略改为"assigned"
        //从瞬时态转换为持久态,不确定主键是否冲突,推荐使用SaveOrUpdate
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        try {

            Students s = new Students();

            s.setSid(1);
            s.setSname("lisi");         
            session.saveOrUpdate(s);

            /*
             * s.getSid(1);
             * s.setSname("lisi");
             * session.save(s);
             * 此时由于主键1已经存在,执行save方法,故会产生主键冲突
             * 
             * */           
            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }               
    }

5.delete()
a.持久态或者托管态可以执行delete();
b.瞬时态可以执行delete(),但是Hibernate并不推荐使用delete()删除瞬时态对象,因为这样做没有任何意义。

@Test
    public void testDelete(){

        //持久态或者托管态可以执行delete方法
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        try {

            Students s = (Students)session.get(Students.class, 1);
            session.delete(s);

            tx.commit();

        } catch (Exception e) {

            e.printStackTrace();
            tx.rollback();          
        }                               
    }

6.Merge()
a.使用merge方法,如果数据库中有该记录,则更新该记录,如果不存在该记录,则进行insert操作。使用saveOrUpdate()的话和此方法相同;
b.执行完merge(obj)返回一个持久化对象的引用,而实参obj本身还是托管状态的;
c.saveOrUpdate()后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对象不会纳入session管理,再次查询该对象还是会从数据库中取。

@Test
    public void testMerge(){


                Session session = sessionFactory.getCurrentSession();
                Transaction tx = session.beginTransaction();

                try {

                    Students s1 = new Students();
                    s1.setSid(1);
                    s1.setSname("lisi");
                    Students s2 = (Students)session.merge(s1);
                    System.out.println(s1.hashCode());//s1还是托管的
                    System.out.println(s2.hashCode());//s2是持久化的

                    tx.commit();

                } catch (Exception e) {

                    e.printStackTrace();
                    tx.rollback();          
                }       
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值