Hibernate的事务级别控制与查询对象的API(Query查询与Criterial查询+离线查询)

12 篇文章 0 订阅
5 篇文章 0 订阅

1、事务级别控制

可以在Hibernate的配置文件中对事务进行配置。配置文件中,可以设置事务的隔离级别。其具体的配置方法是在hibernate.cfg.xml文件中的<session-factory>标签元素中进行的。配置方法如下所示。(这些事务隔离级别的具体描述可见JDBC)

<!—

 事务隔离级别 

hibernate.connection.isolation = 4

1Read uncommitted isolation

2Read committed isolation

4Repeatable read isolation

8Serializable 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;
	}		
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值