03-Hibernate进阶

Hibernate进阶

  • hibernate.cfg.xml常用配置
  • session简介
  • transaction简介
  • session详解
  • 对象关系映射常用配置

hibernate.cfg.xml常用配置

hibernate通过读取hibernate.cfg.xml文件,能够实现连接数据库以及生成表结构。对于该文件常用的配置属性有以下:

  • hibernate.show_sql: 是否把Hibernate运行时的SQL语句输出到控制台

  • hibernate.format_sql:配置输出到控制台的SQL语句是否进行排版

  • hibernate.hbm2ddl.auto:生成表结构的策略,可以取的值有create|update|create-drop|validate

    create表示生成新的表结构,如果存在原有的表结构,会先进行删除然后在进行创建新的表结构。

    update表示在原有的表结构的基础上进行更新。

    create-drop表示先创建在删除。

    validate表示加载hibernate时,验证创建数据库表结构,如果和原来的表结构不同的话则不创建表。

  • hibernate.default_schema:数据库表默认的前缀,如果设置了,则创建表的时候,所有表有前缀。

  • hibernate.dialect:配置数据库的方言,可针对特定的数据库优化。

session简介

hibernate的执行流程

  1. 首先创建一个配置对象Configuration,该配置对象的作用就是用来读取hibernate.cfg.xml这个配置文档。
  2. 使用创建的配置对象来进行创建SessionFactory对象,创建SessionFactory时就会加载关系对象映射文件。
  3. 获得SessionFactory对象之后就可以获取Session对象,Session对象类似于JDBC中的Connection,获得一个Session对象就相当于获得了一个数据库连接对象,那么就可以执行Session对应的增删改查方法。
  4. 在执行某一个具体增删改查方法的时候需要开启事务Transaction
  5. 之后完之后需要先提交事务,然后在关闭Session
//创建配置对象
        Configuration configuration = new Configuration().configure();

        //创建会话工厂对象
        sessionFactory = configuration.buildSessionFactory();
        //会话对象
        session = sessionFactory.openSession();
        //开启事务
        transaction = session.beginTransaction();

在这里插入图片描述

  1. Hibernate也是对JDBC的封装,所以不建议直接使用JDBCconnection直接操作数据库而是通过使用session来操作数据库,可以理解session是操作数据库的对象。

  2. sessionconnection,是多对一的关系,一个session都有一个与之对应的connection,一个connection不同时刻可以供多个session使用

  3. session通过对应的save()``update()``delect()``createQuery()等方法完成增删改查操作。

transaction简介

Hibernate事务默认是不自动提交的,所以在用session对象保存数据时如果不开启事务并主动提交事务,数据并不会真正保存到数据库中的。

  • 开启自动提交功能

    调用sessiondoWork()方法,获得JDBCconnection之后设置其为自动提交模式。

    session.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                connection.setAutoCommit(true);
            }
        });

session详解

  • 获取session的方式

    • sessionFactory.openSession()

    • sessionFactory.getCurrentSession(),该方式需要在hibernate.cfg.xml中做一些配置,

      如果是本地事务(jdbc事务)

      <property name="current_session_context_class">thread</property>

      如果是全局事务(jta事务)

      <property name="current_session_context_class">jta</property>
  • openSessiongetCurrentSession的区别

    • getCurrentSession在事务提交或者回滚之后都会自动关闭,而如果使用openSession没有手动关闭,在多次之后会导致连接池溢出
    //两次connection的hashCode值不同说明第一次使用之后没有释放,那么多次之后就会溢出
    	
     @Test
    public void testSaveBookWithOpenSession() {
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        BooksEntity book = new BooksEntity("209", "zhangdd",
                "Hibernate入门", 0.0, 2016, "Hibernate教程,从入门到精通",
                0);
        session.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                System.out.println(connection.hashCode());
            }
        });
        session.save(book);
        transaction.commit();
    
        //=====================
        Session session1 = sessionFactory.openSession();
        transaction = session1.beginTransaction();
        BooksEntity book1 = new BooksEntity("210", "zhangdd",
                "Hibernate入门", 0.0, 2016, "Hibernate教程,从入门到精通",
                0);
        session1.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                System.out.println(connection.hashCode());
            }
        });
        session1.save(book1);
        transaction.commit();
    }
    //两次connection的hashCode值相同说明第一次使用之后就释放了,第二次可以重新使用
    		
     @Test
    public void testSaveBookWithGetCurrentSession() {
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        session.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                System.out.println(connection.hashCode());
            }
        });
        BooksEntity book = new BooksEntity("209", "zhangdd",
                "Hibernate入门", 0.0, 2016, "Hibernate教程,从入门到精通",
                0);
        session.save(book);
        transaction.commit();
        //=====================
    
        Session session1 = sessionFactory.getCurrentSession();
        transaction = session1.beginTransaction();
        session1.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                System.out.println(connection.hashCode());
            }
        });
        BooksEntity book1 = new BooksEntity("210", "zhangdd",
                "Hibernate入门", 0.0, 2016, "Hibernate教程,从入门到精通",
                0);
        session1.save(book1);
        transaction.commit();
    }
    • openSession每次创建新的session对象,getCurrentSession使用现有的session对象
    @Test
    public void testOpenSession() {
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Session session2 = sessionFactory.openSession();
        System.out.println(session==session2);
        
    }
    @Test
    public void testGetCurrentSession() {
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Session session2 = sessionFactory.getCurrentSession();
        System.out.println(session==session2);
    }

hbm配置文件常用设置

在这里插入图片描述

在这里插入图片描述

  • name:对象关系映射的类
  • table:映射数据库的表
  • batch-size:抓取策略,一次可以抓取多少条数据
  • where:抓取条件
  • entity-name:同一个类映射为多个表