(六)Hibernate数据查询

Session接口

    Session接口里面本身所定义的数据查询只有一个根据ID查询的操作方法,但是这个方法有两个定义

根据主键查询:

load(Class<T> theClass, Serializable id)

根据主键查询:

get(String entityName, Serializable id)

get查询不存在的ID会返回null,而load会报错

面试题:请问Hibernate中定义的Session中get()与load()方法有什么区别?

    get()和load()方法都是在Session接口中定义的根据主键查询的操作;

   get()方法查询不存在会返回null,

   load()方法查询时,如果主键不存在,则抛出异常.

Query查询

  面对数据操作中,数据查询的部分永远都是最为复杂的部分,所以来讲如果要进行更加合理的,那么必须依靠Query接口来实现,而如果要想取得此接口的实例化对象,必须依靠Session接口完成,在Session接口中定义有如下的方法:

        取得Query接口对象

Query createQuery(String queryString)
       此处表示传入一个hql语法进行数据查询(Hibernat Query Language);

  在Query接口里面主要定义如下几个操作方法:

    ●设置要操作的数据:public Query setXxx(int position,数据类型 val)

    ●设置参数:public Query setParameter(int position,Object val);

    ●取得单个查询结果:public Object uniqueResult();

    ●查询全部数据 public List list()

    ●数据更新:public int executeUpdate()

数据查询

    在Hibernate里面Session的查询不能够胜任于复杂查询,所以现在的所有查询都通过Query接口完成,在这个接口里面要使用hql语言(及其类似 于SQL语句)

范例:查询全部数据

package cn.zwb.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;

public class QueryDemoA {
	public static void main(String[] args) {	
		String hql="FROM News AS n";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		List<News> all=query.list();
		Iterator<News> iterator =all.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
		HibernateSessionFactory.closeSession();
	}
}

  现在通过以上代码可以发现如下几点:

    ●在Hiberante里面使用的都是HQL,但是在使用HQL的时候一定要注意,FROM子句后面跟的是POJO类的名字,必须注意大小写"News.java"(News),而"AS"指的就是别名,一般情况下可以省略

    ●在使用Hiberante进行数据查询的时候,发现所有的内容都会以POJO类的形式返回,所有的实例化操作部分都由Hibernate自动帮助用户处理了,

    所谓的HQL语法的结构非常类似于SQL语句,那么也可以编写SELECT语句,但是大部分人不会这么写.

范例:查询指定数据列

package cn.zwb.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;

public class QueryDemoB {
	public static void main(String[] args) {	
		String hql="SELECT n.title,n.item FROM News AS n";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		List<Object[]> all=query.list();
		Iterator<Object[]> iterator =all.iterator();
		while(iterator.hasNext()){
			Object[] obj=iterator.next();
			System.out.println(obj[0]+","+obj[1]);
		}
		HibernateSessionFactory.closeSession();
	}
}

        此时的代码的确是进行了数据列的操作限制,但是其结果发现为了保证查询,那么返回的数据不再自动转换为POJO类,而是以对象数组的形式返回,相比较POJO类型,以上的操作明显不方便.

范例:使用限定查询

package cn.zwb.test;
import org.hibernate.Query;

import cn.zwb.dbc.HibernateSessionFactory;
public class QueryDemoD {
	public static void main(String[] args) {	
		String hql="FROM News n WHERE n.nid=?";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		query.setParameter(0, 3);  //?从0开始,所有的类型都由Hibernate自己处理,
		System.out.println(query.uniqueResult());
	}
}

        模糊查询在Query中可以继续像SQL那样直接使用

范例:实现模糊查询

package cn.zwb.test;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class QueryDemoE {
	public static void main(String[] args) {	
		String hql="FROM News n WHERE n.title LIKE ?";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		query.setParameter(0, "%啦啦%");  //?从0开始,所有的类型都由Hibernate自己处理,
		List<News> all=query.list();
		Iterator<News> iterator =all.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
		HibernateSessionFactory.closeSession();
	
	}
}

       各个数据库之中最麻烦的在于分页的支持不同,而Hibernate是一个跨数据库的工具,所以里面的分页将使用统一的方式进行处理,在Query接口里面定义有两个操作方法;

        ●设置开始行:public Query setFirstResult(int firstResult);

        ●设置最大返回行:public Query setMaxResults(int maxResults)

使用分页查询

