学习目标
(如果没有了解可以去我主页看看 第一至二章的内容来学习)我们已经对JPA的基本概念、对象/关系映射注解,仅仅通过少量配置实现单表大部分CRUD操作,进行分页,自定义QL语句,自定义动态查询完成复杂查询,本章我们继续学习JPA高级应用,掌握多表联接查询,以及通过关联映射完成延迟加载、级联操作等。
本章我们除了JPA的多表联接查询、关联映射外,还会在后半部分快速完成Spring Boot 和MyBatis的集成开发,包括基于XML配置和注解配置两种方式。
3.1 JPA多表查询
多表查询在 Spring Data JPA 中有两种实现方式,第一种是创建一个结果集的接口来接收多表接查询后的结果,第二种是利用JPA的关联映射来实现。
3.1.1 数据库表及关系
我们通常不直接编写代码来定义数据库表及其关系,因为这些操作更多是在数据库层面(如使用SQL语句)或通过ORM(对象关系映射)框架来完成的。不过,我可以向你展示如何使用Java代码结合JDBC(Java Database Connectivity)来执行SQL语句,这些SQL语句可以创建表、定义关系等。
使用JDBC创建表和关系
以下是一个简单的Java示例,展示了如何使用JDBC连接数据库并执行SQL语句来创建表及定义表之间的关系。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class DatabaseExample {
public static void main(String[] args) {
// 数据库连接信息(请根据你的数据库进行更改)
String url = "jdbc:mysql://localhost:3306/yourdatabase";
String user = "username";
String password = "password";
try {
// 加载并注册JDBC驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 建立连接
Connection conn = DriverManager.getConnection(url, user, password);
// 创建Statement对象来执行SQL语句
Statement stmt = conn.createStatement();
// 创建表
String sqlCreateTable1 = "CREATE TABLE IF NOT EXISTS Student (" +
"id INT AUTO_INCREMENT PRIMARY KEY, " +
"name VARCHAR(255) NOT NULL)";
String sqlCreateTable2 = "CREATE TABLE IF NOT EXISTS Course (" +
"id INT AUTO_INCREMENT PRIMARY KEY, " +
"name VARCHAR(255) NOT NULL)";
// 创建关系表
String sqlCreateRelationTable = "CREATE TABLE IF NOT EXISTS Enrollment (" +
"student_id INT, " +
"course_id INT, " +
"FOREIGN KEY (student_id) REFERENCES Student(id), " +
"FOREIGN KEY (course_id) REFERENCES Course(id), " +
"PRIMARY KEY (student_id, course_id))";
// 执行SQL语句
stmt.executeUpdate(sqlCreateTable1);
stmt.executeUpdate(sqlCreateTable2);
stmt.executeUpdate(sqlCreateRelationTable);
// 关闭资源
stmt.close();
conn.close();
System.out.println("Tables and relations created successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用JPA或Hibernate
在Java中,更常见的方式是使用JPA(Java Persistence API)或Hibernate这样的ORM框架来管理数据库表及关系。这些框架允许你通过定义Java类(实体)及其关系来映射到数据库表及表之间的关系。
Hibernate很多公司都会用MyBatis代替它,Hibernate是一个对象关系映射(ORM)框架,它允许Java开发者以面向对象的方式与数据库进行交互,减少了直接编写SQL的需求。Hibernate的优点包括简化数据库操作、支持多种数据库、高性能的事务管理、高度灵活的查询语言HQL(Hibernate Query Language),以及良好的数据库无关性。此外,Hibernate还提供了缓存和延迟加载等技术,有效地提高了数据访问的性能,并保证了数据的一致性。
3.1.2 多表联接查询
在Spring Data JPA中,你可以通过@Query注解在Repository接口中定义自定义的JPQL(Java Persistence Query Language)查询,或者使用@EntityGraph来优化加载关联数据。但是,直接在JPQL中编写多表联接查询是更常见的做法。
假设你有两个实体类Student和Course,以及一个联接表Enrollment(虽然通常联接逻辑是通过实体关系来处理的,而不是物理的联接表)。
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// 省略getter和setter
@OneToMany(mappedBy = "student")
private List<Enrollment> enrollments;
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY