- 为什么使用hibernate?
a) hibernate对jdbc进行封装,大大简化了数据访问层的繁琐的重复性代码
b) hibernate是一个优秀的ORM实现,简化了Dao层的编码功能
c) 方便数据库的移植
d) 提供了缓存机制,使程序执行更加高效 - 什么是ORM?
a) ORM(Object Relational Mapping):对象关系映射,将Java对象映射到数据库表,通过操作对象达到操作数据库的目的
b) 优点:提高开发效率、降低开发成本、开发更简单更对象化、可移植性强 - HIbernate如何再控制台查看打印的SQL语句?
a) 在配置文件种将hibernate.show_SQL设置为true即可(开启后会降低长须的运行效率) - hibernate有几种查询方法?
a) 三种:原生SQL查询、HQL查询、条件查询Criteria - hibernate中的实体类可以定义为final吗?
a) 可以,但是定义为final的类无法使用hibernate代理模式下的延迟关联提高性能。因为Java的final类不能被拓展,所以hibernate就无法使用代理 - 为什么hibernate的实体类中要提供一个无参构造函数?
a) hibernate框架使用反射机制(Reflection API),通过调用Class.newInstance()创建实体类的实例,没有无参构造函数会抛出一个InstantiationException异常 - hibernate加载持久化对象的两种方式——session.get()、session.load()的区别
a) get
i. hibernate确认该id对应的对象是否存在,首先在session缓存中找,找不到再到二级缓存中找,还没有就到数据库中找,最终还找不到返回null
b) load:加载实体对象的时候,更具配置文件上类的lazy属性(默认未true)配置分情况讨论
i. 如果为true,则先在session的缓存中找对象的OID,不存在就使用延迟加载,返回实体类的代理类对象(代理类为实体类的子类,由cglib动态产生)。等到具体使用到该对象(即获取对象的属性,不过使用getClass()、getId()、或者比较对象的OIDC除外)时,再查询二级缓存,没有再查询数据库,最终没有找到抛出异常ObjectNotFoundException
ii. 如果为false,查询步骤跟get一致,不过最终找不到同样抛出一个异常ObjectNotFoundException - hibernate的getCurrentSession()和openSession()的区别
a) getCurrentSession()返回当前的session,如果没有就调用openSession()产生一个session;openSession()每次都返回一个新的session
b) getCurrentSession()创建的session在事务中可以自动回滚和关闭;openSession()创建的session则需要手动回滚或关闭 - 使用getCurrentSession()需要在hibernate.cfg.xml中加入下面的配置
a) 使用本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
b) 使用全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
- hibernate中session中对象的生命周期
a) 瞬时对象(transient object):使用new操作创建的对象的状态是瞬时的,也就是说与数据库没有任何关联的行为,对象不被引用时,状态将会丢失,由GC回收
b) 持久化对象(persistent object):由持久化管理其session统一管理,持久实例实在事务中进行操作的——它们的状态在事务结束时与数据库同步。事务提交时,对象在内存中的状态将保存到数据库中
c) 离线对象(detached object):session关闭后持久化对象变为离线对象。离线表示对象不再与数据库保持同步,对象不再受hibernate管理
d) session中对象的生命周期图:
- hibernate中的cache,可以分成两层:一级缓存(session缓存)、二级缓存
a) 一级缓存:属于事务级数据缓存,事务结束,该缓存也就失效了(一个session的生命周期对应一个数据库事务或一个程序事务)
b) 二级缓存:属于SessionFactory范围内的缓存,所有的session共享一个二级缓存 - hibernate中二级缓存的使用
a) 选择数据并发策略,有四种策略,对应数据库的隔离级别
i. 事务策略:仅在受管理的环境中使用。保证数据可重复读的隔离级别,读写操作多,更新操作少的数据采用该策略
ii. 读写策略:使用时间戳机制维护读写提交事务隔离级别,读写操作多,更新操作少的数据采用该策略
iii. 非严格读写策略:不保证缓存与数据库之间的一致性。使用该策略需要设置足够的缓存过期时间,否则有可能从缓存中读取脏数据
iv. 只读策略:数据不修改时使用该策略
b) 确定数据并发策略后,需要选一个高效的缓存提供器,这里只针对EhCache(还有其他缓存插件,有兴趣自行百度),作为插件被hibernate调用
i. EnCache:可以在JVM中作为一个简单进程范围内的缓存,可以将缓存的数据放入内存或磁盘,并支持hibernate中的查询缓存
ii. 使用EnCache,需要在hibernate的配置文件中引入,配置如下
<propery name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
- hibernate的二级缓存和查询缓存的区别
a) 一级缓存、二级缓存是针对整个实体的,不会缓存普通属性;查询缓存可以对普通属性进行缓存
b) 查询缓存要求所有的HQL/SQL语句相同,设置传入的参数也要相同,这样hibernate才能在查询缓存中取到数据
c) 查询缓存默认是关闭的,开启方式:
<property name="hibernate.cache.use_query_cache">true</property>
- hibernate中的session的close()、clear()、flush()区别
a) close():将当前会话连接关闭,断开与数据库的连接
b) clear():将一级缓存中的所有持久化对象清除,释放其占有的内存资源
c) flush():刷新一级缓存的内容,使其与数据库保持同步 - hibernate中的SessionFactory
a) 作用:用于创建session对象的工厂,SessionFactory通常在应用启动时创建好
b) SessionFactory是线程安全的
c) SessionFactory的内部状态包含着跟对象关系映射相关的所有元数据,它是不可变的,一旦创建好就不能进行修改 - hibernate中save、persist和saveOrUpdate三个方法的区别
a) 共同点:都可以将对象保存到数据库
b) 不同点:
i. save()只能用于insert操作,返回值是一个Serializable对象
ii. persist()没有返回值
iii. saveOrUpdate()可以insert和update操作 - hibernate中sorted collection和ordered collection的区别
a) sorted collection是使用Java comparator在内存中进行排序
b) ordered collection是数据库的order by句子
c) 对于比较大的数据进行排序最好使用ordered collection,前者可能出现内存溢出的错误 - hibernate是如何工作的?
a) 读取并解析配置文件
b) 读取并解析映射文件,创建SessionFactory
c) 打开Session
d) 创建事务
e) 进行持久化操作
f) 提交事务
g) 关闭Session
h) 关闭SessionFactory