Hibernate_day02(1)

  1. 持久化类的规则

    1.1 什么是持久化类?

        就是一个JavaBean,这个JavaBean与数据库中的表建立了映射关系。这个类就称为是持久化类。简单理解为持久化类=JavaBean+映射文件。

     

    1.2 持久化类的编写规则

    * 提供无参构造方法

    * 提供private属性,getter/setter方法

    * 提供一个唯一标识(OID)的属性与表的主键对应。Java里面使用地址区分是否是同一个对象。数据库中是通过主键区分是否是同一个记录。Hibernate通过唯一标识区分是否在内存中是同一个对象。

    * 实体类不能被final关键字修饰

    * 尽量不要使用基本数据类型

     

    1.3 主键生成策略

    * 自然主键:自然主键指的是类的自身的属性作为主键。相当于将主键暴露给用户,让用户来自定义这个主键

    * 代理主键:代理主键指的是不是类本身的属性作为主键。让程序来维护创建这个主键(推荐使用)

     

    1.4 Hibernate的主键生成策略

        在实体类映射配置文件中配置

    <id name="id" column="id">

    <generator class="主键生成策略"></generator>

    </id>

        increment:由hibernate底层来进行维护,会执行2条SQL,select max(id) from customer获取最大的ID值,再取max(id)+1的值作为插入的ID;有可能发生并发问题

        identity适用于MySQL有自动增长的数据库。sequence适用于有序列数据库Oracle。native叫做本地策略,根据底层的数据库不同自动选择使用identity还是sequence。

 

  1. Hibernate持久化对象的三种状态

 

1.瞬时态(transient)

    持久化对象没有持久化标识OID,对象也没有被Session管理

* 获得瞬时态对象:

    Customer customer = new Customer();

* 转换成持久态对象:

    session.save(customer);

    //session.saveOrUpdate(customer);

* 转换成托管态对象:

    session.setId(1L);

 

2.持久态(persistence)

    持久化对象有持久化标识OID,同时也被Session管理

* 获得持久态对象:

    session.get(Customer.class,1L);

    //session.load(Customer.class,1L);

* 转换成瞬时态对象:

    session.delete(1L);

* 转换成托管态对象:

    session.close();     //关闭session

    //session.clear();        //清空session

    //session.evict(customer); //从session中清除一个对象

    

3.托管态(detached)

    持久化对象有持久化标识OID,但是没有被Session管理

* 获得托管态对象:

    Customer customer = new Customer();

    customer.setId(1L);

* 转换成瞬时态对象:

    customer.setId(null);

* 转换成持久态对象:

    customer.save(customer);

    //session.saveOrUpdate(customer);

 

注意:session对象的saveOrUpdate()方法,如果是托管态/持久态对象就执行update(),并且如果是托管态/持久态对象,但是数据库中并不存在这条数据就报错;如果是瞬时态对象就执行save();

 

 

  1. Hibernate一级缓存

    1.什么是一级缓存

        hibernate的一级缓存就是session缓存,是hibernate为了提升性能而默认使用的;当使用session查询数据时,hibernate会先根据唯一标识OID从缓存中查询,如果查到了就直接返回;如果没有查到再从数据库中进行查询,返回结果,并将结果放入缓存中,以及在hibernate缓存快照区记录第一次从数据库查询出来的结果

        只要session没有被关闭,一级缓存就一直存在

        hibernate执行DDL不会清理缓存,只会在commit()的时候更新缓存;而mybatis则会清理缓存,当再需要数据时就会再发送一条sql

        

    2.一级缓存的特点

    * 调用Session接口的save()/update()/saveOrUpdate()方法,hibernate会自动将对象存储到缓存中,但是不修改缓存快照区的数据,只有commit()才会比对缓存区和缓存快照区

    * 调用Session接口的get()/load()先从缓存中查,没有才从数据库查

    * 调用close()/clear()方法会清空缓存

     

    3.缓存快照区:

        当hibernate将对象保存到缓存中时,会备份一份数据到缓存快照区;当执行commit()方法时,hibernate会比较缓存区的数据和缓存快照区的数据,如果不一致,则执行update;一致则不执行

        以下代码,没有手动执行update(),但是由于缓存区数据跟缓存快照区数据不一致,当执行commit()时,会自动执行update()

    @Test

    public void testCache(){

        transaction.begin();

        Customer customer = session.get();

        customer.setName("李四");

        transaction.commit();

    }

  2. Hibernate事务

    1.hibernate中设置事务隔离级别,配置hibernate.cfg.xml中开启即可

    <!-- 设置事务的隔离级别:

            read uncommitted 1

    read committed 2

    repeatable read 4

    serializable 8 -->

    <property name="hibernate.connection.isolation">4</property>

     

    2.与线程绑定的Session的使用

    在hibernate中开启基于线程的Connection,即:ThreadLocal<Connection>,配置hibernate.cfg.xml中开启即可

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

    获取基于线程绑定的session: sessionFactory.getCurrentSession();通过getCurrentSession()获得的session不需要手动close(),当线程结束会自动关闭

 

  1. Hibernate查询语法

    1.HQL: hibernate query language(面向对象)

    //查询所有

    Query query = session.createQuery("from Customer");

    List<Customer> customerList = query.list();

    //条件查询

    Query query = session.createQuery("from Customer where name = ?");

    query.setString(0,"张三");    //占位符索引,从0开始

    List<Customer> customerList = query.list();

    //分页查询,用法等同于limit

    Query query = session.createQuery("from Customer");

    query.setFirstResult(0);    //开始的索引

    query.setMaxResults(10);    //每页显示的条数    

    List<Customer> customerList = query.list();

     

    2.QBC: Query By Criteria

    //查询所有

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

    List<Customer> customerList = criteria.list();

    //条件查询

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

    criteria.add(Restrictions.eq("name","张三"));

    List<Customer> customerList = criteria.list();

    //分页查询

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

    criteria.setFirstResult(0);

    criteria.setMaxResults(10);

    List<Customer> customerList = criteria.list();

     

    3.SQL: Structured Query Language

    //查询所有

    SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");

    sqlQuery.addEntity(Customer.class);    //使用sql查询不能直接封装到对象中,默认会封装为List<Object[]>

    List<Customer> customerList = sqlQuery.list();

    //条件查询

    //分页查询

posted @ 2020-05-22 14:56  学菜狗  阅读(120)  评论(0)    收藏  举报