1、事务级别控制
可以在Hibernate的配置文件中对事务进行配置。配置文件中,可以设置事务的隔离级别。其具体的配置方法是在hibernate.cfg.xml文件中的<session-factory>标签元素中进行的。配置方法如下所示。(这些事务隔离级别的具体描述可见JDBC)
<!—
事务隔离级别
hibernate.connection.isolation = 4
1—Read uncommitted isolation
2—Read committed isolation
4—Repeatable read isolation
8—Serializable isolation
-->
<property name="hibernate.connection.isolation">4</property>
2、Hibernate的查询对象API
a、Query查询
代表面向对象的一个Hibernate查询操作。在Hibernate中,通常使用session.createQuery()方法接受一个HQL语句,然后调用Query的list()或uniqueResult()方法执行查询。所谓的HQL是Hibernate Query Language缩写,其语法很像SQL语法,但它是完全面向对象的。
在Hibernate中使用Query对象的步骤,具体所示:
(1)获得Hibernate的Session对象。
(2)编写HQL语句。
(3)调用session.createQuery 创建查询对象。
(4)如果HQL语句包含参数,则调用Query的setXxx设置参数。
(5)调用Query对象的方法执行查询。
HQL的说明:
把表的名称换成实体类名称。把表字段名称换成实体类属性名称。
具体查询代码示例如下:(表结构与实体类可见第一篇Hibernate博客)
public class HqlQuery {
//基础查询
@Test
public void basicQuery() {
//需要注意的是此时的form后面的参数,实际上均为被映射后的类名和属性名
Session session = HibernateSessionUtil.getSession();
Query createQuery = session.createQuery("from Customer");
List<Customer> list = createQuery.list();
for (Customer customer : list) {
System.out.println(customer);
}
//条件查询
//条件参数必须用占位符
Query createQuery2 = session.createQuery("from Customer where cust_name = ?");
//赋值时需要注意占位符下标从开始
createQuery2.setString(0, "孙悟空");
List<Customer> list2 = createQuery2.list();
for (Customer customer : list2) {
System.out.println(customer.getCust_name());
}
//或者在条件查询中直接将占位符设置为变量名,再对变量名进行赋值即可
Query createQuery3 = session.createQuery("from Customer where cust_name = :custname");
createQuery3.setString("custname", "limeng");
List<Customer> list3 = createQuery3.list();
for (Customer customer : list3) {
System.out.println(customer.getCust_name());
}
}
//分页查询
@Test
public void pageQuery(){
Session session = HibernateSessionUtil.getSession();
String hQL = "from Customer";
Query createQuery = session.createQuery(hQL);
//设置开始记录索引,从0开始,指的是第一条记录
createQuery.setFirstResult(0);
//设置每次查询的记录条数
createQuery.setMaxResults(5);
List<Customer> list = createQuery.list();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Customer customer = (Customer) iterator.next();
System.out.println(customer.getCust_name());
}
}
//排序查询
@Test
public void orderQuery() {
//排序查询即直接将排序条件写在HQL后面即可,默认为asc,升序,可以设置为desc,降序
Session session = HibernateSessionUtil.getSession();
Query createQuery = session.createQuery("from Customer order by cust_id desc");
List<Customer> list = createQuery.list();
for (Customer customer : list) {
System.out.println(customer.getCust_name());
}
}
//聚合查询
@Test
public void methodQuery() {
//聚合查询直接写HQL查询即可
Session session = HibernateSessionUtil.getSession();
Query createQuery = session.createQuery("select count(cust_name) from Customer");
List list = createQuery.list();
for (Object object : list) {
System.out.println(object);
}
//当确定结果唯一时,可以使用下面这个方法
Long total = (Long)createQuery.uniqueResult();
System.out.println(total);
}
//投影查询
//什么是投影查询?即用实体类的一部分属性来构建类,当只想查询实体类的某几个属性时,可以使用投影查询
//但需要注意的是,这几个属性必须作为参数,在实体类中提供构造函数
@Test
public void reflectionQuery() {
Session session = HibernateSessionUtil.getSession();
List<Customer> list = session.createQuery("select new Customer(cust_id,cust_name) from Customer").list();
for (Customer customer : list) {
System.out.println(customer.getCust_name());
}
}
}
b、Criteria查询
Criteria是一个完全面向对象,可扩展的条件查询API,通过它完全不需要考虑数据库底层如何实现,以及SQL语句如何编写,它是Hibernate框架的核心查询对象。Criteria 查询,又称为QBC查询(Query By Criteria),它是Hibernate的另一种对象检索方式。
org.hibernate.criterion.Criterion是Hibernate提供的一个面向对象查询条件接口,一个单独的查询就是Criterion接口的一个实例,用于限制Criteria对象的查询,在Hibernate中Criterion对象的创建通常是通过Restrictions 工厂类完成的,它提供了条件查询方法。
通常,使用Criteria对象查询数据的主要步骤,具体如下:
(1)获得Hibernate的Session对象。
(2)通过Session获得Criteria对象。
(3)使用Restrictions的静态方法创建Criterion条件对象。Restrictions类中提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件。
(4)向Criteria对象中添加Criterion 查询条件。Criteria的add()方法用于加入查询条件。
(5)执行Criterita的 list() 或uniqueResult() 获得结果。
细节:
HQL能查的,QBC都能查,反之亦然。
查询的示例代码如下:
public class CriteriaQuery {
//普通查询与条件查询
@Test
public void basicQuery() {
Session session = HibernateSessionUtil.getSession();
Criteria createCriteria = session.createCriteria(Customer.class);
//查询全部
createCriteria.list();
createCriteria.add(Restrictions.eq("cust_name", "limeng"));
List<Customer> list = createCriteria.list();
for (Customer customer : list) {
System.out.println(customer.getCust_id());
}
}
/**
* 分页查询
* 和HQL是一模一样的
*/
@Test
public void test3(){
Session s = HibernateSessionUtil.getSession();
//1.获取Criteria对象
Criteria c = s.createCriteria(Customer.class);//它就相当于HQL的from Customer
//2.设置分页
c.setFirstResult(2);
c.setMaxResults(2);
//3.执行对象的方法获取结果集
List list = c.list();
for(Object o : list){
System.out.println(o);
}
}
/**
* 排序查询
*/
@Test
public void test1(){
Session s = HibernateSessionUtil.getSession();
//1.获取对象
Criteria c = s.createCriteria(Customer.class);
//2.设置排序
c.addOrder(Order.desc("cust_id"));
//3.获取结果集
List list = c.list();
for(Object o : list){
System.out.println(o);
}
}
/**
* QBC使用聚合函数
* 统计查询
* 涉及的对象:
* Criteria
* 涉及的方法:
* setProjection(Projection p);
* 参数的含义
* Projection:要添加的查询投影
*/
@Test
public void test2(){
Session s = HibernateSessionUtil.getSession();
//1.获取对象
Criteria c = s.createCriteria(Customer.class);//from Customer | select * from cst_customer
//2.想办法把select * 变成 select count(*)
// c.setProjection(Projections.rowCount());//select count(*)
c.setProjection(Projections.count("cust_id"));//select count(cust_id)
//3.获取结果集
// List list = c.list();
// for(Object o : list){
// System.out.println(o);
// }
Long total = (Long)c.uniqueResult();
System.out.println(total);
}
}
Query By Criteria查询方式的查询条件列表如下:
短语 | 含义 |
Restrictions.eq | 等于= |
Restrictions.allEq | 使用Map,使用key/value进行多个等于的判断 |
Restrictions.gt | 大于> |
Restrictions.ge | 大于等于>= |
Restrictions.lt | 小于< |
Restrictions.le | 小于等于<= |
Restrictions.between | 对应sql的between子句 |
Restrictions.like | 对应sql的like子句 |
Restrictions.in | 对应sql的in子句 |
Restrictions.and | and 关系 |
Restrictions.or | or关系 |
Restrictions.sqlRestriction | Sql限定查询 |
Restrictions.asc() | 根据传入的字段进行升序排序 |
Restrictions.desc() | 根据传入的字段进行降序排序 |
运算类型 | HQL运算符 | QBC运算方法 |
比较运算 | = | Restrictions.eq() |
<> | Restrictions.not(Restrictions.eq()) | |
>= | Restrictions.ge() | |
< | Restrictions.lt() | |
<= | Restrictions.le() | |
is null | Restrictions.isNull() | |
is not null | Restrictions.isNotNull() | |
范围运算符 | in | Restrictions.in() |
not in | Restrictions.not(Restrictions.in()) | |
between | Restrictions.between() | |
not between | Restrictions.not(Restrictions.between()) |
运算类型 | HQL运算符 | QBC运算方法 |
字符串模式匹配 | like | Restrictions.like() |
逻辑 | and | Restrictions.and()| Restrictions.conjunction() |
or | Restrictions.or()| Restrictions.disjunction() | |
not | Restrictions.not() | |
|
|
3、离线查询
什么是离线查询?
简单来说,正常情况下的查询,creteria的创建是依赖session的,使用session.createCriteria来创建。而离线的Criteria创建的时候是脱离session创建的,这样可以在web层去组装查询条件,可以在web层创建criteria,然后将Criteria传递给Service层和dao层。这样设计的好处是dao方法不用有多个。DetachedCriteria的对象一般被称为离线对象,该对象的用法和Criteria完全一样。
也就是说可以在web层创建离线查询对象,然后组装查询条件,再将离线查询对象传递到DAO层,进行查询操作,这样可以降低DAO层的代码复杂程度:
DetachedCriteria dc=DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.idEq(6l));
示例类代码如下:
public class OfflineQuery {
/**
* 离线条件查询
* 离线:
* 它是和在线对应的。
* Criteria对象是一个在线对象,它是由一个可用的(活动的)Session对象获取的出来的。
* 当session失效时,就无法再获取该对象了。
* 有一个对象,它也可以用于设置条件,但是获取的时候并不需要Session对象。
* 该对象就叫做离线对象:
* DetachedCriteria对象
* 使用该对象进行的查询就叫做:离线查询
*
* 如何获取该对象
* DetachedCriteria dCriteria = DetachedCriteria.forClass(要查询的实体类字节码);
*
*/
@Test
public void test3(){
//模拟一次web操作: 浏览器发送请求——调用servlet——调用service——调用dao——拿到结果到jsp上展示
List list = servletFindAllCustomer();
for(Object o : list){
System.out.println(o);
}
}
//模拟servlet
public List<Customer> servletFindAllCustomer(){
//离线对象
DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);
//设置条件:和Criteria是一样的
dCriteria.add(Restrictions.like("cust_name","%m%"));
return serviceFindAllCustomer(dCriteria);
}
public List<Customer> serviceFindAllCustomer(DetachedCriteria dCriteria) {
return daoFindAllCustomer(dCriteria);
}
public List<Customer> daoFindAllCustomer(DetachedCriteria dCriteria) {
Session s = HibernateSessionUtil.getSession();
//把离线对象使用可用Session激活
Criteria c = dCriteria.getExecutableCriteria(s);
List<Customer> list = c.list();
return list;
}
}