文章目錄
  1. 1. 前言
  2. 2. SQL的四种连接
    1. 2.1. 数据表
    2. 2.2. inner join
      1. 2.2.1. for example
    3. 2.3. left join
      1. 2.3.1. for example
    4. 2.4. right join
      1. 2.4.1. for example
    5. 2.5. cross join
      1. 2.5.1. for example
  3. 3. hql实现
    1. 3.1. Entity
    2. 3.2. left join
  4. 4. 总结
  5. 5. 参考文章

我们有的时候需要多表联合查询,当然在mysql中我们通过建视图来加快我们查询的速度,也可以直接写sql语句来实现。但是在java中,我们也可以用hql面向对象的语言来进行查询。一起来看一下hql如何用。

前言

如果你想了解mysqlinner join, left outer join, right outer join, cross join话,我建议你先用navicat一款非常优秀的跨平台数据库可视化软件建一下视图,自己看一眼建完之后生成的sql语句,我刚开始学和写hql语句的时候我都会看一下他们生成的sql语句是什么样的,然后给自己一点儿思路。

框架:Spring
环境:Ubuntu, IDEA

SQL的四种连接

数据表

user表

id name password
1 aaa 123
2 bbb 456
3 ccc 789

teacher表

id name professor
1 lisi aaa
2 zhangsan ddd

inner join

典型的联接运算,使用像 = 或 <> 之类的比较运算符
假如运算是”=”,然后我们就可以找到两张表中列的值相同的记录。

for example

我们可以这样写sql语句:

1
select user.*, teacher.* from user inner join teacher on user.name=teacher.professor

然后我们就可以看到找到了username列和teacher表中professor列的值相同的记录:

name id password id name professor
aaa 1 123 1 lisi aaa

left join

左向外连接的结果集包括LEFT OUTER子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。

for example

我们可以这样写sql语句:

1
select user.*, teacher.* from user left join teacher on user.name=teacher.professor

name id password id name professor
aaa 1 123 1 lisi aaa
bbb 2 456 NULL NULL NULL
ccc 3 789 NULL NULL NULL

right join

右向外连接是左向外连接的反向连接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。

for example

我们可以这样写sql语句:

1
select user.*, teacher.* from user right join teacher on user.name=teacher.professor

name id password id name professor
aaa 1 123 1 lisi aaa
NULL NULL NULL 2 zhangsan ddd

cross join

交叉连接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉连接也称作笛卡尔积。

for example

我们可以这样写sql语句:

1
select user.*, teacher.* from user cross join teacher

name id password id name professor
aaa 1 123 1 lisi aaa
aaa 1 123 2 zhangsan ddd
bbb 2 456 1 lisi aaa
bbb 2 456 2 zhangsan ddd
ccc 3 789 1 lisi aaa
ccc 3 789 2 zhangsan ddd

hql实现

如果你没有写任何hql的经历,那么请自己在参考文章的连接中自己学习哦!

Entity

Employee.java

1
2
3
4
5
6
7
8
@Entity
public class Employee {
@Id
private int empId;
@Column(name="emp_name")
private String empName;
// Setters and Getters
}

Company.java

1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Company {
@Id
private int compId;
@Column(name="comp_name")
private String compName;
@OneToMany
@JoinColumn(name="comp_id")
private Set<Employee> employees;
// Setters and Getters
}

我们在数据库中准备如下数据
Company

id comp_name
1 ABCD
2 EFGH

Employee

id emp_name comp_id
1 Mohan 2
2 Sohan 1
3 Ramesh 2

left join

Spring中,我们可以在@Query中写hql语句查询,也可以写原生的sql语句查询。下面我们就用hql来完成left join

CompanyRepository.java

1
2
3
4
public interface CompanyRepository extends CrudRepository<Company, Long> {
@Query("select comp, emp from Company as comp left outer join comp.employees as emp);
List<?> getAllEmployeeCompany();
}

然后我们打印出来,就会发现下面的数据:

1
2
3
4
Hibernate: select company0_.comp_id as comp_id1_0_0_, employees1_.emp_id as emp_id1_1_1_, company0_.comp_name as comp_nam2_0_0_, employees1_.emp_name as emp_name2_1_1_ from company company0_ left outer join employee employees1_ on company0_.comp_id=employees1_.comp_id
CompId:1, CompName:ABCD, EmpId:2, EmpName:Sohan
CompId:2, CompName:EFGH, EmpId:1, EmpName:Mohan
CompId:2, CompName:EFGH, EmpId:3, EmpName:Ramesh

总结

第一次用java,第一次用hql,第一次直接写多表联合查询。刚开始的时候无从下手。刚开始看Spring的官方文档一头雾水,后来经潘老师一说,我开始用navicat,从建立视图,然后看生成的sql语句。然后找博客看sql的内连接,外连接。最后学习hql,然后在回过头来看Spring的文档实现简单的查询。然后在实践中一点一点理解。

参考文章

5.3.4. Using @Query Spring docs
Hibernate HQL Associations and inner join, left outer join, right outer join, cross join Example
JPA: Query that returns multiple entities stackoverflow
第 15 章 HQL: Hibernate 查询语言
SQL 左外连接,右外连接,全连接,内连接

文章目錄
  1. 1. 前言
  2. 2. SQL的四种连接
    1. 2.1. 数据表
    2. 2.2. inner join
      1. 2.2.1. for example
    3. 2.3. left join
      1. 2.3.1. for example
    4. 2.4. right join
      1. 2.4.1. for example
    5. 2.5. cross join
      1. 2.5.1. for example
  3. 3. hql实现
    1. 3.1. Entity
    2. 3.2. left join
  4. 4. 总结
  5. 5. 参考文章