Hibernate入门

it2023-03-29  75

1.1Hibernate简介 1.1.1Hibernate的创始人Gavin King 1.1.1.1EJB 3.0专家委员会成员 1.1.1.2JBoss核心成员之一 1.1.1.3《Hibernate in Action》的作者 1.1.2优秀的Java持久化层解决方案(全自动ORM框架) 1.1.3主流的对象-关系映射工具 1.2Hibernate优点 1.2.1简化了JDBC 繁琐的编码 1.2.2对面向对象特性支持良好 1.2.3可移植性好 1.3Hibernate缺点(Hibernate一般只适用于小项目开发,提高开发效率) 1.3.1不适合需要使用数据库的特定优化机制的情况 1.3.2不适合大规模的批量数据处理 1.4使用Hibernate的步骤 1.4.1准备Hibernate的Jar包 基本Jar包结构

1.4.2编写hibernate核心配置文件hibernate.cfg.xml 1.4.2.1从官方zip包中找到模板文件

1.4.2.2修改内容可以参考官方文档提供的模板

搜索:

<!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> <!-- Database connection settings --> <property name="connection.driver_class">oracle.jdbc.OracleDriver</property> <property name="connection.url"> jdbc:oracle:thin:@//localhost:1521/orcl </property> <property name="connection.username">scott</property> <property name="connection.password">tiger</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- 执行Hibernate API时显示执行的SQL语句 --> <property name="show_sql">true</property> <!-- 格式化SQL语句 --> <property name="format_sql">true</property> <!-- Drop and re-create the database schema on startup --> <!-- <mapping resource="org/hibernate/tutorial/domain/Event.hbm.xml" /> --> </session-factory> </hibernate-configuration>

修改对应数据库的连接和用户名密码,方言等信息。(示例为Oracle11g数据库配置)

1.4.3创建持久化类和映射文件 持久化类要求: 1、实现Serializable接口 2、属性类型与数据库兼容 3、生成getter和setter方法 4、默认构造函数

映射文件Xxx.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> <!-- 配置类型映射,table表示表名,name表示类名 --> <class table="`DEPT`" name="com.entity.Dept" > <!-- id表示主键列,name是属性名,column是列名,type是指定java类型 --> <id name="deptNo" column="`DEPTNO`" type="int"> <!-- generator节点是生成主键的策略,常用increment,sequence,identity,native,uuid 等 --> <!-- increment是使用Max查出表主键最大值+1,优点跨数据库 --> <generator class="increment"></generator> </id> <!-- property表示普通列 --> <property name="dName" column="`DNAME`" type="string"></property> <property name="loc" column="`LOC`" type="string"></property> </class> </hibernate-mapping>

1.4.4构建Hibernate的核心对象

public class HibernateUtil { private static SessionFactory sessionFactory = null; static{ // 配置文件路径 try { Configuration cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); sessionFactory = cfg.buildSessionFactory(); } catch (Throwable e) { e.printStackTrace(); } } public static Session openSession(){ // 立刻开启一个session对象 return sessionFactory.openSession(); } public static Session currSession(){ // 获取当前session对象 return sessionFactory.getCurrentSession(); } public static void closeSession(Session session){ // 关闭session try { if(session != null && session.isOpen()){ session.close(); } } catch (HibernateException e) { e.printStackTrace(); } } }

1.4.5操作session方法(增删改查)

@Test public void testGet(){ try { Session session = HibernateUtil.openSession(); Transaction trans = session.beginTransaction(); Dept dept = (Dept) session.get(Dept.class, 10); System.out.println("=============================="); System.out.println(dept); System.out.println(dept.getDname()); HibernateUtil.closeSession(session); trans.commit(); } catch (Exception e) { e.printStackTrace(); } }

1.5使用Hibernate执行增删查改操作 1.5.1openSession和getCurrentSession的区别 1.5.1.1openSession每次打开新的会话,getCurrentSession默认是线程级别,在同一个线程中每次获取都是同一个,除非关闭了再次调用则产生新会话。 1.5.1.2如果使用openSession,查询可以不开启事务,但是getCurrentSession即使查询也需要事务。

1.5.2load和get的区别 1.5.2.1当数据存在的情况,get会立刻执行sql语句查出数据,load会先返回一个动态代理对象,此对象没有加载任何数据,当调用某个属性时才会去查询数据库加载数据。 1.5.2.2当数据不存在时,get会获取到null对象,所以使用属性时报空指针异常,load由于已经有代理对象,但是内部的target对象获取不到,则报一个ObjectNotFoundException。

1.5.3更新对象(session.update(object)) 1.5.3.1使用load或get获取到数据库中的数据(持久状态数据),直接修改属性,提交事务即可完成修改。 1.5.3.2自己new对象,但是要保证主键必须设置,否则无法更新。

1.5.4删除对象(session.delete(object) 类似更新的两种方式,但是都必须调用delete方法)

1.6Hibernate对象的三种状态 1.6.1临时状态(瞬时状态),数据库中没有此条数据,只存在于内存中。 1.6.2持久状态,数据库和内存中的数据同步的时候。 1.6.3游离状态(脱管状态),数据库中有此数据,但是数据有没有被session管理的情况。

三种状态相互转化调用的方法示意图:

1.7Hibernate脏检查 1.7.1脏检查机制 Session脏检查步骤,当一个Dept对象被加入到Session缓存中,此时为持久状态,Session会为Dept对象的值类型的属性复制一份快照。当Session清理缓存时,会先进行脏检查,即比较Dept对象的当前属性与它的快照,来判断Dept对象的属性是否发生了变化,如果发生了变化,就称这个对象是“脏对象”,Session会根据脏对象的最新属性来执行相关的SQL语句,从而同步更新数据库。

1.7.2刷新缓存机制 刷新缓存就是将数据库同步为与Session缓存一致,刷新缓存时会执行脏检查 Session会在以下时间点刷新缓存 调用Session的flush()方法 调用Transaction的commit()方法

1.8Hibernate的更新相关方法 1.8.1update方法 1.8.2saveOrUpdate方法 当对象存在主键值时,调用update方法 当对象不存在主键值时(null),调用insert方法

1.8.3merge方法(机制比较复杂,了解就好) 1.8.3.1new一个对象 如果该对象设置了ID,则这个对象就当作游离态处理:

 当ID在数据库中不能找到时,用update的话肯定会报异常,然而用merge的话,就会insert。

当ID在数据库中能找到的时候,update与merge的执行效果都是更新数据,发出update语句;

如果没有设置ID的话,则这个对象就当作瞬态处理:

 用update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID

最新回复(0)