Hibernate 和快照

 

 

8.Oracle中的数据类型

                       

9.Oracle中的伪列

Rowid和RowNum

Rowid

 

Rownum:在内存中形成一个不断裂的自增列

--最重要的。就是Oracle分页

我想要emp中的第二页数据,4--6

 

9.Oracle分页三层嵌套  :性能最高

select * from

(

   Select emp.*,rownum as rn

   from

   (

     select * from emp 

    )emp

    where  rownum<=9

)

where rn>=7

这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,
这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。

10.第一个入门案例

1.构建了一个Student实体类

public class Student {

    private Integer id;

    //name

    private String name;

    //age

    private Integer age;

}

2.构建一个大配置

 在src根目录下书写

Hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<<hibernate-configuration>

   <session-factory>

        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>

        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>

        <property name="connection.username">sb</property>

        <property name="connection.password">sb</property>

       

        <!-- 输出所有 SQL 语句到控制台。 -->

        <property name="hibernate.show_sql">true</property>

       

        <!-- 在 log 和 console 中打印出更漂亮的 SQL。 -->

        <property name="hibernate.format_sql">true</property>

        <!-- 方言 -->

        <property name="hibernate.dialect">    org.hibernate.dialect.Oracle10gDialect</property>

   

       <!-- 关联小配置 -->

      

   </session-factory>

 

</hibernate-configuration>

  

3.构建小配置,和实体类对应的

  Student.hbm.xml

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

 <hibernate-mapping package="cn.happy.entity">

     <class name="Student" table="Student">

         <id name="id" type="int" column="id">

         </id>

         <property name="name" type="string" column="name"/>

         <property name="age" type="int" column="age"/>

     </class>   

 </hibernate-mapping>

 

4.测试代码

  对session进行探究。

  Session.save(stu);

  package cn.happy.test;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;

import org.junit.Test;

 

import cn.happy.entity.Student;

 

public class H_01Test {

  @Test

  public void testAdd(){

      //1.1构建一个学生对象

      Student stu=new Student();

      stu.setAge(18);

      stu.setName("2016年8月28日09:21:09训练营");

      stu.setId(3);

     

      //1.2 找到和数据库的接口      xxx========session--->sessionFactory--->configure.buildSessionFactory()

      //咱们要想打通和db通道

      Configuration cf=new Configuration().configure("hibernate.cfg.xml");

      SessionFactory factory = cf.buildSessionFactory();

      Session session = factory.openSession();

      Transaction tx = session.beginTransaction();

     

     

      //1.3保存  

      session.save(stu);

      tx.commit();

      session.close();

  }

   

}

11.ORM

Object Relational Mapping 对象/关系 映射

 

 

 

 

         
   
   

Object(对象)Java

   

 

   

Java实体类

   

Public class Student{

   

      Priavte Integer age;

   

      Private Integer id;

   

      Private String name;

   

}

   

 

   
   
         
   
   

Mapping (hbm配置文件)

   

<class name=”Student” table=”Student”>

   

      <id name=”id” column=”id”>

   

      </id>

   

      <property name=”name” column=”name”/>

   

</class>

   
   
         
   
   

Relational(关系)  DB

   

关系型数据库

   

Sql sever mysql oracle

   

Student

   

  Id    Number

   

      Age       Number

   

      Name  nvarchar2(32)

   

 

   
   

 

 

 

 

 

 

 

 

 

12.Hibernate定位

 HIbernate是一款实现了ORM思想的框架

 JDO

 TOpLink

 

13.用HIbernate实现删除,修改和查询

/**

    * 1.1 删除学生

    */

   @Test

   public void delTest(){

       Session session = HibernateUtil.getSession();

       Student stu=new Student();

       stu.setId(2);

       Transaction tx = session.beginTransaction();

       session.delete(stu);

       tx.commit();

       HibernateUtil.closeSession();

       System.out.println("del ok!");

   }

   /**

    * 1.2 修改学生

    */

   @Test

   public void updateTest(){

       Session session = HibernateUtil.getSession();

       

       //不被上下文跟踪对象

       /*Student stu=new Student();

       stu.setId(3);

       stu.setName("微冷的雨训练营");*/

       

       //方式二:如何用呗上下文跟踪的方式

       //检索出一条记录,一个实体对象

       Student stu= (Student)session.load(Student.class,3);

       stu.setName("金龙加油!!!!");

 

       Transaction tx = session.beginTransaction();

       session.update(stu);

       tx.commit();

       HibernateUtil.closeSession();

       System.out.println("update ok!");

   }

 

 

Hibernate的一级缓存:快照区

现在我们详细的说一下一级缓存的结构

 
session就会维护我们的一级缓存
 
session的内部是有一系列java的集合的
 
我们要怎样才能看到集合里面的东西呢?
 
断点运行的时候
 
session是一个接口,我们使用的都是这个session
05-Hibernate的一级缓存:快照区 里面提供的实现类是SessionImpl,其实 我们在这里面就可以看到很多的内容
05-Hibernate的一级缓存:快照区 actionQueue就是java的集合,是一个活动队列,他记录了一些插入的信息,更新的次数,删除的信息。
 
05-Hibernate的一级缓存:快照区
 
里面其实还有map集合的
 
这个你可以去查看它的源代码
 
 
Ctrl+Shift+T
05-Hibernate的一级缓存:快照区
 
它是在我们核心包hibernate3.jar包下
05-Hibernate的一级缓存:快照区
 
这个当然是实现了session这个接口
 
 
它这里面有很多的这种集合
里面有很多的集合才构成了一级缓存
 
 
一级缓存里面是有一个非常特殊的区域的,叫做快照区,快照区有什么用呢?
持久态对象能自动去更新数据库,其实是完全依赖里面的快照区的,相当于把你的数据照了一个快照,快照放在它的一个区域里面,它提交的时候都会与快照去匹配,快照区的原理是会去比对你的数据是否一致,如果不一致,就会自动更新数据出来,就会自动更新数据库,其实是完全依赖了它的快照区
 
 
 
深入去理解一级缓存的结构
 
 
我要更新,更新我不要调用update,就可以自动完成更新
05-Hibernate的一级缓存:快照区
 
 
我现在查询,还是这两个
我现在还是把第一条记录改成hibernate3
05-Hibernate的一级缓存:快照区
 
然后我还是在加一个断点运行
05-Hibernate的一级缓存:快照区
 
我们现在DeBug
然后在这里执行get查询方法会发送sql查询语句
05-Hibernate的一级缓存:快照区
05-Hibernate的一级缓存:快照区
我只要commit就会发送update语句了
05-Hibernate的一级缓存:快照区
 
05-Hibernate的一级缓存:快照区 然后我们现在看一下数据库 已经完成更新了
 
 
05-Hibernate的一级缓存:快照区
 
 
 
现在我再运行这个程序
 
数据中原来就是Hibernate3
现在程序里设置的名字也是hibernate3
05-Hibernate的一级缓存:快照区
 
执行get是查询,是会发查询sql语句的
05-Hibernate的一级缓存:快照区 05-Hibernate的一级缓存:快照区
但是我执行下面提交commit就没有sql的update语句了
 
它是智能的,如果你的数据不一致就更新,如果一致就不更新
 
 
这都是依赖我们一级缓存的快照区域
 
 
结合程序的运行来看
 
 
hibernate一级缓存的快照区
 
我现在让它不一样
05-Hibernate的一级缓存:快照区
 
这个时候是和数据库中的内容是不一样的
 
 
 
现在我们还是运行程序
 
 
我们现在看一下session的结构,session主要是由java集合组成的
 
只有手动调用update的时候,actionQueue里面才有值的,所以这也是一级缓存的数据
05-Hibernate的一级缓存:快照区
 
我们只要调用get方法查一下,就会往一级缓存里面放数据,这里面其实还有一块区域是map集合。
 
05-Hibernate的一级缓存:快照区
 
 
entityEntries里面有map
05-Hibernate的一级缓存:快照区
 
map里面有一个table
 
 
 
05-Hibernate的一级缓存:快照区
 
actionQueue必须手动去调update,里面才会有东西,这个叫活动队列,persistentContext才是真正缓存的区域,一级缓存是用map来构成的,map的key是我们的一级缓存区,value是快照区,一开始执行了一次查询,
 
key里面有book,book里面查出有作者id,name,price。这是我们数据库里面的数据
 
value里面有一个loadstate,我们可以看到这里面也有数据
05-Hibernate的一级缓存:快照区
 
05-Hibernate的一级缓存:快照区
 
 
value就是它的快照区
 
当我setName的时候
05-Hibernate的一级缓存:快照区
 
 
它改变的是一级缓存的值,而不是改变快照区的值。
 
这个时候向下执行你可以看到变化
05-Hibernate的一级缓存:快照区 key里面的值发生变化了
而value里面还是hibernate3 没有变
05-Hibernate的一级缓存:快照区
 
 
 
就是快照是不会变的
 
 
但是当事务一提交的时候就可以更新数据库了,不提交的话数据库是不会变的,其实这里只有快照区变的时候数据库才会变。
 
 
不是更新快照区,而是比对你的快照区,和你的一级缓存区key里面是否一致,如果一直就不更改,如果不一致就更新,所以这里我们可以看到一个具体的结构。
 
 
我们把代码放过来一起看看的更清楚一点
 
当我调用get方法一查询的时候,向我的一级缓存区和快照区都缓存了一个,当你一执行查询的时候,数据往一级缓存里面放一个,往快照里面也放一个,当我一set的时候,改变了我们一级缓存区的数据,就是把原来的hibernate3改变成spring3,一级缓存spring3里面就改成了hibernate3了,当我做事务提交的时候,commit的时候回去比对一级缓存区key和快照区value是否相等,当我们事务提交的时候,它会去比对一级缓存区和快照区的值是否一致,如果一致了就不更新了,如果你的一级缓存区和快照区一样,就不更新,如果不一致,就会更新我们的数据库,现在我的数据变成了Spring了
05-Hibernate的一级缓存:快照区
 
当我们下一次再来运行程序的时候就不更新了
原来是spring3,现在还是spring3
一执行查询,在persistenceContext里面,key就是我们一级缓存的区域,value的loadstate里面,这里面就是我们的快照区,现在都是一样,都是spring3,当我执行get的时候还是spring3,value里面也是spring3,当你再一提交的时候,没有update,一级缓存中是有这么一个区域存在的,就是我们的快照区,
 
 
 
 
我们自动更新数据库,都是依赖hibernate中的一级缓存的快照区
 
 
深入理解一级缓存的快照区
 
05-Hibernate的一级缓存:快照区
 
 
 
事务提交的时候就会更新数据库了
 
 
 
 
 
 
 
 
 

 

posted @ 2016-08-29 14:34  吴玄坤  阅读(1514)  评论(0编辑  收藏  举报