1.在控制台中显示Hibernate打印的SQL中的参数

默认情况下,hibernate的sql中都是以问号代表参数,并没有显示参数的真实值,但是也不是做不到,只需要两步配置就可以显示出参数的真实值了:

(1)spring的配置文件中增加: 
<prop key="hibernate.show_sql">true</prop> 
或者在hibernate的配置文件中增加: 
<property name="show_sql">true</property>

(2)在log4j.properties中做如下配置: 
log4j.appender.STDOUT.Threshold=trace 
log4j.category.org.hibernate.SQL=trace 
log4j.category.org.hibernate.type=trace

2.spring进行事务控制时,何时得到session,何时开启事务,何时打开连接?

在方法开始前spring通过动态代理,利用AOP的方式,为普通要调用的方法在方法开始处添加事务控制,如果在方法中要进行save操作,则进行getSession。
在调用getSession()方法时,拿到数据库连接,如果在一个循环中多次调用save方法,因为Spring会控制在一个事务中只有同一个Session,

所以跟数据库的连接也只有一次,所以如果循环保存一个list,在service层循环和在Dao层循环都是一样的(spring事务是加在service层的情况)。

3.Hibernate delete操作的理解

delete()方法用于从数据库中删除与Java对象对应的记录。如果传入的参数是持久化对象,Session就计划执行一个delete语句。
如果传入的参数是游离对象,先使游离对象被Session关联,使它变为持久化对象,然后计划执行一个delete语句。
值得注意的是,Session只有在清理缓存的时候的才执行delete语句。
此外,只有当调用Session的close()方法时,才会从Session的缓存中删除该对象。

例如以下代码先加载一个持久化对象,然后通过delete()方法将它删除:

1
2
3
4
5
6
7
Session session1 = sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
// 先加载一个持久化对象
Customer customer = (Customer)session.get(Customer.classnew Long(1));
session.delete(customer); // 计划执行一个delete语句
txt1.commit(); // 清理缓存,执行delete语句
session.close();子// 从缓存中删除Customer对象

以下代码直接通过delete()方法删除一个游离对象:

1
2
3
4
5
6
7
Session session2 = sessionFactory.openSession();
Transaction tx2 = session1.beginTransaction();
// 假定customer是一个游离对象,先使它被Session关联,使它变为持久化对象,
// 然后计划执行一个delete语句
session2.delete(customer);
tx2.commit(); // 清理缓存,执行delete语句
session2.close(); // 从缓存中删除customer对象 

如果希望删除多个对象,可以使用另一种重载形式的delete()方法:

1
session.delete("from Customer as c where c.id>8");

以上delete()方法的参数为HQL查询语句,delete()方法将从数据库中删除所有满足查询条件的记录。

4.Hibernate的几种查询方式

(1)使用HQL语句

Query q = session.createQuery("select e from com.sun.demo.Emp e");

(2)使用Load方法(主键查询)

Emp e = (Emp)session.load(Emp.class, 1141);

(3)使用get方法(主键查询)

Emp e = (Emp)session.get(Emp.class, 1141);

(4) 参数化查询(使用?通配符,或者命令通配符)

1
2
3
4
5
6
7
8
Query q = session.createQuery("update Userinfo set ename='AAA' WHERE ename=?");
       q.setParameter(0"SMITH");
 
Query q = session.createQuery("update Userinfo set ename='AAA' WHERE ename like ?");
       q.setParameter(0"%M%");
 
Query q = session.createQuery("update Userinfo set ename='AAA' WHERE ename like :lkename");
       q.setParameter("lkename""%L%");

  

(5)命名查询

1
2
3
4
5
<query name="myquery">
 
 <![CDATA[ from com.sun.hibernate.Employer where job = ?]]>
 
</query>

  

1
2
Query q = session.getNamedQuery("myquery");
q.setParameter(0"MANAGER");

(6)属性查询

Query q = session.createQuery("select max(sal) from Employer e where sal is not null");

Query q = session.createQuery("select distinct job from Employer e");

(7)实例化查询

步骤如下:

1.编写你的HQL语句

2.创建普通的Java类 -------------------与POJO类不同,它与数据库没有任何关系

3.在该java类中你需要创建和查询结果对应的字段

4.在该java类中,你需要创建合适的构造函数

5.完善你的HQL语句,使用实例化查询的方式进行包装

6.通过list.get(i)获取的结果就不再是一个数组,而是一个包装后的对象

