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.
class
,
new
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());
}
|