当我学完这个之后 我仿佛都懂了 = =或许这就是 hibernate的力量吧.

操纵持久化对象(Session)

1.1. 在hibernate中java对象的状态

Hibernate 把对象分为 4 种状态:

¨       持久化状态,

¨       临时状态,

¨       游离状态,

¨       删除状态.

Session 的特定方法能使对象从一个状态转换到另一个状态

1.2. 临时对象(transient)

¨       在使用代理主键的情况下, OID 通常为 null

¨       不处于 Session 的缓存中

¨       在数据库中没有对应的记录

1.2.1.  删除对象(Removed)

¨       OID 不为 null

¨       从一个 Session实例的缓存中删除

¨       Session 已经计划将其从数据库删除, Session 在清理缓存时, 会执行 SQL delete 语句, 删除数据库中的对应记录

¨       一般情况下, 应用程序不该再使用被删除的对象

1.2.2.  持久化对象(也叫”托管”)(Persist)

1.2.3.

¨       OID 不为 null

¨       位于 Session 缓存中

¨       持久化对象和数据库中的相关记录对应

¨       Session 在清理缓存时, 会根据持久化对象的属性变化, 来同步更新数据库

¨       在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象

1.2.4.  游离对象(也叫”脱管”)(Detached)

¨       OID 不为 null

¨       不再处于 Session 的缓存中

¨       一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录

1.2.5.  对象的状态转换说明(图)

对象的状态转换图

测试hibernatejava对象的状态

程序代码

生命周期

状态

tx = session.beginTransaction();

Customer c = new Customer);

开始生命周期

临时状态

Session.save(c)

处于生命周期中

转变为持久化状态

Long id=c.getId();

c = null;

Customer c2 = (Customer)session.load(Customer.class,id);

tx.commit();

处于生命周期中

处于持久化状态

session.close();

处于生命周期中

转变为游离态

c2.getName();

处于生命周期中

处于游离态

c2 = null;

结束生命周期

结束生命周期

 

1.2.6.  对象的状态总结

 

 

Session缓存存在对应的记录

数据中存在对应的记录

临时态

no

no

持久态

yes

可能有也可能没有

游离态

no

可能有(数据没有删除)也可能没有

 

1.2.7.  操纵持久化对象的方法(Session中)

1.2.8.  save()

Session 的 save() 方法使一个临时对象转变为持久化对象。

¨       Session 的 save() 方法完成以下操作:

  • 把 News 对象加入到 Session 缓存中, 使它进入持久化状态
  • 选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID. 在使用代理主键的情况下, setId() 方法为 News 对象设置 OID 使无效的.
  • 计划执行一条 insert 语句,把Customer对象当前的属性值组装到insert语句中

¨       Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当 News 对象处于持久化状态时, 不允许程序随意修改它的 ID

@Test

    public void save() throws Exception{

       Session session = sessionFactory.openSession();

       Transaction tc = null;

       User user = null;

       try {

           tc = session.beginTransaction();

           user = new User();//临时状态

           user.setName("张张");

           session.save(user);//持久化状态

           tc.commit();

       } catch (Exception e) {

           tc.rollback();

           throw e;

       }finally{

           session.close();

       }

       user.setName("王王");//游离状态

       System.out.println(user.getName());

    }

1.2.9.      update()

Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句。

 

@Test

    public void update() throws Exception{

       Session session = sessionFactory.openSession();

       Transaction tc = null;

       User user = null;

       try {

           tc = session.beginTransaction();

           user = (User) session.get(User.class, 1);

           //session.clear();

           //session.evict(user);//清楚某一个对象。

           user.setName("冯芬1");

           //session.update(user);//执行完才提交给数据库

           session.flush();//一执行立即提交

           System.out.println("执行");

           tc.commit();

       } catch (Exception e) {

           tc.rollback();

           throw e;

       }finally{

           session.close();

       }

  }Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句。

若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update(更新之前先查询) 设为 true. 该属性的默认值为 false

当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常

原因是:两个不同的对象拥有相同的OID

当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常

1.2.10.     saveOrUpdate()

该方法同时包含save和update方法,如果参数是临时对象就用save方法,如果是游离对象就用update方法,如果是持久化对象就直接返回。

判定对象为临时对象的标准

