文章目录
1 Session查询
Session接口里面本身所定义的数据查询只有一个根据ID查询的操作方法,但是这个方法却有两个定义:
(1)根据主键查询:public <T> T get(Class<T> entityType, Serializable id)
(2)根据主键查询:public <T> T load(Class<T> theClass, Serializable id)
两个操作方法上只差了一个单词,那么使用上有差别吗?
范例:使用get()查询
package org.lks.test;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class TestNewsGet {
public static void main(String[] args) {
News vo = HibernateSessionFactory.getSession().get(News.class, 100);
System.out.println(vo);
HibernateSessionFactory.closeSession();
}
}
Hibernate:
select
news0_.nid as nid1_0_0_,
news0_.ntitle as ntitle2_0_0_,
news0_.nvisits as nvisits3_0_0_,
news0_.nitem as nitem4_0_0_
from
hedb.news news0_
where
news0_.nid=?
null
package org.lks.test;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class TestNewsGet {
public static void main(String[] args) {
News vo = HibernateSessionFactory.getSession().load(News.class, 100);
System.out.println(vo);
HibernateSessionFactory.closeSession();
}
}
Hibernate:
select
news0_.nid as nid1_0_0_,
news0_.ntitle as ntitle2_0_0_,
news0_.nvisits as nvisits3_0_0_,
news0_.nitem as nitem4_0_0_
from
hedb.news news0_
where
news0_.nid=?
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [org.lks.pojo.News#100]
使用load()查询的时候如果指定的ID不存在,那么就会出现异常。
面试题:请问Hibernate中get()与load()方法有什么区别?
(1)get()与load()方法都是在Session接口中定义的根据主键查询的操作;
(2)get()方法查询时,如果主键不存在,则返回null;
(3)load()方法查询时,如果主键不存,则抛出异常。
2 Query查询
面对数据操作中,数据的查询部分永远都是最为复杂的部分,所以来讲如果要进行更加合理的查询操作,那么必须依靠Query接口来实现,而如果要想取得此接口的实例化对象,必须依靠Session接口完成,在Session接口中定义有如下方法:
(1)取得Query接口对象:public Query createQuery(String queryString)
|————此处表示传入一个hql语法进行数据查询(Hibernate Query Language)
在Query接口里面主要定义了如下几个操作方法:
(1)设置要操作的数据:【Deprecated】default Query<R> setXxx(int position, 数据类型 val)
|————(since 5.2) use setParameter(int, Object) or setParameter(int, Object, Type) instead
Bind a positional float-valued parameter.
(2)设置参数:public Query<R> setParameter(int position, Object value)
;
(3)取得单个查询结果:public R uniqueResult()
;
(4)查询全部数据:public List<R> list()
;
(5)数据更新:public int executeUpdate()
;
2.1 数据查询
在Hibernate里面Session查询不能够胜任于复杂查询,所以现在的所有查询都通过Query接口完成,那么在这个接口里面要使用hql语言(极其类似于SQL语句)。
范例:查询全部数据
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoA {
public static void main(String[] args) {
String hql = "FROM News AS n"; //hql查询全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
}
}
现在通过以上的代码可以发现如下几点:
(1)在Hibernate里面使用的都是HQL,但是在使用HQL的时候一定要注意,FROM子句之后跟的是POJO类的名字,必须注意大小写News.java
(News),而AS
指的就是别名,一般情况下可以省略。
(2)在使用Hibernate进行数据查询的时候,发现所有的内容都会自动以POJO类的形式返回,所有的实例化的操作部分都由Hibernate自动帮助用户处理了;
所谓的HQL其语法的结构非常类似于SQL语法结构,那么也可以编写SELECT语句,但是大部分人不会这么写。
范例:查询指定的数据列
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
public class QueryDemoA {
public static void main(String[] args) {
String hql = "SELECT n.ntitle,n.nitem FROM News AS n"; //hql查询全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
List<Object[]> all = query.list();
Iterator<Object[]> iter = all.iterator();
while(iter.hasNext()){
Object[] obj = iter.next();
System.out.println(obj[0] + ", " + obj[1]);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
此时的代码的确是进行了数据列的操作限制,但是其结果发现为了保证查询,那么返回的数据不再自动转化为News这个POJO类,而是以对象数组的形式返回,相比较自动匹配POJO类型,以上的操作明显不方便。
Hibernate在设计的时候考虑到了以上的情况,所以在Hibernate里面提供有一个专门负责转换处理的类(org.hibernate.transform.AliasToBeanResultTransformer
),但是即便转换了你也需要做一些辅助性的操作。随后在Query接口里面使用如下的转换操作方法明确设置:
(1)设置结果转换:【Deprecated】default Query<R> setParameters(Object[] values, Type[] types)
范例:手工转换
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoC {
public static void main(String[] args) {
String hql = "SELECT n.ntitle AS ntitle,n.nitem AS nitem FROM News AS n"; //hql查询全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setResultTransformer(new AliasToBeanResultTransformer(News.class));
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
在本代码之中实际上只是一个功能的演示,如果真查询,就查询全部数据,千万别做部分数据的查询。
那么既然可以实现查询全部的操作,就一定可以实现根据ID查询的操作,也就是说使用限定查询。
范例:在Query中实现限定查询
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public