批量更新
//查询User表中的所有记录
ScrollableResults uScrollableResults = session.createQuery("from User")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count = 0;
//遍历User表中的全部记录
while(uScrollableResults.next()) {
User user = uScrollableResults.get(0);
// user.setFullName(fullName);
user.setName("newName");
if(++count % 20) {
session.flush();
session.clear();
}
}
DML风格的批量更新
String hqlUpdate = "update User u set name= :newName";
//执行更新
int updateEntities = session.createQuery(hqlUpdate)
.setString("newName", "新名字")
.executeUpdate();
String halDelete = "delete User";
//执行删除
int deleteEntities = session.createQuery(halDelete)
.executeUpdate();
1HQL查询
HQL是 Hibernate Query Language的缩写,HQL的语法很像SQL的语法,但HQL是一种面向
的查询语言。SQL的操作对象是数据表、列等数据库对象,而HQL的操作对象是类、实例、属性等。
HQL是完全面向对象的查询语言,因此可以支持继承、多态等特性。
HQL查询依赖于 Query类,每个Quey实例对应一个查询对象。使用HL查询按如下步骤进
获取 Hibernate Session对象。
②编写HQL语句。
③3)以HQL语句作为参数,调用 Session的 createQuery方法创建查询对象
④如果HQL语句包含参数,则调用Query的 setXxx()方法为参数赋值。
⑤5调用 Query对象的list()或 uniqueResult()方法返回查询结果列表(持久化实体集)
下面的查询示例示范了HQL查询的基本用法。
//以HQL语句创建Query对象
List pl =session.createQuery("select distinct p from Person p" + "join p.myEvents where title= :eventTitle")
//执行setString()方法为HQL语句的参数赋值
.setString("eventTitle", "表态")
//Query()调用list()方法获取查询的全部实例
.list();
List pl1 = session.createQuery("select distinct p from Person p"
+ "inner join p.myEvents event where event.happenDate"
+ "between :firstDate and : endDate")
//设置参数
.setDate("firstDate", start)
.setDate("endDate", new Date())
//返回结果
.list();
List pl2 = session.createQuery("select distinct p.id, p.name, p.age"
+ "from Person p join p.myEvents")
//Query调用list()方法访问查询得到的全部属性
.list();
Query还包含如下两个方法
setFistResult(int firstResult):设置返回的结果集从第几条记录开始
setMaxResult(int maxResult):设置本次查询返回的结果数目
这两个方法用于对HQL查询实现分页查询
关联和连接:
HQL支持两种关联连接形式:隐式与显式
HQL查询到的from字句
隐式连接形式不使用join关键字,使用英文点号来隐式连接关联实体,而Hibernate底层将自动进行关联查询。
//使用Implict查询Person持久化实体 p.myEvent属性是一个持久化实体
From Person p where p.myEvent.title > :title
//使用显式连接
From Person p inner join p.myEvent event where event.happenDate < :endDate
使用显式连接时可以为相关联的实体,及关联集合中的全部元素指定一个别名
连接的集中方式
1>inner join(内连接),可简写成join
2>left outer join(左外连接),可简写成left join
3>right outer join (右外连接),可简写成right join
4> full join(全连接)
使用with 提供额外的连接
//使用显式连接
from Person p
inner join p.myEvent event wiih p.id > event.id where event.happenDate < :endDate
如果myEvents是个集合
返回一个集合[集合元素是Person实体和MyEvent实体组成的数组]
Select p from Person p inner join p.myEvents e where e.title = :eventTitle
返回Person实体组成的集合,且元素不重复
Select distinct p from Person p inner join p.myEvents e where e.title = :eventTitle
如果Person对象中的属性是集合属性,则加载实体时,系统采用默认懒加载方法
避免懒加载的方法如下:
- 在Hibernate持久化注解中指定fetch=FetchType.EAGER来关闭延迟加载
- 使用join fetch 例如:from Person as p join fetch p.scores
使用fetch关键字应注意以下几点
1> fetch不应该与 setMaxResults()或 setFirstResult()共用。因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,即无法预先知道精确的行数
2> fetch不能与独立的with条件一起使用。
3>如果在一次查询中 fetch多个集合,可以查询返回笛卡儿积,因此请多加注意
4> full join fetch与 right join fetch是没有任何意义的
如果在持久化注解中映射属性时通过指定 fetch= FetchType.LAZY启用了延迟加载(这种延迟加载是通过字节码增强来实现的),然后程序里又希望预加载那些原本应延迟加载的属性,则可以通过fetch all properties来强制 Hibernate立即抓取这些属性。
from Document fetch all properties order by name
from Document doc fetch all properties where lower(doc.name) like ‘%cats%’
HQL查询的select字句
Select p.name from Person as p
//还可以选择组件属性包含的属性
select p.name.firstName from Person as p
//select选出的多项存入List对象中
select new list(p.name,p.address) from Person as p
//将选择出的对象封装成对象[前提是ClassTest支持这些属性的构造器]
select new ClassTest(p.name, p.address) from Person as p
//给选中的表达式命名别名
select p.name as personName from Person as p
select new map(p.name, as personName) from Person as p //返回一个集合
HQL查询的聚集函数
1>avg
2>count:
3>max
4>min
5>sum:
select count(*) from Person
select max(p.age) from Person as p
selct支持字符串连接符、算数运算符,以及SQL函数
select p.name || “” || p.address from Person as p
多态查询
From后跟类名、或接口,则查询该持久化类,及子类或则实现该接口的所有实例
Where查询
只要不出现集合HQL语句可使用点号来隐式连接多个数据表
from Foo foo where foo.bar.customer.address.city like “Guangzhou%”
生成一个四表连接的查询语句【=运算符既可以比较属性,又可以比较实例】
From Cat cat, Cat rival where cat.mate = rival.mate select cat, mate from Cat cat, Cat mate where cat.mate = mate
Id作为组件类型的标识符使用
from Person as person where person.id.country = ‘au’
and person.id.medicareNumber = 1234
from Account as account where account.owner.id.country = ‘AU’
and account.owner.id.medicareNumbber = 123456
嵌入where字句的java类名,将作为辨别者值
//执行多台查询时,默认会选出Cat及其所有子类的实例
From Cat cat where cat.class = DomesticCat
另外当where子句中的运算符只支持基本类型或字符串时,where子句中的属性表达式必须以基本类型或字符串结尾
//例如 Account.Person,而person.Name组件 时where子句示例
from Account as a where a.person.name.firstName like “dd%”
Where子句支持的表达式表达式
- 数学运算符:+ - * /
- 二进制比较运算符: = >= <= <> != like
- 逻辑运算符:and、or、not
- in, not in, between, is null, is not null, is empty, is not empty、 membet of and not member of
- 简单的case,case…when,..then..else....end和case、 case when…then,..then..end等
- 字符串连接符:如 value1 || value2,或使用字符串连接函数concat(value1,value2)
- 时间操作函数: current_date()、 current_time(), current_timestamp()、second()、minute()、hour()、day()、month()、year()等
- 还支持EJB-QL3.0所支持的函数或操作: substring().trim(). lower(),upper()、length()、locate()、abs()、sqrt()、bit_length()、coalesce()和nullif()
- 支持数据库的类型转换函数,如cast(…as…),第二个参数是 Hibemate的类数名,或者extract(…from…),前提是底层数据库支持 ANSI cast()和extract().
- 如果底层数据库支持单行函数:sign(), trunc()、 rtrim(), sin().则HOL通句也完全复持,
- HQL语句支持使用命名参数作为占位符,方法是在参数名前英交加冒号(:)等:也支持使用英文问号+数字的形式(?N)的参数作为占位,
- 当然,也可以在 where子句中使用SQL常量, ,还可以在HQL语句中使用Java中的 public static final类型的常量,例如 Color.RED
- 除此之外, where子句还支持如下的特殊关键字用法
- HOL index()函数,作用于join的有序集合的别名
- HQL函最,把集合作为参数:size()、 minelement(),maxelement(), minindex(). maxindex()
有特别的 elements()和 indices()函数,可以用数量词加以限定,如same、all、exists、any、in
16.in与 between…..and
from DomesticCat cat where cat.name between ‘ A and‘B‘
from DomesticCat cat where cat. name in (‘Foo,‘Bar,‘Bar‘)
from DomesticCat cat where cat,name not between ‘A’ and‘B’
from DomesticCat cat where cat. name not in (‘Foo‘,‘Bar’,’Baz’)
17.子句 is null与 is not nul可以被用来测试空值。
from DomesticCat cat where ca.name is null
from person as p where p.address is not null
18.如果在 Hibernate配置文件中进行如下声明
<property name="hibernate.query,.substitutions">true I, false 0</property>
上面的声明表明:HQL转换SOL语句时,将使用字符1和0来代替关键字true和false,然后就可以在表达式中使用1和0来构建布尔表达式了。
from Cat cat where cat,.alive= 0
19.size关键字用于返回一个集合的大小,例如:
from Cat cat where cat.kittens.size >0; from Cat cat where size(cat..kittens) > 0
20.对于有序集合,还可使用 minindex()与 maxindex()函数代表最小与最大的索引序数。
可以使用 minelement()与 maxelemet()函数代表集合中最小与最大的元素,例如
from Calendar cal where maxelement(cal.holidays) > current_date;
from Order where maxindex(order.items) > 100;
from Order where where minelement(order.items)> 100;
21.还有特别有用的 elements()和 indices()函数,用于返回指定集合的所有元素和所有索引值。还可以any、some、all、exists、in等SQL函数操作集合里的元素,例如
//操作能合元素
Select mother from Cat an mother, Cat as kit where kit in elements(foo.kittens)
//p的name属性等于集合中某个元素的name属性
Select p from NameList list, Person p where p.name = some elements(list.names)
//操作集合元素
from Cat cat where exists elements(cat.kittens)
from Player p where 3 > all elements(p.scores)
from Show show where ‘fizard’ in indices(show.acts)
22.值得指出的是,这些结构变量: size elements, indices. minindex; maxindex, inclement.,max
在where子句中,有序集合(数组、List集合、Map对象)的元素可以通过们运算符访问,例
等,只能在 where子句中使用
//item是有序集合性
from Order order where order items [0].id-12347
//holidays是Map集合属性, holidays[‘national’]代表key为 nationa1的元素
Select person from Person person, Caledar calendar where calendar.holidays[‘national day’] = person.birthDay and person.nationlity.calendar = calendar;
//下同时使用List集合和Map集合属性
select item from Item item, order order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11;
select item from Item item, Order order where order items[ maxindex(order.items) ] = item and order.id = 11;
23.在[]中的表达式甚至可以是一个算术表达式。例如
Select item form Item item, Order order where order.items[size(order.items) - 1] = item;
order by子句
查询返回的集合可以根据类或组件属性的任何属性进行排序。例如:
from Person as p order by p.name, p.age
还可使用asc或desc关键字指定升序或降序的排序规则。例如:
from Person as p order by p.name asc, p.age desc
如果没有指定排序规则,则默认采用升序规则。
group by子句
//返回聚集值的查询可以对持久化类或组件属性的属性进行分组,分组使用 group by子句,
select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color
类似于SQL的规则,出现在select后的属性,要么出现在聚集函数中,要么出现在 group by的属性列表中,看下面的示例:
//select后出现的id处于group by 之后,而name属性则出现在聚集函数中
select foo.id, avg(name), max(name) from Foo foo join foo.names name group by foo.id
//having子句用于对分组进行过滤,[having字句只能在group by字句时才可以使用]
select cut.color, sum(cat.weight), count (cat) from Cat cat group by cat. color having cat.color in (eg.Color.TABBY,eg.Color.BLACK)
/****如果底层数据库支持having字句和group子句中使用普通函数或聚集函数,则HQL的having与order by字句也可以使用普通函数和聚集函数
order by 和 group by子句不能包含算术表达式
*********/
select cat from Cat cat join cat.kittens kitten group by cat having avg(ktten.weight) > 100
order by count (kitten) asc,sum(kitten.weight) desc
期待完善中、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
原文地址:https://www.cnblogs.com/sundaysjava/p/10347431.html