¨       Java 象的 OID 为 null

¨       映射文件中为 <id> 设置了 unsaved-value 属性, 并且 Java 对象的 OID 取值与这个 unsaved-value 属性值匹配(在hbn3中基本用不到了)

@Test

    public void saveOrUpdate() throws Exception {

       Session session = sessionFactory.openSession();

       Transaction tc = null;

       User user = null;

       try {

           tc = session.beginTransaction();

           //临时对象执行插入

//        user = new User();

//        user.setName("洋洋");

//        session.saveOrUpdate(user);

           //游离对象执行修改

//        user  = (User) session.get(User.class,1);

//        session.evict(user);

//        session.saveOrUpdate(user);

           //如果是持久化对象就直接返回,不执行操作

           user  = (User) session.get(User.class,1);

           session.saveOrUpdate(user);

           tc.commit();

       } catch (Exception e) {

           tc.rollback();

           throw e;

       }finally{

           session.close();

       }

    }

如果参数是临时对象就会用save方法

如果是游离对象就用update方法

如果是持久化对象就直接返回,不执行操作

判定对象为临时对象的标准

¨       Java 对象的 OID 为 null

¨       映射文件中为 <id> 设置了 unsaved-value 属性, 并且 Java 对象的 OID 取值与这个 unsaved-value 属性值匹配,执行插入操作

根据以上判断临时对象的标准id=null是临时对象。但可以定义属性为int  id

* 此时id默认值是0而不是null,应该执行更新操作

* 但实际我们要执行的插入操作。这时,可以在id中设置unsaved-value=0(默认值)

1.2.11.     get()、load()

都可以根据给定的 OID 从数据库中加载一个持久化对象

@Test

    public void getOrLoad() throws Exception {

       Session session = sessionFactory.openSession();

       Transaction tc = null;

       User user = null;

       try {

           tc = session.beginTransaction();

           //get方式会马上执行sql语句

           user  = (User) session.get(User.class,1);

           System.out.println("aaaaa");

           System.out.println(user.getName());

           //load方式不会马上执行sql语句

           user  = (User) session.load(User.class,2);

           System.out.println("bbbbbbbbbbbb");

           System.out.println(user.getName());

           tc.commit();

       } catch (Exception e) {

           tc.rollback();

           throw e;

       }finally{

           session.close();

       }

            }

区别:

¨       当数据库中不存在与 OID 对应的记录时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null

¨       两者采用不同的延迟检索策略

get():获取数据,是持久化状态

1. 会生成:select ... where id=?

2. 会马上执行sql语句

3. 如果数据不存在,就返回null

load():获取数据,是持久化状态

1.会生成:select ... where id=?

2. load()后返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能了。

3.让懒加载失效的方式:一、把实体写成final的;二、在hbm.xml中写<class ... lazy="false">

4. 不会马上执行sql语句,而是在第1次使用非id或class属性时执行sql。

5. 如果数据不存在,就抛异常:ObjectNotFoundException

1.2.12.     delete()

Session 的 delete() 方法既可以删除一个游离对象, 也可以删除一个持久化对象。

¨       如果参数是持久化对象,就执行一个delete语句,若为游离对象,先使游离对象被session关联,使他变为持久化对象

¨       计划执行一条 delete 语句

¨       把对象从 Session 缓存中删除, 该对象进入删除状态.

1.2.13.     与触发器协同工作

Session.save(c);

Session.flush();

Session.refresh(c);

------------------------------------------------------

触发器的行为导致缓存与数据库中的数据不一致。解决办法是执行完

操作后,立即调用session的flush方法和refresh方法,迫使缓存与

数据库同步。

Session的update操作方法盲目的激活触发器

如果游离状态的对象的属性和数据库一致,则更新操作是多余的。

为避免这种情况:

<class name=“” table=“” select-before-update=“true”>

……

</class>

1.2.14.     DML(数据操作语言)风格的操作

,Hibernate 提供通过 Hibernate 查询语言(HQL)来执行大

批量 SQL 风格的 DML 语句的方法。

UPDATE 和 DELETE 语句的伪语法为:( UPDATE | DELETE ) FROM? EntityName (WHERE

where_conditions)?。

要注意的事项:

•在 FROM 子句(from-clause)中,FROM 关键字是可选的

•在 FROM 子句(from-clause)中只能有一个实体名,它可以是别名。如果实体名是别名,那么

任何被引用的属性都必须加上此别名的前缀;如果不是别名,那么任何有前缀的属性引用都是

非法的。

•不能在大批量 HQL 语句中使用 joins 连接(显式或者隐式的都不行)。不过在 WHERE 子句中

可以使用子查询。可以在 where 子句中使用子查询,子查询本身可以包含 join。

•整个 WHERE 子句是可选的。

使用 Query.executeUpdate() 方法执行一个 HQL UPDATE语句

由 Query.executeUpdate() 方法返回的整型值表明了受此操作影响的记录数量

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

String hqlDelete = "delete Customer c where c.name = :oldName";

// or String hqlDelete = "delete Customer where name = :oldName";

int deletedEntities = s.createQuery( hqlDelete )

.setString( "oldName", oldName )

.executeUpdate();

tx.commit();

session.close();

6.HQL介绍

SQL(表和字段)  HQL(对象和属性)

使用HQL查询

HQL: Hibernate Query Language.

特点:

1,与SQL相似,SQL中的语法基本上都可以直接使用。

2,SQL查询的是表和表中的列;HQL查询的是对象与对象中的属性。

3,HQL的关键字不区分大小写,类名与属性名是区分大小写的。

4,SELECT可以省略.

案例:

1,简单的查询

hql = "FROM Employee";

hql = "FROM Employee AS e";   使用别名

hql = "FROM Employee e";   使用别名,as关键字可省略

执行查询

List list = session.createQuery(hql).list();

显示结果

while(itr.hasNext()){

                                     //System.out.println(itr.next().getName());

                                     Object[] object =  (Object[]) itr.next();

                                     System.out.println(object[0]+":"+object[1]);

                            }

2,带上过滤条件的(可以使用别名):Where

 hql = "FROM Employee WHERE id<10";

                     hql = "FROM Employee e WHERE e.id<10";

                     hql = "FROM Employee e WHERE e.id<10 AND e.id>5";

3,带上排序条件的:Order By

        hql = "FROM Employee e WHERE e.id<10 ORDER BY e.name";

                     hql = "FROM Employee e WHERE e.id<10 ORDER BY e.name DESC";

                     hql = "FROM Employee e WHERE e.id<10 ORDER BY e.name DESC, id ASC";

4,指定select子句(不可以使用select *)

   hql = "SELECT e FROM Employee e";   相当于"FROM Employee e"

                     hql = "SELECT e.name FROM Employee e";   只查询一个列,返回的集合的元素类型就是这个属性的类型

                     hql = "SELECT e.id,e.name FROM Employee e";   查询多个列,返回的集合的元素类型是Object数组

                     hql = "SELECT new Employee(e.id,e.name) FROM Employee e";   可以使用new语法,指定把查询出的部分属性封装到对象中

5,执行查询,获得结果(list、uniqueResult、分页 )

Query query = session.createQuery("FROM Employee e WHERE id<3");

                     query.setFirstResult(0);

                     query.setMaxResults(10);

                     List list = query.list();   查询的结果是一个List集合

                     Employee employee = (Employee) query.uniqueResult();  查询的结果是唯一的一个结果,当结果有多个,就会抛异常

                     System.out.println(employee);

6,函数的使用

hql = "select count(id) from Department";

                            Number num =  (Number) session.createQuery(hql).uniqueResult();

                            System.out.println(num);

7,分组查询

hql = "select d.name,count(d.name) from Department d group by d.name";

hql = "select d.name,count(d.name) from Department d group by d.name having count(d.name)>5";

8,参数查询

第一种:使用“?”

hql = "from Department d where d.id between ? and ? ";

List list = session.createQuery(hql)

                            .setParameter(0, 2)

                            .setParameter(1, 8)

                            .list();

第二种:使用变量名

    hql = "FROM Employee e WHERE id BETWEEN :idMin AND :idMax";

                   List list = session.createQuery(hql)//

                   .setParameter("idMax", 15)//

                   .setParameter("idMin", 5)//

         .list();

第三种:当参数是集合时,使用setParameterList()设置参数值

      hql = "FROM Employee e WHERE id IN (:ids)";

                   List list = session.createQuery(hql)//

                   .setParameterList("ids", new Object[] { 1, 2, 3, 5, 8, 100 })//

                   .list();

