Hibernate开发的基本步骤?
- 编写配置文档hibernate.cfg.xml
- 编写实体类
- 生成对应实体类的映射文件并添加到配置文件中
- 调用Hibernate API进行测试
Hibernate的执行流程?
HibernateExcuteStep.png自己做的,感觉良好。接下来稍微谈点图里的东东。
hibernate.cfg.xml常用配置
- hibernate.show_sql——是否把Hibernate运行时的SQL语句输出到控制台,编码阶段便于测试。
- hibernate_format_sql——输出到控制台的SQL语句是否进行排版,便于阅读。建设设置为true。
- hbm2ddl.auto——可以帮助java代码生成数据库脚本,进而生成具体的表结构。create|update|create-
drop|validate。 - hibernate.default_schema——默认的数据库。
- hibernate.dialect——配置Hibernate数据库方言,Hibernate可针对特殊的数据库进行优化。
Hibernate中的Session究竟是什么?
如其名,会话。你可以把Session理解成操作数据库的对象。
hibernate.show_sql——是否把Hibernate运行时的SQL语句输出到控制台,编码阶段便于测试。
hibernate_format_sql——输出到控制台的SQL语句是否进行排版,便于阅读。建设设置为true。
hbm2ddl.auto——可以帮助java代码生成数据库脚本,进而生成具体的表结构。create|update|create-drop|validate。
hibernate.default_schema——默认的数据库。
hibernate.dialect——配置Hibernate数据库方言,Hibernate可针对特殊的数据库进行优化。
Hibernate中的Session
你可以把Session理解成操作数据库的对象。
而Connection是jdbc的对象。
Session与Connection是多对一的关系。
如何获取Session对象?
- openSession
- getCurrentSession
如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置:分别可以配置本地事务和全局事务。
openSession和getCurrentSession的区别?
- getCurrentSession在事务提交或者会馆之后会自动关闭,而openSession需要你手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
- openSession每次创建新的Session对象,getCurrentSession使用现有对象。好奇的话,你可以比较一下hashCode( )。
Transaction的概念
hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式。所以用Session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。
如果你想让hibernate像jdbc那样自动提交事务,必须调用Session对象的doWork( )方法,获得jdbc的Connectio后,设置其为自动提交事务模式。当然,一般不建议这么做。
Session中get( )与load( )的区别?
在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回持久化对象。
load方法会在调用后返回一个代理对象——该代理对象只保存了实体对象的id,直到使用对象的非主键时才会发出sql语句。
查询数据库中不存的数据时:get方法返回null,而load则会抛出org.hibernate.ObjectNotFoundException。
ps:关于返回对象的问题。可以尝试获取它的对象——OBJECT.getClass( ).getName( )来获得更加直观的答案。
Hibernate 对象的三种状态
Hibernate对象的状态是基于Session会话的。
临时状态
是指从对象通过new语句创建到被持久化之前的状态,此时对象不在Session的缓存中。
处在此状态的对象具备以下特点:
- 不在Session缓存中,不与任何Session实例相关联。
- 在数据库中没有与之对应的记录。
通常在下列情况下对象会进入临时状态:
- 通过new语句创建新对象。
- 执行delete( )方法,对于游离状态的对象,delete( )方法会将其与数据库中对应的记录删除;而对于持久化状态的对象,delete( )方法会将其与数据库中对应的记录删除,并将其在Session缓存中删除。
例如:Object object = new Object( ); 此时object为临时状态,数据库中没有对应的数据,Session缓存中也没有相关联的实例。
持久化状态
是指对象被持久化到Session对象被销毁之前的状态,此时对象在Session的缓存中。
处在此状态的对象具备以下特点:
- 在Session缓存中,与Session实例相关联。
- 在数据库中有与之对应的记录。
- Session在清理缓存的时候,会根据持久化对象的属性变化更新数据库。
通常在下列情况下对象会进入临时状态:
- 执行save( )或saveOrUpdate( )方法,使临时对象转变为持久化对象。
- 执行upda( )或saveOrUpdate( )方法,使游离对象转变为持久化对象。
- 执行load( )或get( )方法,返回的对象都是持久化对象。
- 执行find( )方法,返回List集合中存放的都是持久化对象。
- 在允许级联保存的情况下,Session在清理缓存时会把与持久化对象关联的临时对象转变为持久化对象。
例如:Session session = factory.openSession( ); object.setName("持久化对象"); session.save(object); 此时object对象为持久化对象,Session缓存中有相关联的实例,数据库中有相应的记录。
游离状态:是指从持久化对象的Session对象被销毁到该对象消失之前的状态,此时对象不在Session的缓存中。
处在此状态的对象具备以下特点:
- 不在Session缓存中,不与任何Session实例相关联。
- 在数据库中有与之对应的记录(前提是没有其他Session实例删除该条记录)。
通常在下列情况下对象会进入临时状态:
- 执行close( )方法,将Session缓存清空,缓存中的所有持久化对象将转变成游离对象。
- 执行evict( )方法,能从缓存中删除一个持久化对象,使之转变成游离对象。
例如:session.close( ); 此时上文的object对象为游离对象,Session缓存中没有有相关联的实例,数据库中有相应的记录。
代码 | 对象的生命周期状态 | 对象的状态 |
---|---|---|
Object object = new Object( ); | 开始生命周期 | 开始生命周期 |
Session session = factory.openSession( ); Transaction tx = session.beginTransaction( ); | 在生命周期中 | 临时状态 |
session.save(object); | 临时状态 | 转变为持久化状态 |
tx.commit( ); | 在生命周期中 | 持久化状态 |
session.close( ); | 在生命周期中 | 转变为游离状态 |
System.out.println(object.getName( )); | 在生命周期中 | 游离状态 |
object = null; | 结束生命周期 | 结束生命周期 |
三种状态在程序的转换过程:
代码 | 对象的生命周期状态 | 对象的状态 |
---|---|---|
Object object = new Object( ); | 开始生命周期 | 开始生命周期 |
Session session = factory.openSession( ); Transaction tx = session.beginTransaction( ); | 在生命周期中 | 临时状态 |
session.save(object); | 临时状态 | 转变为持久化状态 |
tx.commit( ); | 在生命周期中 | 持久化状态 |
session.close( ); | 在生命周期中 | 转变为游离状态 |
System.out.println(object.getName( )); | 在生命周期中 | 游离状态 |
object = null; | 结束生命周期 | 结束生命周期 |
Hibernate 核心接口
在使用Hibernate的时候,我们通常都会用的Configuration、SessionFactory、Session、Transaction、Query和Criteria等接口。通过这些接口可以,不仅可以存储与取出持久化对象,还可以对事务进行管理。下面对着几个接口一一介绍:
Configuration:
Configuration是Hibernate的入口,负责将配置文件信息加载到内存,并创建一个SessionFactory对象,把读入的配置信息加载到SessionFactory对象的内存里。
特点
Configuration对象的作用是除了有读取配置文件的功能,还能创建SessionFactory对象。Configuration对象只存在于系统的初始化阶段,然后所有的持久化操作都能通过这个SessionFactory实例来进行。 Configuration对象只有在Hibernate 进行初始化的时候才需要创建,当使用Configuration对象的实例创建了SessionFactory对象的实例后,其配置信息已经绑定在他返回的SessionFactory对象实例中。因此,一般情况下,得到SessionFactory对象后,Configuration对象的使命就结束了。
用法
属性文件(hibernate.properties):Configuration cfg = new Configuration( ); Xml文件(hibernate.cfg.xml):Configuration cfg = new Configuration( ).configure( );
SessionFactory
SessionFactory负责创建Session实例,每个SessionFactory实例对应一个数据库。SessionFactory是重量级的,占用缓存较大,所以每个数据库只需创建一个SessionFactory实例,当需要操作多个数据库时,再为每一个数据库指定一个SessionFactory实例。
特点
1线程安全,同一个实例可以被应用的多个线程共享
2重量级,不能随意创建和销毁他的实例,一个数据库,只需要创建一个SessionFactory的实例。
3以后对Configuration对象势力作出的修改都不会影响已经创建好的SessionFactory实例,如果需要使用基于改动后的Configuration实例的SessionFactory,需要从Configuration对象中重新创建新的SessionFactory实例。
用法
Configuration config = new Configuration( ); ServiceRegistry sr = new ServiceRegistryBuilder( ).applySettings(config.getProperties( )).buildServiceRegistry( ); SessionFactory sessionFactory = config.buildSessionFactory(sr);
Session
Session是Hibernate持久化操作的基础,负责管理所有与持久化有关的操作,Session与SessionFactory不同,它是轻量级的,也是非线程安全的。创建和销毁不会消耗太多资源,可以为每一个请求分配一个Session。
特点
1不是线程安全的,应该避免多个线程共享同一个Session实例。
2Session实例是轻量级的。
3Session对象内部有一个缓存,被称为Hibernate第一缓存,他存放被当前工作单元中加载的对象,每个Session实例都有自己的缓存。
用法
Session session = sessionFactory.openSession( ); 常用方法: session.save( ); session.update( ); session.saveOrUpdate( ); session.delete( );
Transaction
Transaction负责Hibernate的数据库事务,其实Hibernate本身并不具备事务管理的能力,只是对底层事务接口进行了封装,这样有利于在不同环境或容器中移植,也可以直接访问底层的事务接口。
用法
Transaction tx = session.beginTransaction( );
Query和Criteria
Query和Criteria负责Hibernate的查询操作。 Query实例封装了一个HQL(Hibernate Query Language)查询语句,HQL与SQL有些类似,只是HQL是面向对象的,它操作的是持久化类的类名和属性名,而SQL操作的是表名和字段名。 Criteria实例完全封装了字符串形式的查询语句,它比Query实例更加面向对象,更适合执行动态查询。
常见注解
类级别注解
注解 | 解释 |
---|---|
@Entity | 实体类 对应一个表 |
@Table | |
@Embeddable | 嵌入类 |
Entity
实体类。对应一个表
可以带Name属性,对应一个数据库中的表。
Table
配合@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息。
但实际来说,每个数据库对catalog和schama的支持都不同。
属性:
- name:可选,映射表的名称,默认表名和实体名称一致,只有在不一致的情况下才需要指定表名。
- catalog:可选。表示Catalog名称,默认为Catalog("")。
- schema:可选。表示Schema名称,默认为Schema("")。
网友评论