例子:

1
2
3
4
5
6
7
Query q = session.createQuery("SELECT new com.sun.demo.UserDate(ename,SYSDATE) FROM Userinfo");
List list = q.list();
for(int i=0;i<list.size();i++){
       UserDate u = (UserDate)list.get(i);
       System.out.println(u.getEname());
 
}

  

(8)多态查询

对于pojo来说,java中的这种关系被扩展到了数据库表中

hibernate在查询一个表的同时,会检查该表所对应的POJO类有没有子类,如果有,一起查询出来

(9)分页查询

//查询第三到五条

q.setFirstResult(3);//从第三条开始

q.setMaxResults(3);//提取三条

(10)uniqueResult方法查询(查询结果只能是一个字段)

Query q = session.createQuery("select count(*) from Employer");

Long count = (Long)q.uniqueResult();

(11)Criteria查询(通过面向对象化的设计,将数据查询条件封装为一个对象)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Criteria c = session.createCriteria(Employer.class);
 
       c.addOrder(Order.asc("sal"));      //按薪水升序查询
 
       c.setFirstResult(3);
 
       c.setMaxResults(3);
 
       List list = c.list();
 
       for(int i=0;i<list.size();i++){
 
           Employer emp = (Employer)list.get(i);
 
           System.out.println(emp.getEname() + " : " + emp.getSal());
 
       }

  

5.Hibernate框架的工作流程

a. 读取并解析配置文件
b.读取并解析映射信息,创建SessionFactory
c.打开Sesssion
d.创建事务Transation
e.持久化操作
f.提交事务
g.关闭Session
h.关闭SesstionFactory

6.Hibernate框架中的核心接口有哪些,这些接口的具体功能是什么?

核心接口有:session,sessionFactory,transaction,query,configuration.
a) Session接口:Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句。)。
b) SessionFactory接口:SessionFactroy接口负责初始化Hibernate。它充当数据存 储源的代理,并负责创建Session对象。
c) Configuration接口:Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。
d) Transaction接口:Transaction接口负责事务相关的操作。
e) Query和Criteria接口:Query和Criteria接口负责执行各种数据库查询。它可以使用HQL语言或SQL语句两种表达方式。

7.Hibernate中的Session对象表示什么?它与Web程序中的Session是一样的机制吗?

Hibernate中的Session对象代表与数据库之间的一次操作,它的概念介于Connection和Transaction之间,也称为持久化管理器,因为它是与持久化有关的操作接口。它通过SessionFactory打开,在所有的工作完成后,需要关闭。
它与Web层的HttpSession没有任何关系,Web层的HttpSession是指一个作用域。

8.Hibernate.cfg.xml配置文件中,应该包含哪些具体的配置内容?

Hibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect, 连接池等。
Hibernate映射文件(*.hbm.xml)。

9.简述Hibernate的主键机制

A, 数据库提供的主键生成机制。identity、sequence(序列)。
B, 外部程序提供的主键生成机制。increment (递增) ,hilo(高低位) ,seqhilo(使用序列的高低位 ),uuid.hex(使用了IP地址+JVM的启动时间(精确到1/4秒)+系统时间+一个计数器值(在JVM中唯一) ),uuid.string。
C, 其它。native(本地),assigned(手工指定),foreign(外部引用)

10.请简述Hibernate中cascade,inverse,constrained几个属性的区别?

cascade(级联) :
是操作主表或者从表时,要不要自动操作从表或者主表,比如,保存主表的时候,要不要也默认保存从表,cascade 的值主要有四种:none,all,delete,save-update。
Inverse:
是指要不要交出控制权,值有true(交出控制权,不再维护双方的关系)和false(不交出控制权,继续维护双方的关系)。
constrained:
表示当前引用对象的主键是否作为当前对象的主键参考,true为是,false为否.

11.Hibernate有几种数据查询方式,这几种数据查询方式的优缺点

使用主键id加载对象(load(),get());
Criteria: 通过面向对象化的设计,将数据查询条件封装为一个对象。Criteria本身只是一个查询容器,查询条件通过criteria.add方法添加到criteria查询实例中。
HQL(Hibernate Query Language)针对hibernate的查询语言,完全面向对象,理解继承,多态和关联之类的概念。HQL配备了很强大的查询语言,在语法结构上类似SQL,但HQL是面向对象的查询语言。
Native sql: 使用数据库的原生sql语句来查询。
优缺点:
a) criteria 最适合动态查询,但不太适合统计查询,qbe还不够强大.只适合简单的查询
b) hql功能很强大,适合各种情况,但是动态条件查询构造起来很不方便
c) Native sql可以实现特定的数据库的sql.但是可移植性并不好