9在映射文件配置HQL语句

为了使程序具有更大的灵活性,Hibernate可以在映射文件中配置HQL语句。如下所示为在Student.hbm.xml中的配置。

<hibernate-mapping>

     <class name="hibernate.ch06.Student" table="student" catalog="joblog">

          <!--此处省略了配置-->

     </class>

     <query name="searchStudent"><![CDATA[

     from Student s where s.sage>22

     ]]>(<![CDATA[  ]]>表示一些特殊字符不需要转义)

     </query>

</hibernate-mapping>

可以用如下代码访问配置文件中的HQL语句。

Session session=HibernateSessionFactory.currentSession();//创建Session

        Query query=session.getNamedQuery("searchStudent");                   //用getNamedQuery得到查询

        List list=query.list();                                                   //执行查询

        Iterator it=list.iterator();

        while(it.hasNext()){

               Student stu=(Student)it.next();

               System.out.println(stu.getSname());

        }

其中,getNamedQuery()函数用来访问映射文件Student.hbm.xml中配置的HQL语句,参数为配置的名称。

Select s.id,s.name, c.name from t_student s,t_classes c where c.id = s.classId

Select s.id,s.name, c.name from t_student s right join t_classes c on s.classtId = c.id;

10.连接查询

   //第一种:(内连接)

                            //hql = "select s.id,s.name,c.name from Student s join s.classes c";

                            //第二种:

                            //hql = "select s.id,s.name,s.classes.name from Student s";

                            //外连接:

hql = "select s.id,s.name,c.name from Student s right join s.classes c";

hql = "select s.id,s.name,c.name from Student s left join s.classes c";

11.更新

             //更新前:

                            Student student = (Student)session.get(Student.class, 2);

                            System.out.println(student.getName());

                            int num = session.createQuery("update Student s set s.name=? where s.id=2")

                            .setParameter(0,"好人1")

                            .executeUpdate();

                            System.out.println(num);

                            //更新后:

                            session.refresh(student);

                            System.out.println(student.getName());

12.删除

/*int num1 = session.createQuery("delete Student s  where s.id=1")

                            .executeUpdate();

                            System.out.println(num1);*/ 

Criteria查询方式

// 创建Criteria对象

         Criteria criteria = session.createCriteria(Student.class);

                            // 增加过滤条件

                            criteria.add(Restrictions.ge("id", 2));

                            criteria.add(Restrictions.le("id", 5));

                            // 增加排序条件

criteria.addOrder(Order.desc("id"));

                            criteria.addOrder(Order.desc("name"));

                                                        // 执行查询

                            // criteria.setFirstResult(0);

                            // criteria.setMaxResults(100);

                            // criteria.uniqueResult();

                            // criteria.list()

                            List list = criteria.list();

                            Iterator  itr = list.iterator();

                            while(itr.hasNext()){

                                     Student student = (Student)itr.next();

                                     System.out.println(student.getName()+":"+student.getScore());

                            }

写完了 今天落枕了 起床也是在床底睁开眼  歪着脖子写了折磨一一篇, 真难受啊 不过这质量算是我写过最棒的一篇了吧.

hibernate深度学习 游离状态 HQL的更多相关文章

  1. 时间序列深度学习:状态 LSTM 模型预测太阳黑子

    目录 时间序列深度学习:状态 LSTM 模型预测太阳黑子 教程概览 商业应用 长短期记忆(LSTM)模型 太阳黑子数据集 构建 LSTM 模型预测太阳黑子 1 若干相关包 2 数据 3 探索性数据分析 ...

  2. 时间序列深度学习:状态 LSTM 模型预測太阳黑子(一)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/kMD8d5R/article/details/82111558 作者:徐瑞龙,量化分析师,R语言中文 ...

  3. Hibernate框架学习(八)——查询-HQL语法

    一.单表查询 1.基础语法 2.排序 3.条件 4.分页 5.聚合 6.投影 二.多表查询 1.回顾原生SQL 1>交叉连接-笛卡尔积(避免)select * from A,B; 2>内连 ...

  4. hibernate学习(三) hibernate中的对象状态

    hibernate对象的状态分为三种:  游离状态,持久化状态,瞬时状态 下面一行代码区分: Configuration   cfg=new Configuration().configure(); ...

  5. hibernate框架学习笔记4:主键生成策略、对象状态

    创建一个实体类: package domain; public class Customer { private Long cust_id; private String cust_name; pri ...

  6. hibernate实体对象的三种状态:自由状态,持久状态,游离状态.

    自由态与游离态的区别: 当一个持久化对象,脱离开Hibernate的缓存管理后,它就处于游离状态,游离对象和自由对象的最大区别在于,游离对象在数据库中可能还存在一条与它 对应的记录,只是现在这个游离对 ...

  7. hibernate学习系列-----(4)hibernate基本查询上篇:HQL基本查询

    紧接着上一篇,今天继续hibernate的学习总结,来聊一聊hibernate的基本查询方法,先说说HQL(hibernate Query Language):它是官方推荐的查询语言.在开始写代码之前 ...

  8. Hibernate框架学习(三)——实体规则、对象状态、一级缓存

    一.Hibernate中的实体规则 1.实体类创建的注意事项 1)持久化类提供无参数构造,因为在Hibernate的底层需要使用反射生成类的实例. 2)成员变量私有,提供公有的get和set方法,需提 ...

  9. Hibernate基础学习2

    Hibernate基础学习2 测试hibernate的一级缓存,事务以及查询语句 1)Hibernate的一些相关概念 hibernate的一级缓存 1)缓存是为了提高该框架对数据库的查询速度 2)一 ...

随机推荐

  1. VMS项目总结

    开发完一个项目后,如果能够很好的对这个项目做个总结,对我们以后的项目开发以及个人技术的积累都会有很大的帮助.最近在外派公司做完一个系统,在此进行一下深入的总结,也希望给读者带来一些个启示. 一.系统介 ...

  2. 8 个最好的 jQuery 树形 Tree 插件

    由于其拥有庞大,实用的插件库,使得 jQuery 变得越来越流行.今天将介绍一些最好的 jQuery 树形视图插件,具有扩展和可折叠的树视图.这些都是轻量级的,灵活的 jQuery 插件,它将一个无序 ...

  3. 关于如何通过kali linux 攻击以及破解WPA/WPA2无线加密

    http://blog.csdn.net/wingstudio_zongheng/article/details/51435212 1.前期准备 1)打开一个终端  执行命令: ifconfig   ...

  4. DELETE_FAILED_INTERNAL_ERROR Error while Installing APK

    真是Android2.3的特殊版本问题,问题原因是android2.3的instant run的测试版安装方式有所特别,解决办法有2: 1.手动adb install 安装包 2.把Instant r ...

  5. 体育Bank2016会议笔记

    补注:会议全称应该是体育Bank2016体育投融资总裁年会 新华社体育部徐仁基 演讲主题:帮郭川找到大海-->帮民众找到自己真正的体育爱好 激发和培养体育市场是重中之重 将体育培养成生活习惯.生 ...

  6. python数据存储技巧

    1.文本存储 比如我们现在有10篇文章,每篇文章由三部分组成,题目,作者,内容(title,author,content),然后要求这三个部分明确展示出来,并且每篇文章之间用=====分割. 大致思路 ...

  7. Hibernate二级缓存简述及基于Spring4,Hibernate5,Ehcache3的二级缓存配置

    Hibernate L2缓存 缓存的分类 L2缓存工作原理 放入二级缓存的数据 Ehcache 依赖 ehcache.xml 常用的memoryStoreEvictionPolicy(缓存算法) eh ...

  8. Python 描述符是什么?以及如何实现

    先看一个例子,@property.被@property修饰的成员函数,将变为一个描述符.这是最简单的创建描述符的方式. class Foo: @property def attr(self): pri ...

  9. Python_Excel文件操作

    ''' 使用xlrd模块写入Excel文件 ''' import xlrd book=xlrd.open_workbook(r'/Users/c2apple/Desktop/纪录/测试报告/张涛文件盘 ...

  10. mysql workbench EER图,里面的实线以及虚线的关系

    ERWin里面线代表实体间的三种关系:决定关系(Identifying Relationship),非决定关系(None-Identifying Relationship),多对多(Many-To-M ...