java

位置:IT落伍者 >> java >> 浏览文章

Hibernate数据查询


发布日期:2022年03月18日
 
Hibernate数据查询

Hibernate Query Language(HQL)

Criteria Query

Native SQL

下面对其分别进行解释

Hibernate Query Language:

HQL提供了是十分强大的功能它是针对持久化对象用取得对象而不进行updatedelete和insert等操作而且HQL是面向对象的具备继承多态和关联等特性

from子句

from子句是最简单的HQL例如from Student也可以写成 select s from Student s它简单的返回Student类的所有实例

值得注意的是除了JAVA类和属性的名称外HQL语句对大小写不敏感

select子句

有时并不需要取得对象的所有属性这时可以使用select子句进行属性查询如select sname from Student s

public void HQLselectDEMO()

{

TRegister user = new TRegister();

Session session = HibernateUtilcurrentSession();

Query query = sessioncreateQuery(select uuserName from TRegister u);

List list = querylist();

for(int i = ; i < listsize(); i++)

{

String name = (String)listget(i);

Systemoutprintln(name);

}

}如果要查询两个以上的属性桧以数组的方式返回如下 public void HQLselectDEMO()

{

TRegister user = new TRegister();

Session session = HibernateUtilcurrentSession();

Query query = sessioncreateQuery(select uuserName usex from TRegister u);

List list = querylist();

for(int i = ; i < listsize(); i++)

{

Object obj[] = (Object[])listget(i);

Systemoutprintln(obj[]+ 的性别是+obj[]);

}

}

在使用属性查询时由于使用对象数组操作和理解不太方便如果将 一个object[]中所有成员封装成一个对象就方便多了下面的程序做了示例 public void HQLselectDEMO()

{

Session session = HibernateUtilcurrentSession();

Query query = sessioncreateQuery(select new TRegister(uuserNameusex) from TRegister u);

List list = querylist();

for(int i = ; i < listsize(); i++)

{

//Object obj[] = (Object[])listget(i);

TRegister user = (TRegister)listget(i);

Systemoutprintln(usergetUserName()+ 的性别是+usergetSex());

}

/** *//**要正确运行以上程序需要在TRegister类中加入一个相应的构造函数

public TRegister(String userNameString sex) {

thisuserName = userName;

thissex = sex;

}

*/

}

统计函数查询

可以在HQL中使用函数经常使用的函数如下

count()统计记录条数

min()求最小值

max()求最大值

sum()求和

avg()求平均值

例如要取得Student实例的数量可以编写如下HQL语句

select count(*) from Student

取得Student平均年龄的HQL语句

select avg(sage) from Student as s

可以使用distinct去除重复的数据

select distinct sage from Student as s

where子句

HQL也支持子查询它通过where子句实现这一机制where子句可以让用户缩小要返回的实例的列表范围例如下面语句会返回所有名字为Bill的Student实例

Query query = sessioncreateQuery(from Student as s where sname=Bill);

where子句允许出现的表达式包括了SQL中可以使用的大多数情况

数学操作+*/

真假比较操作= >= <= <> != like

逻辑操作and or not

字符串连接||

SQL标题函数 如upper()和lower()

如果查询返回多条记录可以用以下关键字来量化

all表示所有的记录

any表示所有记录中的任意一条

some与any相同

in与any等价

exists表示子查询至少要返回一条记录

例如下面语句返回所有学生年龄都大于的班级对象

from Group g where <all (select sage from gstudents s)

下列语句返回在所有学生中有一个学生的年龄等于的班级

from Group g where = any (select sage from gstudents s)

或者

from Group g where = some(select sage from gstudents s)

或者

from Group g where in (select sage from gstudents s)

order by子句

查询返回列表可以按照任何返回的类或者组件的属性排序

from Student s order by sname asc

连接查询

与SQL一样HQL也支持连接查询如内连接外连接和交叉连接

inner join内连接

left outer join左外连接