12.Hibernate如何实现对象之间的多对多的映射

(主表User)

<class name=” com.softfz.pojo.User” table=”T_USER”>
<id name=”id” column=”userId”><generator class=”native”/></id>
<set name=”roles” table=”t_user_role” cascade=”save-update” >
<!– column指中间表的外键字段 –>
<key column=”useridd”></key>
<!– column指与从表相关联的中间表的外键字段 –>
<many-to-many class=”com.softfz.pojo.TRole” column=”roleidd”>
</many-to-many>
</set>
</class>

(从表role)

<class name=”com.softfz.pojo.TRole” table=”T_ROLE” >
<id name=”id” column=”userId”><generator class=”native”/></id>
<set name=”users” table=”t_user_role” cascade=”save-update”>
<!– column指中间表的外键字段 –>
<key column=”roleid”></key>
<!– column指与从表相关联的中间表的外键字段 –>
<many-to-many class=”com.softfz.pojo.TUser” column=”userid”>
</many-to-many>
</set>
</class>

13.Hibernate框架中,如何实现对象数据之间的内连接操作和左外连接操作

内连接
hql = ”Select a,b From Orderinfo a,Orderdetail b where a.autoid = b.orderid”;
特点:无需配置Orderinfo和Orderdetail的关联关系。

左外连接
hql = ”Select a From Orderinfo a left join a.orderDetails”;
特点:必须配置Orderinfo与orderDetails之间的关联关系。

14.如何在Hibernate中实现对数据的批量删除和批量更新

通过Hibernate的session.delete(“from TUser”)进行批量操作有如下缺点:
(1) 占用大量内存,必须把1万个TUser对象先加载到内存,然后一一通过主键删除他们。
(2) 执行的delete语句的数目太多,每个delete语句只能更新一个Customer对象,必须通过1万条delete语句才能删除一万个TUser对象,频繁的访问数据库,会大大降低应用的性能。
直接通过Hibernate API进行批量更新和批量删除都不值得推荐。而直接通过JDBC API执行相关的SQL语句或调用相关的存储过程,是批量更新和批量删除的最佳方式,这两种方式都有以下好处:
(1) 无需把数据库中的大批量数据先加载到内存中,然后逐个更新或修改他们,因此不会消耗大量内存。
(2) 能在一条SQL语句中更新或删除大批量的数据。

15.在Hibernate 中 Java 对象的状态有哪些 ?

临时状态(transient):不处于 Session 的缓存中。OID 为 null 或等于 id 的 unsaved-value 属性值
持久化状态(persistent):加入到 Session 的缓存中。
游离状态(detached):已经被持久化,但不再处于 Session 的缓存中。

16.持久化对象的三种状态,代表含义。

临时状态——刚用new语句创建,未被持久化,不处于session的缓存中。
持久化状态——已经被持久化,处于session的缓存中。
游离态——已经被持久化,但不处于session的缓存中。

17.哪些情况下需要使用原生SQL,如何调用原生 SQL ?

  • 有些数据库函数,hql不能正常调用,如Oracle的listagg行聚合函数
  • model对象之间不设置连接关系,hql无法使用join语句
  • 要自定义返回数据类型,如不同表之间联合查询多个字段

调用 Session 的 createSQLQuery()方法。

18.三种检索策略是什么,分别适用于哪种场合?

立即检索——
优点:对应用程序完全透明,缺点:select语句数目多。适用:类级别。

延迟检索——
优点: 由应用程序决定加载哪些对象,可以避免执行多余的select语句以及避免加载不需要访问的对象,节省内存空间,提高检索效率。
缺点: 应用程序如果要访问游离态的代理类实例,必须保证它在持久化时已经被初始化。
适用: 一对多或多对多关联。应用程序不需要立即访问或者根本不会访问的对象。

迫切左外连接检索:
优点:对应用程序完全透明,不管对象处于持久化状态还是游离状态,应用程序都可以方便的从一个对象导航到另一个与它相关联的对象。使用了外连接,select语句数目少。
缺点:可能会加载程序不许要访问的对象。复杂的数据库表连接形象检索性能。
适用:一对一或多对一关联。应用程序需要立即访问的对象。数据库系统具有良好的表连接性能。

