
24. 为什么要使用 hibernate?
- Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
- Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作
- Hibernate使用java的反射机制,而不是字节码增强程序类实现透明性
- Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系
- *Hibernate本身性能并不是很好,存在很多优化手段 (一级缓存、二级缓存、查询缓存、抓取策略)。
25. 什么是 ORM 框架?
ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。
只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。当前ORM框架主要有五种:Hibernate(Nhibernate),iBATIS,mybatis,EclipseLink,JFinal。
ORM是通过使用描述对象和数据库之间映射的元数据,在我们想到描述的时候自然就想到了xml和特性(Attribute).目前的ORM框架中,Hibernate就是典型的使用xml文件作为描述实体对象的映射框架,而大名鼎鼎的Linq则是使用特性(Attribute)来描述的。
26. hibernate 中如何在控制台查看打印的 SQL 语句?
在 Config 里面把 hibernate. show_SQL 设置为 true 就可以。但不建议开启,开启之后会降低程序的运行效率。
示例:
找到hibernate的配置文件-- hibernate.cfg.xml
加入:
<property name="hibernate.show_sql">true</property>
如果你用spring那么就要:
修改spring里面的配置文件:
...
<property name="hibernateProperties">
<props>
<prop key = "hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key = "hibernate.show_sql">false</prop>
27. hibernate 有几种查询方式?
Hibernate有4种查询方法。
HQL 通过Hibernate提供的查询语言进行查询。Hibernate Query lanague
EJBQL(JPQL 1.0) 是EJB提供的查询语言
QBC(query by cretira)通过Cretira接口进行查询
QBE(query by Example) 通过Example编程接口进行查询
从功能强弱上排序:NativeSQL > HQL > EJBQL(JPQL 1.0) >QBC(query by cretira) >QBE(query by Example) 1: QBE (Query By Example) QBC查询方式。
QBC(Query By Criteria)查询方式是 Hibernate 提供的“ 更加面向对象”的一种检索方式。 QBC 在条件查询上比 HQL 查询更为灵活,而且支持运行时动态天生查询语句。
在Hibernate 应用中使用 QBC 查询通常经过 3 个步骤:
(1)使用 Session 实例的 createCriteria() 方法创建 Criteria 对象
(2)使用工具类 Restrictions 的相关方法为 Criteria 对象设置查询对象
(3)使用 Criteria 对象的 list() 方法执行查询,返回查询结果QBE查询QBE查询就是检索与指定样本对象具有相同属性值的对象。因此QBE 查询的关键就是样本对象的创建,样本对象中的所有非空属性均将作为查询条件。 QBE 查询的功能子集,固然 QBE 没有 QBC 功能大,但是有些场合 QBE 使用起来更为方便。
工具类Example 为 Criteria 对象指定样本对象作为查询条件Java代码:
1 Session session = HibernateSessionFactory.getSessionFactory().openSe ssion();
2 Transaction ts = session.beginTransaction();
3 Customer c = new Customer();
4 c.setCname("Hibernate");
5 Criteria criteria = session.createCriteria(Customer. class );
6 Criteria.add(Example.create(c));
7 Iterator it = criteria.list().iterator();
8 ts.commit();
9 HibernateSessionFactory.closeSession();
28. hibernate 实体类可以被定义为 final 吗?
是的,你可以将Hibernate的实体类定义为final类,但这种做法并不好。因为Hibernate会使用代理模式在延迟关联的情况下提高性能,如果你把实体类定义成final类之后,因为 Java不允许对final类进行扩展,所以Hibernate就无法再使用代理了,如此一来就限制了使用可以提升性能的手段。不过,如果你的持久化类实现了一个接口而且在该接口中声明了所有定义于实体类中的所有public的方法轮到话,你就能够避免出现前面所说的不利后果。
29. hibernate里实体类用int和Integer区别
返回数据库字段值是null的话,int类型会报错。int是基本数据类型,其声明的是变量,而null则是对象。所以hibernate实体建议用integer;
通过jdbc将实体存储到数据库的操作通过sql语句,基本数据类型可以直接存储,对象需要序列化存储。
在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
如何序列化
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File("E:/Person.txt")));
oo.writeObject(person);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:/Person.txt")));
Person person = (Person) ois.readObject();
30. hibernate 是如何工作的?
1.通过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息
3.通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
4.Session session = sf.openSession();//打开Sesssion
5.Transaction tx = session.beginTransaction();//创建并启动事务Transation
6.persistent operate操作数据,持久化操作
7.tx.commit();//提交事务
8.关闭Session
9.关闭SesstionFactory
31. get()和 load()的区别?
· 数据查询时,没有 OID 指定的对象,get() 返回 null;load() 返回一个代理对象。
· load()支持延迟加载;get() 不支持延迟加载。
32. 说一下 hibernate 的缓存机制?
hibernate 常用的缓存有一级缓存和二级缓存:
一级缓存:也叫 Session 缓存,只在 Session 作用范围内有效,不需要用户干涉,由 hibernate 自身维护,可以通过:evict(object)清除 object 的缓存;clear()清除一级缓存中的所有缓存;flush()刷出缓存;
二级缓存:应用级别的缓存,在所有 Session 中都有效,支持配置第三方的缓存,如:EhCache。
33. hibernate 对象有哪些状态?
· 临时/瞬时状态:直接 new 出来的对象,该对象还没被持久化(没保存在数据库中),不受 Session 管理。
· 持久化状态:当调用 Session 的 save/saveOrupdate/get/load/list 等方法的时候,对象就是持久化状态。
· 游离状态:Session 关闭之后对象就是游离状态。
34. 在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
· getCurrentSession 会绑定当前线程,而 openSession 则不会。
· getCurrentSession 事务是 Spring 控制的,并且不需要手动关闭,而 openSession 需要我们自己手动开启和提交事务。
35. hibernate 实体类必须要有无参构造函数吗?为什么?
hibernate 中每个实体类必须提供一个无参构造函数,因为 hibernate 框架要使用 reflection api,通过调用 ClassnewInstance() 来创建实体类的实例,如果没有无参的构造函数就会抛出异常。