hibernate 中left join 与left join fetch ,right join与right join fetch 等的区别

本文探讨了在懒加载模式下进行左连接查询时的注意事项,特别是如何避免查询结果重复的问题,并通过具体示例说明了正确使用fetch关键字的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

外键引用的值所对应的边相对于该表为主表

left join 与left join fetch

主表查询

当lazy=true时 hql关联查询该实体类的子表(对应子

实体)时必须使用fetch关键字,并且在前要加select distinct语句否则 查出来的条数会重复

 

 例如lazy=true情况下person主表 member子表pid关联查询所有person记录时,子表中有两条pid=8的member记录

 执行hql   from Person person right join fetch person.members(其中members为主表对应pojo或实体类的member集合)

 就会查询出两条person记录

### 在 Java 中实现 SQL 左连接 (LEFT JOIN) 在 Java 应用程序中执行 SQL 的 `LEFT JOIN` 查询通常涉及以下几个方面: #### 使用 JDBC 执行 LEFT JOIN JDBC(Java Database Connectivity)允许开发者通过 Java 代码来访问数据库并执行 SQL 查询。对于执行带有 `LEFT JOIN` 的查询,可以按照如下方式进行。 ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class LeftJoinExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/testdb"; String user = "root"; String password = ""; try (Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT e.id, e.name, d.department_name FROM employees e LEFT JOIN departments d ON e.department_id = d.id")) { while (rs.next()) { System.out.println(rs.getInt("id") + "\t" + rs.getString("name") + "\t" + ((rs.getString("department_name") != null) ? rs.getString("department_name") : "No Department")); } } catch (Exception e) { e.printStackTrace(); } } } ``` 这段代码展示了如何建立 MySQL 数据库的连接,并执行了一个 `LEFT JOIN` 来获取员工及其所属部门的信息。当某个员工不属于任何已知部门时,在结果集中该员工对应的部分将会显示为 `NULL` 或者自定义的消息[^1]。 #### 结合 ORM 框架简化操作 除了直接使用 JDBC 外,还可以利用像 Hibernate 这样的对象关系映射(ORM)框架来进行更简洁的操作。这里给出一个基于 JPA Spring Data 的例子,展示怎样在一个实体类之间设置一对多的关系,并通过 Repository 接口轻松完成 `LEFT JOIN` 查找。 ##### 实体类 Employee.java ```java @Entity @Table(name="employees") public class Employee { @Id private int id; private String name; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="department_id", nullable=true) private Department department; // Getters and Setters... } ``` ##### 实体类 Department.java ```java @Entity @Table(name="departments") public class Department { @Id private Integer id; private String departmentName; @OneToMany(mappedBy="department", fetch=FetchType.LAZY) private List<Employee> employees; // Getters and Setters... } ``` ##### DAO 层接口 EmployeesRepository.java ```java @Repository public interface EmployeesRepository extends JpaRepository<Employee, Long> {} // Using the repository to perform a left join query would be as simple as calling findAll() List<Employee> allEmployeesWithDepartments = employeeRepo.findAll(); for(Employee emp : allEmployeesWithDepartments){ System.out.println(emp.getName() + ": " + (emp.getDepartment()!=null?emp.getDepartment().getDepartmentName():"No Dept.")); } ``` 这种方式不仅减少了手动编写 SQL 的工作量,而且使得应用程序更加易于维护发展[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值