19.说说 Hibernate 的缓存

Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存:
1). Hibernate一级缓存又称为”Session的缓存”,它是内置的,不能被卸载。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
2).Hibernate二级缓存又称为”SessionFactory的缓存”,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,是一个可配置的插件,在默认情况下,SessionFactory不会启用这个插件。
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;如果都查不到,再查询数据库,把结果按照ID放入到缓存。删除、更新、增加数据的时候,同时更新缓存。

20.Hibernate中的延迟机制的原理,以及Hibernate中数据有几种延迟加载方式?

延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
Hibernate中提供了三种延迟加载方式分别是
A. 实体对象的延迟加载
B. 集合的延迟加载
C. 属性的延迟加载

21.Hibernate中Load和Get两种方法查询数据的区别?

load是采用延迟机制(load语句不读库,等使用非主键时才去读库),而get不采用延迟机制(get语句时马上读库)。
a.当数据库不存在对应ID数据时,调用load()方法将会抛出ObjectNotFoundException异常,get()方法将返回null.
b.当对象.hbm.xml配置文件<class>元素的lazy属性设置为true时,调用load()方法时则返回持久对象的代理类实例,此时的代理类实例是由运行时动态生成的类,该代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所在属性为null值,查看日志并没有Hibernate SQL输出,说明没有执行查询操作,当代理类实例通过getXXX()方法获取属性值时,Hiberante才真正执行数据库查询操作。当对象.hbm.xml配置文件<class>元素的lazy属性设置为false时,调用load()方法则是立即执行数据库并直接返回实体类,并不返回代理类。而调用get()方法时不管lazy为何值,都直接返回实体类。
c.load()和get()都会先从Session缓存中查找,如果没有找到对应的对象,则查询Hibernate二级缓存,再找不到该对象,则发送一条SQL语句查询。
总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

22.Hibernate如何实现对象之间一对一的映射。一对一的映射有几种方式?

A.以主键关联:关联的两个实体共享一个主键

具体映射:
(主表User)

<class name=”TUser” table=”T_USER”>
<id name=”userid” type=”java.lang.Long”>
<column name=”USERID” precision=”22″ scale=”0″ />
<generator class=”sequence”>
<param name=”sequence”>seq_t_user</param>
</generator>
</id>
<one-to-one name=”userInfo” cascade=”all”></one-to-one>
</class>

(从表UserInfo)

<class name=” UserInfo” table=”T_USERINFO ”>
<id name=”userid”>
<!– userInfo的主键来源user,也就是共享user的主键 –>
<generator class=”foreign”>
<param name=”property”>user</param>
</generator>
</id>
<!– one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,constrained=”true”, 表明当前主键上存在一个约束,UserInfo的主键作为外键参照了user–>
<one-to-one name=”user” constrained=”true”/>
</class>

B.一对一以外键关联: 两个实体各自有不同的主键,但是一个实体有一个外键引用另一个实体的主键。
(从表UserInfo)

<class name=” com.softfz.pojo.UserInfo” table=”T_USERINFO ”>
<id name=”userInfoId” type=”java.lang.Long”>
<column name=”USERID” precision=”22″ scale=”0″ />
<!– userInfo的主键来源由序列生成 –>
<generator class=”sequence”>
<param name=”sequence”>seq_t_userinfo</param>
</generator>
</id>

<!—may-to-one表示user和userinfo是一对多的关系,userinfo的外键 – userid参考user的主键,unique 表示这是一种特殊的一对多->
<many-to-one name=”user” column=”userid” unique=”true”>
</many-to-one>
</class>

  

23.Hibernate如何实现对象之间的一对多映射?

(主表User)
<class name=”com.test.hibernate.User” table=”TBL_USER”>
<id name=”id” column=”userId”><generator class=”native”/></id>
<set name=”addresses” cascade=”all” inverse=”true” >
<!– 从表的外键字段 –>
<key column=”userid”/>
<one-to-many class=”com.test.hibernate.Address”/>
</set>
</class>
(主表Address)
<class name=”com.test.hibernate.Address” table=”TBL_ADDRESS”>
<id name=”id” column=”addressId”> <generator class=”native”/></id>
<!—column表示从表的外键字段userid参考了user的主键 –>
<many-to-one name=”user” class=”com.softfz.pojo.TUser” column=”userid”>
</many-to-one>
</class>

