1.HQL语法
select ... from ... 与SQL不同的是select 后跟的是实体对象,也可以是实体对象的属性或者其他值(相当于选取全部列,或者某些列)
Query query =session.createQuery("select c from Cat as c"); 可以简写成 “from Cat”
注意HQL大小写不敏感,但涉及Java类名,package名,属性名时,大小写敏感 故只能是“Cat” 不是“cat”。
若是有多个名为Cat的实体类,应当在Cat前加上包名。
2.返回类型
1)查询总数
Query q = session.createQuery("from Joke");
Number number = (Number) q.uniqueResult();
int totalSize = number.intValue();
2)返回集合类型
List<Joke> jokes = (List<Joke>)q.list();
List<String>content=session.createQuery("select j.content from Joke j");
List<String[]>contents=session.createQuery("select j.content , j.name from Joke j");
3)返回 Object[ ] 数组
List<Object[] >list=session.createQuery("select j, j.name from Joke j");
这样便可以得到不同类型的返回值。
3.条件查询
where字句语法 , 可以使用实体类的属性,或者属性的属性。尽量使用setparameter方法传递参数,这样第一次执行SQL时,数据库会对该SQL进行编译,供下次查询使用,对于不同参数的相同查询,数据库将直接使用编译后的SQL,提高效率。
session.createQuery("select j from Joke j where j.createDate < :createDate").setParameter("createDate",new Date());
4.支持的运算符
字符串连接 ...||... 或者 concat(... , ... )
List<String>list=session.createQuery("select '笑话的名字为 ' || j.name || '内容是' || j.content from Joke j where j.name !=null ").list();
trim() ,lower() ,length(), abs() 这些是JPA定义的操作
SQL操作符: in , not in , beween , is null , is not null
List<Joke>list =session.createQuery("select j from Joke j where lower(trim(j.name)) in ('naruto','herry portter') ").list();
List<Joke>list=session.createQuery("from Cat c where size(c.events) >5").list();
5.SQL级联查询
1)跨表查询
List<Event>list = session.createQuery("select e from Event e where e.cat.name='Tom' ").list();
一共需要查询两个表,Event 与 Cat 表
2)多表连接查询
①交叉连接(cross join), 无需任何连接条件
select s.* , teacher_name from student_table s cross join teacher_table t;
from 之后只有一个表名,这里就是广义笛卡尔积。
②自然连接(natural join), 自然连接会以两个表中的同名列作为连接条件,若没有同名列,则与交叉连接完全一样。因为这也没有条件。
select s.* , teacher_name from student_table s natural join teacher_table t ;
select * from student;
+----+------+-------------+
| id | name | javateacher |
+----+------+-------------+
| 1 | 张三 | 202 |
| 2 | 李四 | 201 |
| 3 | 王五 | 201 |
+----+------+-------------+
select * from teacher;
+------------+--------------+----+
| teacher_id | teacher_name | id |
+------------+--------------+----+
| 201 | 马春燕 | 1 |
| 202 | 唐小春 | 2 |
| 203 | 刘志强 | 3 |
+------------+--------------+----+
select s.*,teacher_name from student s natural join teacher t;
+----+------+-------------+--------------+
| id | name | javateacher | teacher_name |
+----+------+-------------+--------------+
| 1 | 张三 | 202 | 马春燕 |
| 2 | 李四 | 201 | 唐小春 |
| 3 | 王五 | 201 | 刘志强 |
+----+------+-------------+--------------+
③字句连接(using),using字句可以指定一列或多列,用于显式指定两个表中的同名列作为连接条件,假设两个表中有超过一列的同名列,若使用natural join,则会把所有的同名列作为连接条件。使用using子句,则可以显式指定用哪些列名作为连接条件。
select s.* , teacher_name from student_table s join teacher_table t using(teacher_id);
使用 join 连接另外一张表,这里要求两张表都含有 teacher_id 字段。
select s.*,teacher_name from student s join teacher t using (id);
+----+------+-------------+--------------+
| id | name | javateacher | teacher_name |
+----+------+-------------+--------------+
| 1 | 张三 | 202 | 马春燕 |
| 2 | 李四 | 201 | 唐小春 |
| 3 | 王五 | 201 | 刘志强 |
+----+------+-------------+--------------+
④on 子句连接,这是最常用的连接方式,每个on子句指定一个连接条件,表明若有N个表连接,则需要N-1个join...on...对。
select s.* , teacher_name from student_table s join teacher_table t on s.javateacher=t.teacher_id;
注:使用on连接不一定非要用等值条件,也可以是非等值条件。
select s.*,teacher_name from student s join teacher t on s.javateacher=t.teacher_id;
+----+------+-------------+--------------+
| id | name | javateacher | teacher_name |
+----+------+-------------+--------------+
| 2 | 李四 | 201 | 马春燕 |
| 3 | 王五 | 201 | 马春燕 |
| 1 | 张三 | 202 | 唐小春 |
+----+------+-------------+--------------+
⑤左右全外连接,分别使用left [outer] join , right [outer] join 和 full [outer] join , 这三种外连接一样通过on 子句来指定。
右外连接:select s.* ,teacher_name from student_table s right join teacher_table t on s.java_teacher <t.teacher_id;
select s.*,teacher_name from student s right join teacher t on s.javateacher<t.teacher_id;
+------+------+-------------+--------------+
| id | name | javateacher | teacher_name |
+------+------+-------------+--------------+
| NULL | NULL | NULL | 马春燕 |
| 2 | 李四 | 201 | 唐小春 |
| 3 | 王五 | 201 | 唐小春 |
| 1 | 张三 | 202 | 刘志强 |
| 2 | 李四 | 201 | 刘志强 |
| 3 | 王五 | 201 | 刘志强 |
+------+------+-------------+--------------+
左外连接:select s.* ,teacher_name from student_table s left join teacher_table t on s.java_teacher <t.teacher_id;
select s.*,teacher_name from student s left join teacher t on s.javateacher<t.teacher_id;
+----+------+-------------+--------------+
| id | name | javateacher | teacher_name |
+----+------+-------------+--------------+
| 1 | 张三 | 202 | 刘志强 |
| 2 | 李四 | 201 | 唐小春 |
| 2 | 李四 | 201 | 刘志强 |
| 3 | 王五 | 201 | 唐小春 |
| 3 | 王五 | 201 | 刘志强 |
+----+------+-------------+--------------+
左表:即指from后的表,不是join后的表,右表与此相反。
左外连接会把左边的表每条显示,右表每有一条记录对应(指符合on条件)则显示一条记录,若无右表对应,只显示一条记录,且右表对应空格填写null。
右外连接会把右边的表每条显示,左表每有一条记录对应则显示一条记录,若无左表对应,则只显示一条记录,且左表对应空格填写null。
全外连接:select s.* ,teacher_name from student_table s full join teacher_table t on s.java_teacher = t.teacher_id;
全外连接的连接条件是等值连接,把所有公共字段相同的部分显示出来。
select name,teacher.teacher_name from student full join teacher on javateacher=teacher.teacher_id;
+------+--------------+
| name | teacher_name |
+------+--------------+
| 李四 | 马春燕 |
| 王五 | 马春燕 |
| 张三 | 唐小春 |
+------+--------------+
inner join 是左表与右表数据都不为空时,才会把数据显示。
select * from teacher inner join student on teacher.teacher_id =student.javateacher;
+------------+--------------+----+----+------+-------------+
| teacher_id | teacher_name | id | id | name | javateacher |
+------------+--------------+----+----+------+-------------+
| 202 | 唐小春 | 2 | 1 | 张三 | 202 |
| 201 | 马春燕 | 1 | 2 | 李四 | 201 |
| 201 | 马春燕 | 1 | 3 | 王五 | 201 |
+------------+--------------+----+----+------+-------------+