四 HQL与Criteria查询
HQL(Hibernate Query Language)
面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态;HQL主要通过Query来操作,Query的创建方式:
Query q = session.createQuery(hql);
from Person
from User user where user.name=:name
from User user where user.name=:name and user.birthday < :birthday
Criteria
Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式:
Criteria crit = session.createCriteria(DomainClass.class);
简单属性条件如:criteria.add(Restrictions.eq(propertyName, value)),
criteria.add(Restrictions.eqProperty(propertyName,otherPropertyName))
注意 解决在映射的表名或者属性名是数据库的关键字,导致利用hibernate建表不能成功的问题
在一些数据库中 比如oracle中 user是作为一个关键字存在的 但是我们映射文件中的映射表名也是user
这样利用hibernate建表是建不了的 可以使用``符号把对应的表名或者列名给引起来
具体方法 <class name="User" table="`user`">形式解决 但是我测试后发现控制台没报错误 也输出了
sql语句 但是就是在数据库中没有表存在
建议最佳解决办法:最好建的映射的表名或者或者映射的列名最好不要是数据库中的关键字
HQL语句的两种方式
第一种:from User as user where user.name=?;
第二种:from User as user where user.name=:name;
两种使用的区别:第一种 query.setString(0, name); 第二种 query.setString("name", name)注意"name" 必须跟
hql语句的:name一致;相比第一种,第二种的优势是,不会出现列名索引对应出错,而出现录入数据不正确的情况 并且
比较好维护
操作HQL语句的Query接口
list()方法 把数据转化为list集合数据
query.setFirstResult() 设置结果集的开始位置 query.setMaxResults() 设置结果集最长索引 用在分页显示数据的数据结果
uniqueResult() 如果数据库只有一行数据,那么就可以使用这个方法去查询数据
iterate() 把查询到得数据转化为迭代器
Criteria
Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式:
Criteria crit = session.createCriteria(DomainClass.class);
简单属性条件如:criteria.add(Restrictions.eq(propertyName, value)),
criteria.add(Restrictions.eqProperty(propertyName,otherPropertyName))
.常用的查询限制方法
在例程9-1中,Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制。这些方法及其他一些criteria常用查询限制方法列于表9-1中。
表9-1 Criteria Query常用的查询限制方法
方 法
说 明
Restrictions.eq()
equal,=
Restrictions.allEq()
参数为Map对象,使用key/value进行多个等于的对比,相当于多个Restrictions.eq()的效果
Restrictions.gt()
greater-than, >
Restrictions.lt()
less-than, <
Restrictions.le()
less-equal, <=
Restrictions.between()
对应SQL的between子句
Restrictions.like()
对应SQL的like子句
Restrictions.in()
对应SQL的in子句
Restrictions.and()
and关系
Restrictions.or()
or关系
Restrictions.isNull()
判断属性是否为空,为空返回true,否则返回false
Restrictions.isNotNull()
与Restrictions.isNull()相反
Order.asc()
根据传入的字段进行升序排序
Order.desc()
根据传入的字段进行降序排序
MatchMode.EXACT
字符串精确匹配,相当于“like 'value'”
MatchMode.ANYWHERE
字符串在中间位置,相当于“like '%value%'”
MatchMode.START
字符串在最前面的位置,相当于“like 'value%'”
MatchMode.END
字符串在最后面的位置,相当于“like '%value'”
例1:查询学生名字以t开头的所有Student对象。
Criteria cr = session.createCriteria(Student.class);
cr.add(Restrictions.like(“name”, “t%”))
List list = cr.list();
Student stu = (Student)list.get(0);
或者使用另一种方式:
Criteria cr = session.createCriteria(Student.class);
cr.add(Restrictions.like(“name”, “t”, MatchMode.START))
List list = cr.list();
Student stu = (Student)list.get(0);
例2:查询学生姓名在Bill, Jack和Tom之间的所有Student对象。
String[] names = {“Bill”, “Jack”, “Tom”}
Criteria cr = session.createCriteria(Student.class);
cr.add(Restrictions.in(“name”, names))
List list = cr.list();
Student stu = (Student)list.get(0);
例3:查询学生的年龄age等于22或age为空(null)的所有Student对象。
Criteria cr = session.createCriteria(Student.class);
cr.add(Restrictions.eq(“age”, new Integer(22));
cr.add(Restrictions.isNull(“age”));
List list = cr.list();
Student stu = (Student)list.get(0);
例4:查询学生姓名以字母F开头的所有Student对象,并按姓名升序排序。
Criteria cr = session.createCriteria(Student.class);
cr.add(Restrictions.like(“name”, “F%”);
cr.addOrder(Order.asc(“name”));
List list = cr.list();
Student stu = (Student)list.get(0);
调用Order.asc的方法应是Criteria的addOrder()方法。
下面给出一个小例子:
这里只列出其中一个页面,其它页面都没有列出,主要是让大家看看Query和Criteria怎么用
首先是Query的用法:
package cn.itcast.hibernate.domain;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import cn.itcast.hibernate.method.MethodManager;
public class QueryTest {
/**
* @param args
*/
public static void main(String[] args) {
User user = new User();
for(int i=1; i<5; i++) {
user.setName("Aaron"+i);
user.setBirthday(new Date());
MethodManager.addUser(user);//保存数据
}
User ss = new User();
ss.setName("Aaron1");
ss.setBirthday(new Date());
MethodManager.addUser(ss);
User ss1 = new User();
ss1.setName("Aaron1");
ss1.setBirthday(new Date());
MethodManager.addUser(ss1);
query("Aaron1");
}
@SuppressWarnings("unchecked")
static void query(String userName){
Session session = null;
try{
session = HibernateUtils.getSession();
String hql = "from User user where user.name = ?";
//String hql1 = "from User user where user.name.birthday is not null"; //多个属性不为空
//String hql = "from User as user where user.name = :ss";
Query query = session.createQuery(hql);
query.setString(0, userName);//问号的位置从0开始
//query.setString("ss", userName);//当多个问号时,可以指定别名,这样可以防止混乱
query.setFirstResult(0);//表示从结果集的第一条记录开始
query.setMaxResults(10);//表示每次取20条记录,这样可以实现跨数据库分页
List<User> list = query.list();
/* Iterator<User> iterator = query.iterate();
while(iterator.hasNext()){
System.out.println(iterator.next().getName());
} */
//User u = (User)query.uniqueResult();//确定独一无二的结果
//System.out.println(u);
/* List names = new ArrayList();
names.add("Aaron1");
names.add("Aaron2");
Query q = session.createQuery("from User user where user.name in (:naa) order by user.birthday desc");
q.setParameterList("naa", names);
List<User> cats = q.list();
for(User userList : cats){
System.out.println(userList.getName()+","+userList.getBirthday());
}
*///查询条件是一个集合
for(User userList : list){
System.out.println(userList.getName()+","+userList.getBirthday());
}
} finally {
if(session!=null)
session.close();//必须关闭session
}
}
}
Criteria的用法:
package cn.itcast.hibernate.domain;
import java.util.Date;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import cn.itcast.hibernate.method.MethodManager;
public class CriteriaQuery {
/**
* @param args
*/
public static void main(String[] args) {
User user = new User();
for(int i=1; i<5; i++) {
user.setName("Aaron"+i);
user.setBirthday(new Date());
MethodManager.addUser(user);//保存数据
}
User ss = new User();
ss.setName("Aaron1");
ss.setBirthday(new Date());
MethodManager.addUser(ss);
User ss1 = new User();
ss1.setName("Aaron1");
ss1.setBirthday(new Date());
MethodManager.addUser(ss1);
query("Aaron1");
}
@SuppressWarnings("unchecked")
static void query(String userName){
Session session = null;
try{
//Criteria和Restrictions实现条件查询
session = HibernateUtils.getSession();
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("name", userName));
criteria.add(Restrictions.le("birthday", new Date()));//多个add表示与
// criteria.add(Restrictions.or(Restrictions.eq("name", userName), Restrictions.eq("name", "Aaron2")));//表示逻辑或,表示名字为Aaron和Aaron1的都查询出来
criteria.addOrder(Order.desc("id")); //按照id倒序
//criteria.setFirstResult(0);
//criteria.setMaxResults(30);
List<User> list = criteria.list();
for(User userList : list){
System.out.println(userList.getName()+","+userList.getBirthday());
}
} finally {
if(session!=null)
session.close();//必须关闭session
}
}
}
补充 :Criteria查询
经验心得:相比Hql来说,Criteria查询方式可以使程序员在不懂sql的情况下进行数据的查询操作,并且Criteria查询方式其实也有Query的同样的查询方法 如分页用到的查询方式,不过官方推荐使用HQL查询