Hibernate日常应用的相关问题的更多相关文章

  1. hibernate之inverse=true相关配置讲解

      首先inverse=”true”是在双向关联里面使用单向关联没有这个配置 inverse – 标记由哪一方来维护关联关系(双向关联中会用到) inverse默认值为false 如果inverse设 ...

  2. hibernate日常BUG总结

    在使用hibernate自动生产表的时候失败, 是配置文件我是从别地方拷贝过来忘记更改,所以报了这个错误. 重新命名了生成表的名称,问题解决! 问题很明显,自动增长的主键应该使用整型. 这里写的是St ...

  3. 程序猿的日常——HashMap的相关知识

    背景知识 哈希冲突 哈希是指通过某种方法把数据转变成特定的数值,数值根据mod对应到不同的单元上.比如在Java中,字符串就是通过每个字符的编码来计算.数字是本身对应的值等等,不过就算是再好的哈希方法 ...

  4. 【译】Spring 4 + Hibernate 4 + Mysql + Maven集成例子(注解 + XML)

    前言 译文链接:http://websystique.com/spring/spring4-hibernate4-mysql-maven-integration-example-using-annot ...

  5. hibernate+mysql的连接池配置

    1:连接池的必知概念    首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...

  6. 【Java EE 学习 53】【Spring学习第五天】【Spring整合Hibernate】【Spring整合Hibernate、Struts2】【问题:整合hibernate之后事务不能回滚】

    一.Spring整合Hibernate 1.如果一个DAO 类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了:如果一个DAO类没有 ...

  7. 【CentOS】Linux日常管理

    /////////////////////////目录///////////////////////////////////////// 一.日常监控指标相关 1.监控系统状态命令 2.查看系统进程 ...

  8. Hibernate 参数设置一览表

    Hibernate 参数设置一览表 属性名 用途 hibernate.dialect 一个Hibernate Dialect类名允许Hibernate针对特定的关系数据库生成优化的SQL. 取值 fu ...

  9. Hibernate参数一览表

    参考文章地址:http://www.blogjava.net/i369/articles/194855.html Hibernate 参数设置一览表 属性名 用途 hibernate.dialect ...

随机推荐

  1. xml 嵌入式资源

    使用Ibatis总是说未能加载相应的sqlmap.xml,原来是 xml以内容方式,而不是嵌入式方式载入Dll中

  2. MyEclipse------如何在特定目录下创建文件夹

    Directory.jsp <%@ page language="java" import="java.util.*" pageEncoding=&quo ...

  3. WinForm AutoComplete 输入提示、自动补全

    一.前言 又临近春节,作为屌丝的我,又要为车票发愁了.记得去年出现了各种12306的插件,最近不忙,于是也着手自己写个抢票插件,当是熟悉一下WinForm吧.小软件还在开发中,待完善后,也写篇博客与大 ...

  4. ios 正则邮箱

    - (BOOL) isEmail { NSString *emailRegEx = @"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0- ...

  5. Adele的生活

    3个小时的电影,有点冗长,中间抽空吃了个饭,跑出去抽了3根烟,接着洗了个脸才回来接着看完,法国人做事真是拖沓啊有木有. 电影看完后给人一种淡淡的忧伤,第一次了解lesbians的真实世界(如果电影是来 ...

  6. css的一些小技巧!页面视觉差!

    相当长的一段时间,现在网站与所谓的“视差”效果一直很受欢迎. 万一你没有听说过这种效果,不同的图像,在不同的方向移动或层主要包括.这导致了一个很好的光学效应,使参观者的注意. 在网页设计中,为了实现这 ...

  7. TCP/IP网络编程技术基础

    零零碎碎记下点→ 不对的欢迎大家批评纠正→ 以免本人及偶尔看到此博客的人继续迷途未返→ >>>>>基础知识→ 1→TCP/IP英文名:Tranmission Contro ...

  8. 复制”链接文件“到虚拟机(VirtualBox)的”共享文件夹“时报错:创建符号链接时报错:只读文件系统

    问题描述: 1.Ubuntu 中的 /www/目录,是宿主主机 Windows 7 以“共享文件夹”的形式挂载的: 2./etc/php.ini 是 /opt/software/php/etc/php ...

  9. Stanford机器学习---第九讲. 聚类

    原文:http://blog.csdn.net/abcjennifer/article/details/7914952 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...

  10. Java获取、删除文件和目录

    package javatest; import java.io.File; import java.util.ArrayList; import java.util.regex.Pattern; c ...