zoukankan      html  css  js  c++  java
  • 三、hibernate常用对象

     

    一、自动创建表

    我们可以在hibernate.cfg.xml上配备属性,让hibernate给我们自动创建表。

    <!-- 自动生成表,加载hibernate.cfg.xml文件时,就会根据hbm文件在数据库中创建表,如果已经有此表就删除再创建-->
    
    <property name="hbm2ddl.auto">create</property>
    <!-- 加载hibernate.cfg.xml文件时,就会根据hbm文件在数据库中更新表(如果没表先创建表),即如果hbm文件中有尚未映射过的字段,就往数据库表中再新增此字段,不会删除原有字段-->
    
    <property name="hbm2ddl.auto">update</property>
    <!-- 加载hibernate.cfg.xml文件时,就会根据hbm文件在数据库中创建表,在显式关闭sessionFactory时,就drop掉此表-->
    
    <property name="hbm2ddl.auto">create-drop</property>
    <!-- 每次插入数据之前都会验证数据库中的表结构和hbm文件中是否一致-->
    
    <property name="hbm2ddl.auto">validate</property>

    在开发测试中,配置哪个都可以,但一般生成完数据库就会立即取消此配置。

    二、事务回滚

    如果在事务中有异常,我们是希望数据能够回滚的(不改变)

    public static void updateEmployee() {
    
    //1.获取一个对话
    
    Session session=MySessionFactory.getSessionFactory().openSession();
    
    //2.创建事务
    
    Transaction ts=null;
    
     
    
    try {
    
    ts=session.beginTransaction();
    
    //3.获取要修改的用户,load方法是通过主键属性获取该对象实例
    
    Employee emp=(Employee) session.load(Employee.class, 1);
    
    //4.修改信息
    
    emp.setName("小小名");
    
     
    
    //5.抛出异常
    
    int i=9/0;
    
     
    
    //6提交事务.
    
    ts.commit();
    
    } catch (Exception e) {
    
    // TODO: handle exception
    
    if(ts!=null){
    
    ts.rollback();//事务回滚
    
    }
    
    //抛出一个运行时异常
    
    throw new RuntimeException(e.getMessage());
    
    }finally{
    
    //7.关闭会话
    
    if(session!=null&&session.isOpen()){
    
    session.close();
    
    }
    
    }
    
     
    
    }

    三、configuration和配置文件

    如果把hibernate.cfg.xml移到某个包下,并且更换了名字,就应该这样读取:

    Configuration configuration=
    
    new Configuration().configure("com/myz/config/hibernate.myz.xml");

    可使用hibernate.properties文件来替代hibernate.cfg.xml文件(不建议)

     

    四、SessionFactory(会话工厂)接口

    ①缓存sql语句和某些数据

    ②在应用程序初始化的时候创建,是一个重量级的类(吃内存),一般用单例模式保证一个应用只需要一个SessionFactory实例。

    ③如果某个应用访问多个数据库,则需要创建多个会话工厂实例。

    ④通过SessionFactory接口可以获得Session(会话)实例。

     

     

    五、Session(会话)接口

    Session一个实例代表与数据库的一次操作(当然一次操作可以是crud的组合)

    session是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSession

    Session可以看作是持久化管理器,它是与持久化操作相关的接口。

    ④openSession与getCurrentSession

    Session session=sessionFactory.openSession();//获取一个全新的session

     

    Session session=sessionFactory.getCurrentSession();//获取和当前线程绑定的session,在同一个线程中,我们获取的session是同一个session,这样利于事务控制。但是使用getCurrentSession需要在hibernate.cfg.xml下配置:

    <!-- 能够使用getCurrentSession -->
    
    <property name="current_session_context_class">thread</property>

    openSession与getCurrentSession还有如下区别:

    1.getCurrentSession创建的session会绑定到当前的线程中,而采用openSession创建的session则不会。

    2.getCurrentSession创建的sessioncommitrollback时会自动关闭,而采用openSession创建的session必须手动关闭

    3.getCurrentSession必须做成事务(查询也必须做成事务提交)

    4.getCurrentSession需要在hibernate.cfg.xml文件中加入配置:

    <!-- 与线程绑定,如果使用的是本地事务(jdbc事务) -->
    
    property name="current_session_context_class">thread</property>
    
    <!-- 如果使用的是全局事务(跨数据库的事务) -->
    
    property name="current_session_context_class">jta</property>

     5.

    SessionFactory启动的时候,hibernate会根据配置创建相应的CurrentSessionContext,在getCurrentSession被调用的时候,实际被执行的是:

    CurrentSessionContex.currentSession()。在currentSession()执行时,如果当前session为空,currentSession会调用SessionFactoryopenSession

    Session接口的几个重要方法

    Session一般以对象的形式来操作,这是几个重要方法

    1.保存一个对象(记录)--save方法

    2.删除一个对象(记录)--delete方法

    3.查询一个对象(记录)--get/load方法

    4.修改一个对象(记录)--update方法

    Get()Load()的区别

    Get()方法直接返回实体类,如果查不到则返回nullload()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时,如果数据不存在,则会抛出异常

    Load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找,即不发出sql语句),等后面使用这个代理对象操作的时候,才到DB中查询(发出SQL语句),这就是我们常说的load在默认情况下支持延迟加载(lazy)

    Get先到缓存(session/二级缓存)中去查,如果没有就到DB中去查(立即发出SQL语句)。总之,如果你确定DB中有这个对象就用load(),不确定就用get()。这样效率高。

    举例(查询一个不存在的记录)

    Employee emp=(Employee) session.get(Employee.class, 8);
    
    //发出了SQL语句
    
     
    
    Employee emp=(Employee) session.load(Employee.class, 8);
    
    //没发出SQL语句,没抛出异常
    
     
    
    Employee emp=(Employee) session.get(Employee.class, 8);
    
    System.out.println(emp);
    
    //发出了SQL语句,并打出null
    
     
    
    Employee emp=(Employee) session.load(Employee.class, 8);
    
    System.out.println(emp);
    
    //发出了SQL语句,之后抛出运行时异常

    从上面我们可以看出,load方法是比较懒一些的,我们不使用查询到的对象时,它便不发出SQL语句去查询到底是否有这个对象。

    这是因为load在默认情况下是支持延迟懒加载的(lazy),我们可以在Employee.hbm.xml中关闭延迟加载。

    <class name="Employee" table="employee" lazy="false">

    此时load方法,查询时也会立即发出SQL语句到数据库中查询。

     
    Employee emp=(Employee) session.get(Employee.class, 8);
    
    //发出了SQL语句,之后抛出了异常

    六、缓存机制详解

    注意:二级缓存需配置使用,否则仅有一级缓存。

    Load方法查询:先到session缓存里查,如果没有则去二级缓存里查。如果二级缓存还没有查到,则不再往下查,返回一个代理对象。如果之后需要用到查询得到的对象,则直接发出sql语句去数据库里查,并将查询得到的对象存入二级缓存(根据查询次数的增多可能会被移动到一级缓存)

    举例:

    Employee emp=(Employee) session.load(Employee.class, 1);
    
    System.out.println(emp.getName());
    
    Employee emp2=(Employee) session.load(Employee.class, 1);
    
    System.out.println(emp2.getHireDate());
    
    //以上两句查询语句,仅产生了一条SQL语句,因为第二次是从二级缓存中取得的

    Get方法查询:先到session缓存里查,如果没有则去二级缓存里查。如果二级缓存还查不到则立即发出SQL语句到数据库查询,并将查询得到的对象存入二级缓存(根据查询次数的增多可能会被移动到一级缓存)

    举例:

    Employee emp=(Employee) session.load(Employee.class, 1);
    
    System.out.println(emp.getName());
    
    Employee emp3=(Employee) session.get(Employee.class, 1);
    
    System.out.println(emp3.getName());
    
    //以上两句查询语句仅产生了一条SQL语句
  • 相关阅读:
    uboot如何检测XC2440是从Nand或Nor启动
    uboot中的快捷菜单的制作说明
    Android存储数据方式
    SharedPreferences详解
    (转载)Android理解:显式和隐式Intent
    使用 Fresco加载图片
    script "text/template"
    网页动画插件---Super Scrollorama , TweenMax 和skrollr
    Android控件之HorizontalScrollView 去掉滚动条
    android编程取消标题栏方法(appcompat_v7、Theme.NoTitleBar)
  • 原文地址:https://www.cnblogs.com/myz666/p/8423572.html
Copyright © 2011-2022 走看看