package cn.zwb.test;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class QueryDemoF {
	public static void main(String[] args) {	
		String hql="FROM News n ";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		query.setFirstResult((6-1)*2);
		query.setMaxResults(2);
		List<News> all=query.list();
		Iterator<News> iterator =all.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
		HibernateSessionFactory.closeSession();
	
	}
} 

  不管是什么数据库,只要是设置了分页都会由Hibernate自己进行适应

        Query接口进行数据统计

package cn.zwb.test;
import org.hibernate.Query;
import cn.zwb.dbc.HibernateSessionFactory;
public class QueryDemoG {
	public static void main(String[] args) {	
		String hql="SELECT COUNT(*) FROM News n ";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		System.out.println(((Long)query.uniqueResult()).intValue());
		HibernateSessionFactory.closeSession();
	
	}
}

        Hibernate中返回的数据个数统计的类型为Long,如果要使用int则还需要将Long变为int

使用SQL查询(不建议使用)

        即使HQL的语法很像SQL语法,但是它依然不是SQL,所以很对时候可能支持度有限.所以为了解决这样的问题,在Hibernate里面也可以使用普通的SQL语句进行数据的查询,但是如果要想将查询结果变为POJO类的形式,则需使用转换操作

        如果要创建SQL查询,在Session接口里面定义有如下方法:

        ●创建SQL查询:public SQLQuery createSQLQuery(String queryString);

查询占位符

        在之前编写的时候使用的HQL的占位符都是"?"(推荐做法),但是在HQL里面对于占位符还有另外一种形式":名称描述",这样的目的主要是为了解决设置的内容过多的时候,"?"容易数不清楚

范例:使用其他占位符

package cn.zwb.test;
import org.hibernate.Query;
import cn.zwb.dbc.HibernateSessionFactory;
public class QueryDemoG {
	public static void main(String[] args) {	
		String hql="FROM News as n WHERE n.nid=:pnid";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		query.setParameter("pnid", 5);
		System.out.println(query.uniqueResult());
		HibernateSessionFactory.closeSession();
	
	}
}

        但是:和?不可以一起使用,如果要想混合使用要将?放在前面,

更新操作

        在Hibernate最早设计的时候,所有的更新操作只能够通过update()方法或者是delete()执行,按时随着时间的发展,发现一个问题,如果使用这些方法无法实现部分数据的更新.

        从Hibernate 2.x开始针对于Query接口实现了功能的扩充,让其可以实现数据更新操作.

范例:使用Query接口更新数据

package cn.zwb.test;
import org.hibernate.Query;
import cn.zwb.dbc.HibernateSessionFactory;
public class QueryUpdateA {
	public static void main(String[] args) {	
		String hql="UPDATE News SET title=?,visits=?";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		query.setParameter(0, "修改标题l");
		query.setParameter(1, 50);
		int len=query.executeUpdate();
		System.out.println("更新行数"+len);
		HibernateSessionFactory.getSession().beginTransaction().commit();
		HibernateSessionFactory.closeSession();
	
	}
} 

范例:实现数据删除操作:

package cn.zwb.test;
import org.hibernate.Query;
import cn.zwb.dbc.HibernateSessionFactory;
public class QueryUpdateB {
	public static void main(String[] args) {	
		String hql="DELETE News WHERE nid=?";
		Query query=HibernateSessionFactory.getSession().createQuery(hql);
		query.setParameter(0, 4);
		int len=query.executeUpdate();
		System.out.println("更新行数"+len);
		HibernateSessionFactory.getSession().beginTransaction().commit();
		HibernateSessionFactory.closeSession();
	
	}
}

Criteria接口

        大部分情况下如果要使用查询操作,首先一定是HQL查询,但是在Hibernate之中有一个特殊情况,Hibernate属于ORMapping的映射框架,那么如果是ORMapping的映射框架,所有的操作偶应该以对象为主进行使用,那么Query的使用就不符合于这种要求了,所以在查询的基础上又扩充了一个基于对象模式的查询接口:Criteria,而这个接口的创建依靠session接口
Criteria createCriteria(Class persistentClass)

范例:查询全部数据

package cn.zwb.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class CriteriaDemoA {
	public static void main(String[] args) {
		Criteria criteria=HibernateSessionFactory.getSession().createCriteria(News.class);
		List<News> allList=criteria.list();
		Iterator<News> iter =allList.iterator();
				while(iter.hasNext()){
					System.out.println(iter.next());
				}
		HibernateSessionFactory.closeSession();
	}
}

        如果只是这种简单的查询,那么使用Criteria接口一定要比使用Query接口更加容易

        但是实际的开发之中,虽然需要查询全部,但是很多时候都需要限定查询,所以在Criteria里面也支持查询条件,此接口定义了如下一个增加查询条件的方法

