Hibernate使用Query查询
如果想要取得Query接口的实例化对象,必须依靠Session接口完成,在Session接口中定义有如下方法:
public Query createQuery(String queryString)
此处表示传入一个hql语法进行数据查询(Hibernate 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() | 数据更新 |
【范例】查询全部数据
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
import java.util.Iterator;
import java.util.List;
public class QueryDemoA {
public static void main(String[] args) {
String hql = "FROM Dept as d";//hql查询全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
List<Dept> allDepts = query.list();
Iterator<Dept> iter = allDepts.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
}
}
执行结果:
通过以上代码可以发现如下几点:
1. 在Hibernate里面使用的都是HQL,但是在使用HQL时一定要注意,FROM子句之后跟的是POJO类的名字,必须注意大小写,而“AS” 指的是别名,一般情况下可以省略。
2…在使用Hibernate进行数据查询时,发现 所有的内容都会自动以POJO类的形式返回。
【范例】查询指定的数据列
import com.gub.dbc.HibernateSessionFactory;
import org.hibernate.Query;
import java.util.Iterator;
public class QueryDemoB {
public static void main(String[] args) {
String hql = "SELECT d.dname,d.address FROM Dept AS d";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
Iterator<Object[]> iter = query.list().iterator();
while(iter.hasNext()){
Object[] objs = iter.next();
System.out.println(objs[0]+","+objs[1]);
}
HibernateSessionFactory.closeSession();
}
}
执行结果:
【范例】在Query中实现限定查询
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
public class QueryDemoC {
public static void main(String[] args) {
String hql = "FROM Dept AS d WHERE d.deptno=?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0,3);//所有的类型由Hibernate处理
Dept dept = (Dept)query.uniqueResult();//表示只返回一个数据的情况
System.out.println("dept = " + dept);
HibernateSessionFactory.closeSession();
}
}
执行结果:
【范例】实现模糊查询
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
import java.util.Iterator;
public class QueryDemoD {
public static <List> void main(String[] args) {
String column = "dname";
String keyword = "财";
String hql = "FROM Dept AS d WHERE "+column+" like ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0,"%"+keyword+"%");//所有的类型由Hibernate处理
Iterator<Dept> iter = query.list().iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
}
}
执行结果:
【范例】实现分页查询
各个数据库之中最麻烦的在于分页的支持不同,而Hibernate是一个跨数据库的工具,所以里面的分页将使用统一的方式进行处理,在Query接口里面定义有两个操作方法:
| 方法 | 描述 |
|---|---|
| public Query setFirstResult(int firstResult) | 设置开始行 |
| public Query setMaxResults(int maxResults) | 设置最大返回行 |
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
import java.util.Iterator;
public class QueryDemoE {
public static <List> void main(String[] args) {
Integer currentPage = 1;
Integer lineSize = 2;
String column = "dname";
String keyword = "部";
String hql = "FROM Dept AS d WHERE "+column+" like ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0,"%"+keyword+"%");//所有的类型由Hibernate处理
query.setFirstResult((currentPage-1)*lineSize);
query.setMaxResults(lineSize);
Iterator<Dept> iter = query.list().iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
}
}
执行结果:
【范例】统计数据个数
在Query接口中如果想要实现数据统计的话,那么就要自己编写SELECT语句了,但是统计的个数只有一个。
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
import java.util.Iterator;
public class QueryDemoF {
public static <List> void main(String[] args) {
String column = "dname";
String keyword = "部";
String hql = "SELECT COUNT(*) FROM Dept AS d WHERE d."+column+" like ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0,"%"+keyword+"%");//所有的类型由Hibernate处理
Long num = (Long) query.uniqueResult();
int count = num.intValue();
System.out.println(count);
HibernateSessionFactory.closeSession();
}
}
Hibernate中返回的数据个数的统计结果类型为long,如果要使用int,则还需要将long变为int。
执行结果:
【范例】使用SQL查询(了解)
即使HQL的语法很像SQL语法,但它不是SQL,所以很多时候支持度不够,在Hibernate里面也可以使用普通的SQL进行数据的查询,但是如果想要将查询结果变为POJO类的形式,必须使用转换的形式。
如果想要创建SQL查询,在Session接口定义了如下方法:
| 方法 | 描述 |
|---|---|
| public SQLQuery createSQLQuery(String queryString) | 创建SQL查询 |
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.SQLQuery;
import org.hibernate.transform.AliasToBeanResultTransformer;
import java.util.Iterator;
import java.util.List;
public class QueryDemoG {
public static void main(String[] args) {
String sql = "SELECT deptno,dname,address FROM Dept";
SQLQuery sqlQuery = HibernateSessionFactory.getSession().createSQLQuery(sql);
sqlQuery.setResultTransformer(new AliasToBeanResultTransformer(Dept.class));//转换器
List<Dept> allDepts = sqlQuery.list();
Iterator<Dept> iter = allDepts.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
}
}
执行结果:
【范例】查询占位符
在之前编写HQL的时候使用的占位符都是"?"(推荐做法),但是在HQL里面对于占位符还有另外一种形式,使用 “:名称” 描述,这样的目的主要是为了解决设置的内容过多的时候,“?”容易数不清楚。
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
import java.util.Iterator;
import java.util.List;
public class QueryDemoH {
public static void main(String[] args) {
String hql = "FROM Dept AS d WHERE d.deptno=:deptno";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter("deptno",3);
Dept dept = (Dept)query.uniqueResult();
System.out.println("dept = " + dept);
}
}
执行结果:
注意:?和占位符最好不要同时使用,如果要混用,请将?写在":"之前,否则就会出错
【范例】在配置文件中编写HQL(了解)
对于HQL的操作如果直接写在程序之中可能会比较混乱,希望可以将HQL和查询分开,但是要想分开必须借助于*.hbm.xml文件完成。
在*.hbm.xml的根节点之下添加query节点
<query name="findById">
FROM Dept AS d WHERE d.deptno=:deptno
</query>
在程序中读取这样的配置信息
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.Dept;
import org.hibernate.Query;
public class QueryDemoI {
public static void main(String[] args) {
//读取配置文件中的findById元素配置的内容
Query query = HibernateSessionFactory.getSession().getNamedQuery("findById");
query.setParameter("deptno",3);
Dept dept = (Dept)query.uniqueResult();
System.out.println("dept = " + dept);
}
}
执行结果:
【范例】Query接口更新数据
在Hibernate最早设计的时候,所有的更新操作只能够通过uodate()方法或者是delete()方法实现,但是发现如果使用这些方法无法实现部分数据的更新。
从·Hibernate2.x开始针对于Query接口进行了扩充,让其可以实现更新操作。
import com.gub.dbc.HibernateSessionFactory;
import org.hibernate.Query;
public class QueryUpdate {
public static void main(String[] args) {
String hql = "UPDATE Dept SET dname=?,address=? WHERE deptno=?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0,"xx部门");
query.setParameter(1,"xx地址");
query.setParameter(2,1);
int len = query.executeUpdate();
System.out.println("更新操作影响的行数:"+len);
HibernateSessionFactory.getSession().beginTransaction().commit();
HibernateSessionFactory.closeSession();
}
}
执行结果:
【范例】Query接口实现数据删除操作
import com.gub.dbc.HibernateSessionFactory;
import org.hibernate.Query;
public class QueryUpdate {
public static void main(String[] args) {
String hql = "DELETE FROM Dept WHERE deptno=?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0,1);
int len = query.executeUpdate();
System.out.println("更新操作影响的行数:"+len);
HibernateSessionFactory.getSession().beginTransaction().commit();
HibernateSessionFactory.closeSession();
}
}
执行结果: