Hibernate入门

小新
2022-04-09 / 0 评论 / 140 阅读 / 正在检测是否收录...

Hibernate的优点:

1、对象化。hibernate可以让开发人员以面相对象的思想来操作数据库。jdbc只能通过SQL语句将元数据传送给数据库,进行数据操作。而hibernate可以在底层对元数据和对象进行转化,使得开发者只用面向对象的方式来存取数据即可。

2、更好的移植性。hibernate使用xml或JPA的配置以及数据库方言等等的机制,使得hibernate具有更好的移植性,对于不同的数据库,开发者只需要使用相同的数据操作即可,无需关心数据库之间的差异。而直接使用JDBC就不得不考虑数据库差异的问题。

3、开发效率高。hibernate提供了大量的封装(这也是它最大的缺点),很多数据操作以及关联关系等都被封装的很好,开发者不需写大量的sql语句,这就极大的提高了开发者的开发效率。

4、缓存机制的使用。hibernate提供了缓存机制(session缓存,二级缓存,查询缓存),对于那些改动不大且经常使用的数据,可以将它们放到缓存中,不必在每次使用时都去查询数据库,缓存机制对提升性能大有裨益。

hibernate的缺点主要有以下几点:

一、由于对持久层封装过于完整,导致开发人员无法对SQL进行优化,无法灵活使用JDBC的原生SQL,Hibernate封装了JDBC,所以没有JDBC直接访问数据库效率高。要使用数据库的特定优化机制的时候,不适合用Hibernate
二、框架中使用ORM原则,导致配置过于复杂,一旦遇到大型项目,比如300张表以上,配置文件和内容是非常庞大的,另外,DTO满天飞,性能和维护问题随之而来
三、如果项目中各个表中关系复杂,表之间的关系很多,在很多地方把lazy都设置false,会导致数据查询和加载很慢,尤其是级联查询的时候。
四、Hibernate在批量数据处理时有弱势,对于批量的修改,删除,不适合用Hibernate,这也是ORM框架的弱点

使用Hibernate操作数据库

(1) 读取并解析配置文件及映射文件。

Configuration conf = new Configuration().configure();

(2) 依据配置文件和映射文件中的信息,创建SessionFactory对象。

SessionFactory sf = conf.buildSessionFactory();

(3) 打开Session

Session session = sf.getCurrentSession();
//或者使用 sf.openSession() : 使用这个需要关闭;

(4) 开始一个事务

Transaction tx = session.beginTransaction();

(5) 数据库操作

session.sava(user); //保存方法

(6) 结束事务

tx.commit(); //提交事务 或
tx.rollback(); // 回滚

封装步骤

package com.xyh.util;

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

public class HibernateUtil {
    private static Configuration configuration;
    private final static SessionFactory sessionFactory;
    
    static{
        try {
            configuration = new Configuration().configure();
            sessionFactory = configuration.buildSessionFactory();
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new ExceptionInInitializerError(e);
        }
    }
    
    public HibernateUtil() {}
    
    public static Session currentSession(){
        return sessionFactory.getCurrentSession();
    }
}

这里直接打开了Session 调用直接使用!

使用Hibernate API

向hibernate.cfg.xml文件中配置映射文件

<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!--配后才能使用session=sessionFactory.getCurrentSession();  -->
assigend:忽略自增长,添加时需手动指定主键
native:采用数据库已有的自增长规则
<property name="current_session_context_class">thread</property>

按主键查询

在进行修改或删除操作时,应县加载对象,然后再执行修改或删除操作,

主键查询对象:

  • get(类 , id)
  • load(类, id)

这两个方法的区别之一:
get方法如果没有查询出数据,就会返回null
load方法如果没有查询出数据,就会抛出异常

实现修改,删除

修改和删除操作之前,要先获取到数据

Hibernate对象三种状态

临时状态、持久状态、游离状态

临时状态(Transient):当new一个实体对象后,这个对象处于临时状态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被jre垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save或者SaveOrUpdate把临时对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久对象。

持久状态(Persistent): 持久化对象的实例在数据库中有对应的记录,并拥有一个持久化表示(ID)。对持久化对象进行delete操作后,数据库中对应的记录将被删除,那么持久化对象与数据库记录不再存在对应关系,持久化对象变成临时状态。持久化对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。在同步之前,持久化对象是脏的(Dirty)。

游离状态(Detached):当Session进行了Close、Clear或者evict后,持久化对象虽然拥有持久化标识符和与数据库对应记录一致的值,但是因为会话已经消失,对象不在持久化管理之内,所以处于游离状态(也叫:脱管状态)。游离状态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。

三种状态之间的转换

l1qp2acg.png

脏检查与刷新缓存

脏检查

Transaction tx = HibernateUtil.currentSession().beginTransaction();
//获取部门对象,emp对象处于持久化状态
Emp emp = (Emp) HibernateUtil.currentSession().load(Emp.class, (short)1944);
//修改后,部门信息和之前不同,此时emp对象成为所谓的 脏对象
emp.setEname("小新");
// 提交事务
tx.commit();

刷新缓存

  • 当刷新缓存(调用Session的flush()方法)时,Hiberante会对Session 中持久状态的对象进行监测 ,判断对象的数据是否发生了改变
  • commit() 方法会首先刷新缓存

刷新缓存机制

  • 刷新缓存就是将数据库同步为与Session缓存一致
  • 刷新缓存时会执行脏检查

Session 会在以下时间点刷新缓存

  • Session 的flush()方法
  • 调用Transaction的commit()方法
1

评论 (0)

取消