rigth outer join右外连接

full join全连接但不常用

下面我重点介绍下内连接查询左外连接和或外连接和内连接大同小异而全连接几乎没有使用得到的地方

inner join可以简写为join例如在查询得到的Group对象时内连接取得对应的Student对象实现的程序代码如下

Student stu = null;

Group group = null;

Query query = sessioncreateQuery(from Group g join gstudents);

List list = querylist();

Object obj[] = null;

for(int i = ; i < listsize(); i++)

{

obj = (Object[])listget(i);

group = (Group)obj[];//group是数组是第一个对象

stu = (Student)obj[];//stu是数组的第二个对象

Systemoutprintln(stugetName()+属于+groupgetName());

}

Criteria Query方式

当查询数据时往往需要设置查询条件在SQL或HQL语句中查询条件常常放在where子句中此处Hibernate还支持Criteria查询这种查询方式把查询条件封装为一个Criteria对象在实际应用中可以使用Session的createCriteria()方法构建一个orghibernateCriteria实例然后把具体的查询条件通过Criteria的add方法加入到Criteria实例中这样程序员可以在不使用SQL甚至HQL的情况下进行数据查询如下 public void criteriaDEMO()

{

Session session = HibernateUtilcurrentSession();

Criteria criteria = sessioncreateCriteria(TRegisterclass);//生成一个Criteria实例

criteriaadd(Restrictionseq(userNamefengyan));//等价于where name = fengyan

List list = criterialist();

TRegister user = (TRegister)listget();

Systemoutprintln(usergetUserName());

}

常用的查询限制方法

上面代码中 Restrictionseq()方法表示equal即等于的情况Restrictions类提供了查询限制机制它提供了许多方法以实现查询限制

Restrictionseq()equal=

RestrictionsallEq() 参数为Map对象使用key/value进行多个等于的对比相当于多个 Restrictionseq()的效果

Restrictionsgt()greaterthan<

Restrictionslt()lessthan<

Restrictionslelessequal<=

Restrictionsbetween()对应SQL的between子句

Restrictionslike()对应SQL的like子句

Restrictionsin()对应SQL的in子句

Restrictionsand()and 关系

Restrictionsor()or 关系

RestrictionsisNull()判断属性是否为空为空返回true否则返回false

RestrictionsisNoyNull()与上面的相反

Orderasc()根据传入的字段进行升序排序

Orderdesc()与上相反

MatchModeEXACT字符串中精确匹配相当于like value

MatchModeANYWHERE字符串在中间位置相当于like%value%

MatchModeSTART字符串在最前面相当于likevalue%

MatchModeEND字符串在最后相当于like%value

下面是几个查询限制的例子

查询学生名字以t开关的所有Student对象

Criteria criertia = sessioncreateCriteria(Studentclass);

criteriaadd(Restrictionslike(name t%));

List list = criterialist();

Student stu = (Student)listget();

或者

Criteria criertia = sessioncreateCriteria(Studentclass);

criteriaadd(Restrictionslike(name tMatchModeSTART));

List list = criterialist();

Student stu = (Student)listget();

查询学生姓名在BillJack和Tom之间所有的Student对象

String[] names = {BillJackTom};

Criteria criertia = sessioncreateCriteria(Studentclass);

criteriaadd(Restrictionsin(name names));

List list = criterialist();

Student stu = (Student)listget();

查询学生年龄(age)等于或为空(null)的所有学生对象

Criteria criertia = sessioncreateCriteria(Studentclass);

criteriaadd(Restrictionseq(age new Integer()));

criteriaadd(RestrictionsisNull(age));

List list = criterialist();

Student stu = (Student)listget();

查询学生姓名以字母F开头的所有Student对象并按姓名升序排序

Criteria criertia = sessioncreateCriteria(Studentclass);

criteriaadd(Restrictionslike(name F%));

criteriaaddOrder(Orderasc(name));