Criteria add(Criterion criterion)

        那么对于所有的条件的创建还需要使用另外一个类:

  • org.hibernate.criterion.Restrictions

这个类定义了如下几个操作方法:

        ●逻辑运算:

            丨-与运算(AND)

public static Conjunction and(Criterion... predicates)

            丨-或运算(OR)

public static Disjunction or(Criterion... predicates)

            丨-非运算

public static Criterion not(Criterion expression)

        ●关系运算:

            |-"=="

public static SimpleExpression eq(String propertyName,
                                  Object value)

            |-"!="

public static SimpleExpression ne(String propertyName,
                                  Object value)

            |-">"

public static SimpleExpression gt(String propertyName,
                                  Object value)

            |-">="

public static SimpleExpression ge(String propertyName,
                                  Object value)

            |-"<"

public static SimpleExpression lt(String propertyName,
                                  Object value)

            |-"<="

public static SimpleExpression le(String propertyName,
                                  Object value)

            |-"LIKE"

public static SimpleExpression like(String propertyName,
                                    Object value)

            |-"IN"

public static Criterion in(String propertyName,
                           Collection values)

                |-"BETWEEN...AND"

public static Criterion between(String propertyName,
                                Object low,
                                Object high)

                |-"IS NULL"

public static Criterion isNull(String propertyName)

                |-"IS NOTNULL"

public static Criterion isNotNull(String propertyName)

范例:根据ID查询

package cn.zwb.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class CriteriaDemoA {
	public static void main(String[] args) {
		Criteria criteria=HibernateSessionFactory.getSession().createCriteria(News.class);
		criteria.add(Restrictions.eq("nid", 3));
		List<News> allList=criteria.list();
		Iterator<News> iter =allList.iterator();
				while(iter.hasNext()){
					System.out.println(iter.next());
				}
		HibernateSessionFactory.closeSession();
	}
}

范例:取得访问量大于100的信息

        

package cn.zwb.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class CriteriaDemoC {
	public static void main(String[] args) {
		Criteria criteria=HibernateSessionFactory.getSession().createCriteria(News.class);
		criteria.add(Restrictions.gt("visits",100));
		List<News> allList=criteria.list();
		Iterator<News> iter =allList.iterator();
				while(iter.hasNext()){
					System.out.println(iter.next());
				}
		HibernateSessionFactory.closeSession();
	}
}

        在整个Criteria操作之中,如果要说最有用处的操作,只有一个:IN()操作,因为这个接口的IN操作可以直接将要查询的数据以Collection形式保存.

范例:使用IN查询

package cn.zwb.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class CriteriaDemoD {
	public static void main(String[] args) {
		Set<Integer> ids=new HashSet<Integer>();
		ids.add(1);
		ids.add(3);
		Criteria criteria=HibernateSessionFactory.getSession().createCriteria(News.class);
		criteria.add(Restrictions.in("nid",ids));
		List<News> allList=criteria.list();
		Iterator<News> iter =allList.iterator();
				while(iter.hasNext()){
					System.out.println(iter.next());
				}
		HibernateSessionFactory.closeSession();
	}
}

        在Criteria接口操作的时候还可以设置排序,里面提供了排序的方式:

Criteria addOrder(Order order)

            ●升序排列:

public static Order asc(String propertyName)

            ●降序排列:

public static Order desc(String propertyName)

package cn.zwb.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import cn.zwb.dbc.HibernateSessionFactory;
import cn.zwb.pojo.News;
public class CriteriaDemoD {
	public static void main(String[] args) {
		Set<Integer> ids=new HashSet<Integer>();
		ids.add(1);
		ids.add(3);
		Criteria criteria=HibernateSessionFactory.getSession().createCriteria(News.class);
		criteria.addOrder(Order.desc("nid"));
		List<News> allList=criteria.list();
		Iterator<News> iter =allList.iterator();
				while(iter.hasNext()){
					System.out.println(iter.next());
				}
		HibernateSessionFactory.closeSession();
	}
}
       

猜你喜欢

转载自blog.csdn.net/qq1019648709/article/details/80700539