java之SQL语句

批量更新

//查询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对象中的属性是集合属性,则加载实体时,系统采用默认懒加载方法

避免懒加载的方法如下:

  1. 在Hibernate持久化注解中指定fetch=FetchType.EAGER来关闭延迟加载
  2. 使用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子句支持的表达式表达式

  1. 数学运算符:+ - * /
  2. 二进制比较运算符: = >= <= <> != like
  3. 逻辑运算符:and、or、not
  4. in, not in, between, is null, is not null, is empty, is not empty、 membet of and not member of
  5. 简单的case,case…when,..then..else....end和case、 case when…then,..then..end等
  6. 字符串连接符:如 value1  || value2,或使用字符串连接函数concat(value1,value2)
  7. 时间操作函数: current_date()、 current_time(), current_timestamp()、second()、minute()、hour()、day()、month()、year()等
  8. 还支持EJB-QL3.0所支持的函数或操作: substring().trim(). lower(),upper()、length()、locate()、abs()、sqrt()、bit_length()、coalesce()和nullif()
  9. 支持数据库的类型转换函数,如cast(…as…),第二个参数是 Hibemate的类数名,或者extract(…from…),前提是底层数据库支持 ANSI cast()和extract().
  10. 如果底层数据库支持单行函数:sign(), trunc()、 rtrim(), sin().则HOL通句也完全复持,
  11. HQL语句支持使用命名参数作为占位符,方法是在参数名前英交加冒号(:)等:也支持使用英文问号+数字的形式(?N)的参数作为占位,
  12. 当然,也可以在 where子句中使用SQL常量, ,还可以在HQL语句中使用Java中的 public static final类型的常量,例如 Color.RED
  13. 除此之外, where子句还支持如下的特殊关键字用法
  14. HOL index()函数,作用于join的有序集合的别名
  15. 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

时间: 2024-08-30 06:26:03

java之SQL语句的相关文章

JAVA中用 SQL语句操作小结

1.添加记录(INSERT) 使用SQL语句的INSERT命令可以向数据库中插入记录,INSERT命令的基本形式为: INSERT INTO 表名 [(字段名1,字段名2-)] VALUES (值1,值2,-) 若在输入记录时,每个字段均有内容,可省略表名后的字段名. 该SQL语句用于将值1,值2--值n分别赋给字段1,字段2,--字段n, 并为表增加一条记录.在使用该命令时要注意下面两个规则: 插入的值必须和列一一对应. 插入值的数据类型必须和对应列的数据类型相一致. 比如使用下面这个命令就可

java中sql语句能不能加分号的问题?

一.原因  在程序运行中,当执行sql后总是报无效字符错误:但是把程序放在pl/sql中执行又没有错误.让我很纳闷!于是我开始查找资料,然后我终于发现了问题. 二.问题剖析 原来在程序中:如果你在程序里面写sql,就不要加分号,在程序里面编译器会把分号当做sql本身的一部分,所以会报错. 如果是在查询工具里面(比如plsql),这个时候可以加上分号,在工具里面已经做过预处理,分号是个分隔符,看到分号就标志着本条sql语句结束了: 因此java中sql语句能不能加分号.

java实现sql语句批处理

Statement实现批处理: 优点:能够处理多种不同结构的sql语句 缺点:不能预处理,执行效率较差.对于参数不同的同一条sql语句需要多次调用addBatch() package com.itheima.batch; import java.sql.Connection; import java.sql.Statement; import org.junit.Test; import com.itheima.util.DBUtil; public class StatementBatch {

Java中sql语句的引号问题

1..sql语句 在数据库中,当我们查询语句时,会使用类似的语句: Select * from userinfo where userid='1' or 1; Select * from userinfo where username="jfl"; 2.问题 Java通常需要连接数据库(Mysql,Oracle等)进行操作,在查询语句块中经常会用到where子句,在这里我们需要注意引号问题. 3.实例 在java中,我们需要将where子句的关键词变成变量,例如userid,usern

关于Java中SQL语句的拼接规则

实现目标语句是这个注意,这里的java变量是idd int idd; String sql = "SELECT id, piUrl FROM picinfos WHERE id BETWEEN '" + idd + "' AND 10" ; java中的字符串只能双引号,如果字符串中需要拼接变量,该变量用单引号括起来,然后加两个双引号再加两个加号,中间就是变量. 拼接步骤 写出SQL具体语句(无变量都是具体值的),比如上面的sql //查询picinfos表中id为

[转帖]关于Java中SQL语句的拼接规则

自学demo 的时候遇到的问题 结果应该是 '"+e.getName()+"' 注意 一共有三组标点符号 (除去 方法函数后面的括号) 实现目标语句是这个注意,这里的java变量是idd int idd; String sql = "SELECT id, piUrl FROM picinfos WHERE id BETWEEN '" + idd + "' AND 10" ; java中的字符串只能双引号,如果字符串中需要拼接变量,该变量用单引号括

在线数据库表(sql语句)生成java实体类工具

相信每个做java开发的读者,都接触过SQL建表语句,尤其是在项目开发初期,因为数据库是项目的基石. 在现代项目开发中,出现了许多ORM框架,通过简单的实体映射,即可实现与数据库的交互,然而我们最初设计的一定是数据库表结构,而不是实体类.实体类仅仅是对底层数据结构的有损压缩,它仅仅是数据载体,不具备数据归档能力. 因此,很多时候,我们需要将原始的SQL建表语句转换成java实体类,这项工作看似简单,但若人工完成,工作量也是相当可观的,而且难免会出现差错. 到目前为止,笔者还没有发现比较靠谱的此类

Java注解项目实战即模拟Hibenernate生成sql语句

整理了近期学习java注解的部分代码 ,借助java注解模拟Hibenernate ORM模型建立对象与sql语句的映射 Table 注解的创建 package com.imooc.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.

java用字符串拼接SQL语句的特殊字符转义问题

在实际的项目开发中,往往会根据用户在界面的文本框中输入的信息,去数据库中做模糊查询.如果使用的是原始的JDBC和SQL,往往需要对用户的输入进行转义,避免生成的sql语法错误,或者防止SQL注入.比如对输入的%和_和',就需要进行转义,因为这3个字符是SQL的特殊字符,如果不处理会导致sql出错或者是查询数据不正确. 假如有这样1个查询请求,模糊查询标题中包含a%b_cc'd的记录,正确的sql应该是下面这样的: select * from t_sch_work_info t where t.t