Hibernate工作流程

Hibernate工作原理

工作流程:

1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息
3.通过config.buildSessionFactory();//创建SessionFactory
4.sessionFactory.openSession();//打开Sesssion
5.session.beginTransaction();//创建事务Transation
6.persistent operate持久化操作
7.session.getTransaction().commit();//提交事务
8.关闭Session
9.关闭SesstionFactory

为什么要用:

1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。简化了DAO层的编码工作

3. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
 

2. Hibernate是如何延迟加载?

1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)

2. Hibernate3 提供了属性的延迟加载功能

      当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在于内存中,实现了延迟加载,节省了服务器的内存开销,从而提高了服务器的性能。

3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)

      类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、

4. 说下Hibernate的缓存机制

1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事务级缓存

2. 二级缓存
a) 应用级缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据
c) 第三方缓存的实现
////////一级缓存:session级的缓存也叫事务级的缓存,只缓存实体,生命周期和session一致。不能对其进行管理,不用显示的调用。

二级缓存:sessionFactory缓存,也叫进程级的缓存,使用第3方插件实现的,也值缓存实体,生命周期和sessionFactory一致,可以进行管理。

首先配置第3方插件,我们用的是EHCache,在hibernate.cfg.xml文件中加入

<property name="hibernate.cache.user_second_level_cache">true</property>

在映射中也要显示的调用,<cache usage="read-only"/>

二级缓存之查询缓存:对普通属性进行缓存。如果关联的表发生了修改,那么查询缓存的生命周期也结束了。

在程序中必须手动启用查询缓存:query.setCacheable(true);

5. Hibernate的查询方式

Sql、Criteria,Hql:
1、 属性查询
2、 参数查询、命名参数查询
3、 关联查询
4、 分页查询
5、 统计函数

6. 如何优化Hibernate?

1.使用 双向一对多关联,不使用单向一对多
2.灵活使用单向一对多关联
3. 不用一对一,用多对一取代 (?)
4.配置对象缓存,不使用集合缓存
5. 一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态
7. 表字段要少,表关联不要怕多,有二级缓存撑腰

1.Hibernate有哪几种查询数据的方式

      (1)导航对象图查询

      (2)OID查询

      (3)HQL

      (4)QBC

      (5)本地SQL

2.load()和get()的区别

get和load都使用内存,get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;而load方法调用时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。详细区别见此

load加载方法:

User user = (User)session.load(User.class, userId);

get加载方法:

User user = (User)session.get(User.class, userId);

      区别1:如果数据库中,没有userId的对象。如果通过get方法加载,则返回的是一个null;如果通过load加载,则返回一个代理对象,如果后面代码如果调用user对象的某个属性(比如user.getPassword())会抛出异常:org.hibernate.ObjectNotFoundException;

      区别2:load支持延迟加载,get不支持延迟加载。

也就是说:

User user = (User)session.load(User.class, userId);

这句代码不会去执行数据库查询,只有用到user时才会去执行数据库查询

而:

User user = (User)session.get(User.class, userId);

立即去执行数据库查询

注意:

Users user = (Users)session.load(User.class, userId);    
System.out.println(user.getId());

      上面这2句代码,不会去执行数据库操作。因为load后会在hibernate的一级缓存里存放一个map对象,该map的key就是userId的值,但是当你getId()时,它会去一级缓存里拿map的key值,而不去执行数据库查询。所以不会报任何错。不会执行任何数据库操作。

你可能感兴趣的:(Hibernate,Web)