List list = criterialist();

Student stu = (Student)listget();

注意调用Orderasc的方法应该是CriteriaaddOrder()方法

连接限制

Criteria查询中使用FetchMode来实现连接限制在HQL语句中可以通过fetch关键字来表示预先抓取(Eager fetching)如下

from Group g

left join fetch gstudents s

where gname like %

可以使用Criteria的API完成同样的功能如下

Criteria criertia = sessioncreateCriteria(Groupclass);

criteriasetFetchMode(students FetchModeEAGER);

criteriaadd(Restrictionslike(name MatchModeEND));

List list = criterialist();

以上两种方式编写的代码都使用相同的SQL语句来完成它们的功能如下

select g* s* from Group g

left outer join Student s

on gid = sgroup_id

where gname like %

Native SQL查询

本地SQL查询指的是直接使用本地数据库的SQL语言进行查询这样做对于将 原来的SQL/JDBC程序迁移到Hibernate应用很有用

创建一个基于SQL的Query

Native SQL查询是通过SQLQuery接口来控制的它通过调用SessioncreateSQLQuery()方法来获得

String sql = select {s*} from t_student s where sage>;

//{}用来引用数据表的别名{s*}表示使用s来做为t_student表的别名

SQLQuery sqlQuery = sessioncreateSQLQuery(sql);

sqlQueryaddEntity(sStudentclass);

List list = sqlQuerylist();

for(int i = ; i < listsize(); i++)

{

Student stu = (Student)listget(i);

}

//createSQLQuery(String sql)利用传入的sql参数构造一个SQLQuery实例使用该方法时还需要传入查询的实体类因此在配合使用SQLQuery的addEntity()方法一起使用

命名SQL查询

与HQL的命名查询相似也可以将 本地的SQK查询语句定义在映射文件中然后像调用一个命名HQL查询一样专题报道调用命名SQL查询

</class>

<sqlquery name=QueryStudents>

<![CDATA[

select {s*} from t_student s where sage >

]]>

<return alias=s class=Student />

</sqlquery>

</hibernatemapping>配合以上配置我们可以如下编写代码来查询 Query query = sessiongetNamedQuery(QueryStudents);

List list = querylist();

for(int i = ; i < listsize();i++)

{

Student stu = (Student)listget(i);

}

也可以在命名查询是设定参数如下 <sqlquery name=QueryStudents>

<![CDATA[

select {s*} from t_student s where sage > :age

]]>

<return alias=s class=Student />

</sqlquery>

</hibernatemapping>程序代码 Query query = sessiongetNamedQuery(QueryStudents);

querysetInteger(age);

List list = querylist();

for(int i = ; i < listsize();i++)

{

Student stu = (Student)listget(i);

}自定义insert update和delete语句

Hibernate x的映射文件中新添加<sql_insert><sql_update><sqldelete>个标记可以使用这个标记自定义自己的insert updatedelete语句 </class>

<sqlinsert>

insert into t_student(nameageid) values(???)

</sqlinsert>

<sqlupdate>

update t_student set name=?age=? where id=?

</sqlupdate>

<sqldelete>

delete from t_student where id = ?

</sqldelete>

</hibernatemapping>对于以上自定义的SQL语句要注意以下几点

insert 和update语句中定义的字段必须和映射文件声明的属性相应一个都不能少

在insert 和update语句中属性出现的顺序必须和映射文件中的顺序一样

在insert语句中主键id总是放在最后

在程序中实现以上自定义的insert语句如下 Student stu = new Student();

stusetName(Bill);

stusetAge();

sessionsave(stu);如果不想在insert或update语句中包括所有属性则可以在属性定义时 加上insert =false或update=false如下 <property name = name type=string insert = false update=false/>

<sqlinsert>

insert into t_student(ageid) values(??)

</sqlinert>

               

上一篇:浅析Struts2与Webwork2的区别

下一篇:SPRING容器外访问SPRING