Spring Data JPA实现多表的关联查询

1、Spring Data JPA关系映射

对象关系映射(Object relational mapping)是指通过将对象状态映射到数据库列,来开发和维护对象和关系数据库之间的关系。它能够轻松处理(执行)各种数据库操作,如插入、更新、删除等。

关系映射的注解:

注解说明
@JoinColumn指定一个实体组织或实体集合。用在“多对一”和“一对多”的关联中。
@OneToOne定义表之间“一对一”的关系。
@OneToMany定义表之间“一对多”的关系。
@ManyToOne定义表之间“多对一”的关系。
@ManyToMany定义表之间“多对多”的关系。

下面将介绍如何使用Spring Data JPA处理多张数据库表之间的关联关系。

 

2、创建项目与配置信息

(1)创建SpringBoot项目

创建SpringBoot项目,并创建项目结构:dao(数据访问层)、entity(实体层)、test(测试层)。

(2)添加JPA和MySQL数据库的依赖

在pom.xml配置文件中,添加如下依赖:

<!-- Spring Data JPA -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
 
<!-- MySQL的JDBC数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.19</version>
</dependency>

(3)配置数据库连接信息

SpringBoot项目使用MySQL等关系型数据库,需要配置连接信息。

将默认的application.properties文件的后缀修改为“.yml”,即配置文件名称为:application.yml,并配置以下MySQL数据库的连接信息:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_admin?useSSL=false&amp
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database: MYSQL
    show-sql: true
    open-in-view: true
    properties:
      hibernate:
        enable_lazy_load_no_trans: true #使用延时加载时控制Session的生命周期
        dialect: org.hibernate.dialect.MySQL5Dialect
        ddl-auto: update

 

3、延时加载时控制Session的生命周期

在Spring Data JPA中在使用延时加载时,要控制Session的生命周期,否则会出现“could not initialize proxy [xxxxxx#1] - no Session”错误。可以在配置文件中配置以下代码来控制Session的生命周期:

application.properties配置文件:

spring.jpa.open-in-view=true
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

application.yml配置文件:

 

4、一对一查询

一对一外键关联的配置比较简单,以公民实体对象和身份证实体对象为例,在表tab_people(公民表)中添加一个字段“card_id”,作为该表的外键,同时需要保证该字段的唯一性,否则就不是一对一映射关系了,而是一对多映射关系。表tab_people和tab_idcard(身份证表)之间的关联关系如下图所示。

【示例】一对一关联,获取公民信息与身份证号码。

(1)在MySQL数据库创建tab_people表和tab_idcard表,并添加相关数据。

-- 判断数据表是否存在,存在则删除
DROP TABLE IF EXISTS tab_people;
DROP TABLE IF EXISTS tab_idcard;
 
-- 创建“身份证信息”数据表
CREATE TABLE IF NOT EXISTS tab_idcard
( 
	id INT AUTO_INCREMENT PRIMARY KEY COMMENT '身份证ID',
	idCard_code VARCHAR(45) COMMENT '身份证号码'
) COMMENT = '身份证信息表';
 
-- 创建“公民信息”数据表
CREATE TABLE IF NOT EXISTS tab_people
( 
	id INT AUTO_INCREMENT PRIMARY KEY COMMENT '公民ID',
	NAME VARCHAR(45) NOT NULL COMMENT '公民名称',
	sex VARCHAR(2) COMMENT '公民性别',
	age INT COMMENT '公民年龄',
	card_id INT UNIQUE COMMENT '身份证ID',
	-- 创建外键约束
	FOREIGN KEY fk_card_id (card_id)
	REFERENCES tab_idcard(id)
) COMMENT = '公民信息表';
 
-- 添加数据
INSERT INTO tab_idcard(idCard_code) VALUE('123456789');
INSERT INTO tab_people(NAME,sex,age,card_id) VALUES('pan_junbiao的博客','男',32,1); 

(2)创建名称为People.java公民信息的持久化类。

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;

/**
 * 公民信息的持久化类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tab_people")
public class People
{
    //公民ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    //公民名称
    @Column(name = "name")
    private String name;

    //公民性别
    @Column(name = "sex")
    private String sex;

    //公民年龄
    @Column(name = "age")
    private int age;

    //关联的身份证对象
    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name="card_id")
    private IDcard idcard;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getSex()
    {
        return sex;
    }

    public void setSex(String sex)
    {
        this.sex = sex;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public IDcard getIdcard()
    {
        return idcard;
    }

    public void setIdcard(IDcard idcard)
    {
        this.idcard = idcard;
    }
}

(3)创建名称为IDcard.java身份证信息的持久化类。

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;

/**
 * 身份证信息的持久化类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tab_idcard")
public class IDcard
{
    //身份证ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    //身份证号码
    @Column(name = "idcard_code")
    private String idCardCode;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getIdCardCode()
    {
        return idCardCode;
    }

    public void setIdCardCode(String idCardCode)
    {
        this.idCardCode = idCardCode;
    }
}

(4)创建名称为PeopleDao.java公民信息数据库访问接口,并继承JpaRepository接口。

package com.pjb.jpauserdemo.dao;

import com.pjb.jpauserdemo.entity.People;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * 公民信息数据库访问接口
 * @author pan_junbiao
 **/
@Repository
public interface PeopleDao extends JpaRepository<People,Integer>
{
}

(5) 测试:一对一新增(新增公民信息与关联的身份证信息)。

@Autowired
private PeopleDao peopleDao;

/**
 * 一对一新增:新增公民信息与关联的身份证信息
 * @author pan_junbiao
 */
@Test
public void addPeopleAndIdcard()
{
    //创建身份证信息
    IDcard idcard = new IDcard();
    idcard.setIdCardCode("123456789");

    //创建公民信息
    People people = new People();
    people.setName("pan_junbiao的博客");
    people.setSex("男");
    people.setAge(32);
    //将公民与身份证信息关联
    people.setIdcard(idcard);
    
    //执行新增操作
    peopleDao.save(people);

    //如果新增成功,则可以获取自增主键
    //否则新增失败,则抛出异常
    if(people.getId()>0)
    {
        System.out.println("新增公民信息成功!");
        System.out.println("公民ID:" + people.getId());
        System.out.println("公民名称:" + people.getName());
        System.out.println("身份证号码:" + idcard.getIdCardCode());
    }
}

执行结果:

(6)测试:一对一查询(获取公民信息与关联的身份证信息)。

@Autowired
private PeopleDao peopleDao;

/**
 * 一对一查询:获取公民信息与关联的身份证信息
 * @author pan_junbiao
 */
@Test
public void getPeopleAndIdcard()
{
    People people = peopleDao.findById(1).get();
    if (people != null)
    {
        System.out.println("---------------1、公民信息--------------------");
        System.out.println("公民编号:" + people.getId());
        System.out.println("公民名称:" + people.getName());
        System.out.println("公民性别:" + people.getSex());
        System.out.println("公民年龄:" + people.getAge());

        //获取关联的身份证信息信息
        System.out.println("---------------2、身份证信息信息---------------");
        IDcard idCard = people.getIdcard();
        if(idCard!=null)
        {
            System.out.println("身份证ID:" + idCard.getId());
            System.out.println("身份证号码:" + idCard.getIdCardCode());
        }
    }
}

执行结果:

 

5、一对多查询

在日常开发中一对多查询是常见的,也是业务中十分重要的部分。下面将以生产商对象(类Factory)与产品对象(类Product)为例,讲解JPA的一对多关联。类Factory与类Product的关联关系如下图。

【示例】建立生产商与产品对象对象的一对多关联,并利用映射关系查询完整的产品信息。

(1)在MySQL数据库创建tab_factory表和tab_product表,并添加相关数据。

-- 判断数据表是否存在,存在则删除
DROP TABLE IF EXISTS tab_factory;
DROP TABLE IF EXISTS tab_product;

-- 创建“生产商信息”数据表
CREATE TABLE IF NOT EXISTS tab_factory
( 
	factory_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '生产商ID',
	NAME VARCHAR(20) NOT NULL COMMENT '生产商名称'
) COMMENT = '生产商信息表';
 
-- 创建“产品信息”数据表
CREATE TABLE IF NOT EXISTS tab_product
( 
	id INT AUTO_INCREMENT PRIMARY KEY COMMENT '产品ID',
	NAME VARCHAR(20) NOT NULL COMMENT '产品名称',
	price DECIMAL(9,2) NOT NULL COMMENT '产品价格',
	factory_id INT COMMENT '生产商ID'
) COMMENT = '产品信息表';
 
-- 添加数据
INSERT INTO tab_factory(NAME) VALUES('华为公司');
INSERT INTO tab_product(NAME,price,factory_id) VALUES('华为手机',1299,1);
INSERT INTO tab_product(NAME,price,factory_id) VALUES('华为路由器',699,1);

(2)创建名称为Product.java产品信息的持久化类。

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;
import java.math.BigDecimal;

/**
 * 产品信息的持久化类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tab_product")
public class Product
{
    //产品ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    //产品名称
    @Column(name = "name")
    private String name;

    //产品价格
    @Column(name = "price")
    private BigDecimal price;

    //生产商信息
    @ManyToOne
    @JoinColumn(name = "factory_id")
    private Factory factory;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public BigDecimal getPrice()
    {
        return price;
    }

    public void setPrice(BigDecimal price)
    {
        this.price = price;
    }

    public Factory getFactory()
    {
        return factory;
    }

    public void setFactory(Factory factory)
    {
        this.factory = factory;
    }
}

(3)创建名称为Factory.java生产商信息的持久化类。

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;
import java.util.List;

/**
 * 生产商信息的持久化类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tab_factory")
public class Factory
{
    //生产商ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "factory_id")
    private int factoryId;

    //生产商名称
    @Column(name = "name")
    private String name;

    //产品列表
    @OneToMany
    @JoinColumn(name = "factory_id")
    private List<Product> productList;

    public int getFactoryId()
    {
        return factoryId;
    }

    public void setFactoryId(int factoryId)
    {
        this.factoryId = factoryId;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public List<Product> getProductList()
    {
        return productList;
    }

    public void setProductList(List<Product> productList)
    {
        this.productList = productList;
    }
}

(4)创建名称为FactoryDao.java生产商信息数据库访问接口,并继承JpaRepository接口。

package com.pjb.jpauserdemo.dao;

import com.pjb.jpauserdemo.entity.Factory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * 生产商信息数据库访问接口
 * @author pan_junbiao
 **/
@Repository
public interface FactoryDao extends JpaRepository<Factory,Integer>
{
}

(5)创建名称为ProductDao.java产品信息数据库访问接口,并继承JpaRepository接口。

package com.pjb.jpauserdemo.dao;

import com.pjb.jpauserdemo.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * 产品信息数据库访问接口
 * @author pan_junbiao
 **/
@Repository
public interface ProductDao extends JpaRepository<Product,Integer>
{
}

(6)测试:一对多查询(获取生产商信息与关联的产品列表)。

@Autowired
private FactoryDao factoryDao;

/**
 * 一对多查询:获取生产商信息与关联的产品列表
 * @author pan_junbiao
 */
@Test
public void getFactoryAndProductList()
{
    Factory factory = factoryDao.findById(1).get();
    if (factory != null)
    {
        System.out.println("---------------1、生产商信息信息--------------");
        System.out.println("生产商编号:" + factory.getFactoryId());
        System.out.println("生产商名称:" + factory.getName());

        //获取关联的产品信息信息
        System.out.println("---------------2、产品信息信息---------------");
        List<Product> productList = factory.getProductList();
        if(productList!=null && productList.size()>0)
        {
            for(Product product : productList)
            {
                System.out.println("产品编号:" + product.getId());
                System.out.println("产品名称:" + product.getName());
                System.out.println("产品价格:" + product.getPrice());
                System.out.println("-------------------");
            }
        }
    }
}

执行结果:

(7)测试:多对一查询(获取产品信息与关联的生产商信息)。

@Autowired
private ProductDao productDao;

/**
 * 多对一查询:获取产品信息与关联的生产商信息
 * @author pan_junbiao
 */
@Test
public void getProductAndFactory()
{
    List<Product> productList = productDao.findAll();
    if(productList!=null && productList.size()>0)
    {
        for (Product product : productList)
        {
            //获取产品信息
            System.out.println("产品编号:" + product.getId());
            System.out.println("产品名称:" + product.getName());
            System.out.println("产品价格:" + product.getPrice());

            //获取关联的生产商信息信息
            Factory factory = product.getFactory();
            System.out.println("生产商编号:" + factory.getFactoryId());
            System.out.println("生产商名称:" + factory.getName());
            System.out.println("-------------------");
        }
    }
}

执行结果:

 

6、多对多查询

多对多关联关系是比较特殊的一种关联关系,它与一对一和一对多关联关系不同,需要通过另外的一张表保存多对多的映射关系。下面将以应用系统中的权限分配为例讲解多对多的关联关系,例如用户可以拥有多个系统的操作权限,而一个权限又可以被赋予多个用户,这就是典型的多对多关联映射关系。其中用户表(tab_user)和权限表(tab_user)的表关系如下图所示。

说明:由于多对多关联关系的查询对第3个表进行反复查询,在一定程度上会影响系统的性能效率,所以在应用中尽量少使用多对多关联关系的表结果。

【示例】建立用户对象与权限对象的多对多关联关系,查询用户admin所拥有的权限,以及权限“新闻管理”被赋予了哪些用户。

(1)在MySQL数据库创建用户表(tab_user)、权限表(tab_role)和映射表(tab_mapping),并添加相关数据。

-- 判断数据表是否存在,存在则删除
DROP TABLE IF EXISTS tab_user;
DROP TABLE IF EXISTS tab_role;
DROP TABLE IF EXISTS tab_mapping;
 
-- 创建“用户信息”数据表
CREATE TABLE IF NOT EXISTS tab_user
( 
	id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
	NAME VARCHAR(45) NOT NULL COMMENT '用户名称'
) COMMENT = '用户信息表';
 
-- 创建“权限信息”数据表
CREATE TABLE IF NOT EXISTS tab_role
( 
	id INT AUTO_INCREMENT PRIMARY KEY COMMENT '权限ID',
	role_name VARCHAR(45) NOT NULL COMMENT '权限名称'
) COMMENT = '权限信息表';
 
-- 创建“映射信息”数据表
CREATE TABLE IF NOT EXISTS tab_mapping
( 
	id INT AUTO_INCREMENT PRIMARY KEY COMMENT '映射ID',
	user_id INT COMMENT '用户Id',
	role_id INT COMMENT '权限Id'
) COMMENT = '映射信息表';
 
-- 添加数据
INSERT INTO tab_user(NAME) VALUES('admin'),('pan_junbiao的博客');
INSERT INTO tab_role(role_name) VALUES('系统管理员'),('新闻管理员'),('广告管理员');
INSERT INTO tab_mapping(user_id,role_id) VALUES(1,1),(1,2),(1,3),(2,2),(2,3);

(2)创建名称为User.java用户信息的持久化类。

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;
import java.util.List;

/**
 * 用户信息的持久化类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tab_user")
public class User
{
    //用户ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    //用户名称
    @Column(name = "name")
    private String name;

    //引用的权限实体对象集合
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "tab_mapping",joinColumns = {@JoinColumn(name = "user_id")},inverseJoinColumns = {@JoinColumn(name="role_id")})
    private List<Role> roleList;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public List<Role> getRoleList()
    {
        return roleList;
    }

    public void setRoleList(List<Role> roleList)
    {
        this.roleList = roleList;
    }
}

(3)创建名称为Role.java权限信息的持久化类。

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;

/**
 * 权限信息的持久化类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tab_role")
public class Role
{
    //权限ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    //权限名称
    @Column(name = "role_name")
    private String roleName;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getRoleName()
    {
        return roleName;
    }

    public void setRoleName(String roleName)
    {
        this.roleName = roleName;
    }
}

(4)创建名称为UserDao.java用户信息数据库访问接口,并继承JpaRepository接口。

package com.pjb.jpauserdemo.dao;

import com.pjb.jpauserdemo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * 用户信息数据库访问接口
 * @author pan_junbiao
 **/
@Repository
public interface UserDao extends JpaRepository<User,Integer>
{
}

(5)测试:多对多查询(获取用户信息与关联的权限列表)。

@Autowired
private UserDao userDao;

/**
 * 多对多查询:获取用户信息与关联的权限列表
 * @author pan_junbiao
 */
@Test
public void getUserAndRole()
{
    List<User> userList = userDao.findAll();
    if(userList!=null && userList.size()>0)
    {
        //遍历用户列表
        for(User user : userList)
        {
            System.out.println("用户编号:" + user.getId());
            System.out.println("用户名称:" + user.getName());

            //获取权限列表
            List<Role> roleList = user.getRoleList();
            if(roleList!=null && roleList.size()>0)
            {
                System.out.print("用户拥有的权限:");
                for (Role role : roleList)
                {
                    System.out.print(role.getRoleName()+";");
                }
            }
            System.out.println("\n-----------------------------------------------");
        }
    }
}

执行结果:

 

  • 17
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: Spring Data JPA可以通过使用@Query注解和JPQL语句来实现多表联合查询。在JPQL语句中,可以使用JOIN关键字来连接多个表,并使用ON子句来指定连接条件。例如: @Query("SELECT u.username, p.title FROM User u JOIN u.posts p ON u.id = p.userId") List<Object[]> findUserAndPost(); 这个例子中,User和Post是两个实体类,它们之间通过userId属性建立了关联关系。通过JOIN关键字和ON子句,我们可以将两个表连接起来,并查询出用户名和文章标题。最终返回的是一个Object数组,包含了查询结果中的两个字段。 除了使用@Query注解,Spring Data JPA还提供了一些方法命名规则,可以自动生成查询语句。例如,如果我们在UserRepository中定义一个方法: List<User> findByPostsTitle(String title); Spring Data JPA会自动根据方法名生成查询语句,查询所有标题为指定值的文章所属的用户。这个方法名中的“Posts”是User实体类中的一个属性,它表示用户发表的所有文章。通过这种方式,我们可以方便地进行多表联合查询,而不需要手动编写复杂的SQL语句。 ### 回答2: Spring Data JPASpring Framework的一个模块,它提供了SpringJPA之间的集成,并支持快速开发具有CRUD功能的应用程序。在多表联合查询中,Spring Data JPA可以使用JPQL或原生SQL语句来查询多个表,并通过实体类的关系来建立表之间的关联。下面将具体介绍如何使用Spring Data JPA进行多表联合查询。 1. 使用JPQL进行多表联合查询 使用JPQL进行多表联合查询比使用原生SQL语句更方便,因为可以直接使用实体类和属性名来代替表名和列名。 例如,我们有两个实体类:Customer和Order,它们之间是多对一的关系,即一个客户可以下多个订单。我们可以使用以下JPQL查询语句来查询所有客户及其对应的订单: ``` @Query("SELECT c, o FROM Customer c LEFT JOIN c.orders o") List<Object[]> findCustomerWithOrder(); ``` 这里使用了LEFT JOIN关键字来连接两个表,LEFT JOIN表示左连接,即返回左表(这里是Customer表)中所有数据和右表(这里是Order表)中匹配的数据。在SELECT语句中,我们选择了两个实体类,分别用c和o来代表它们,并将它们放在一个数组中返回。这样就可以查询到所有客户及其对应的订单。 2. 使用原生SQL语句进行多表联合查询 如果使用JPQL不能满足需求,也可以使用原生SQL语句来进行多表联合查询。这时需要使用EntityManager来执行SQL语句。 例如,我们有两个表:Customer和Order,它们之间的关系同上。我们可以使用以下SQL语句来查询所有客户及其对应的订单: ``` SELECT c.*, o.* FROM customer c LEFT JOIN orders o ON c.id = o.customer_id ``` 在EntityManager中,可以使用createNativeQuery方法来创建原生SQL语句的查询对象,以及setParameter方法来设置查询参数(如果有的话)。例如: ``` String sql = "SELECT c.*, o.* FROM customer c LEFT JOIN orders o ON c.id = o.customer_id"; Query query = entityManager.createNativeQuery(sql); List<Object[]> resultList = query.getResultList(); ``` 这里使用了Query.getResultList方法来返回结果集,它返回的是一个包含多个数组的列表,每个数组对应一行查询结果。数组中的元素按照SELECT语句的顺序排列。 总结 Spring Data JPA提供了方便的方法来进行多表联合查询,可以使用JPQL或原生SQL语句来查询多个表,并通过实体类之间的关系建立表之间的关联。使用JPQL可以更方便地查询,而使用原生SQL语句可以更灵活地满足各种查询需求。 ### 回答3: Spring Data JPASpring Data项目的一部分,它通过JPA规范提供了ORM解决方案。在关系型数据库中,一个数据库通常由多张表组成,而在开发过程中,我们经常需要对这些表进行查询、修改、删除等操作,如果我们需要进行多表查询,该如何实现呢? Spring Data JPA 提供了多种方式实现多表联合查询,下面我们对这些方式进行一一介绍。 1.通过JPA关联查询实现多表联合 JPA提供了两种形式的关联查询:内部关联查询和左外关联查询,这两种关联查询可以满足大部分复杂查询的需求。 内部关联查询:通过@Table注解中@TableJoinColumn属性或@JoinColumn注解,将两个实体类之间的关联关系定义在Java类中。定义完关联关系后,可以通过JPQL或Spring Data JPA提供的函数查询方法实现联合查询。 左外关联查询Spring Data JPA还提供了@Query注解的方式,开发者可以自行编写JPQL或SQL语句实现多表联合查询,并通过@Query注解进行绑定。 2.通过Criteria API实现多表联合 Criteria API是JPA提供的查询语言的一种形式,它允许开发人员通过程序生成查询语句,而不必编写具体的SQL或JPQL语句。使用Criteria API时,只需要将实体类的基本属性与关联属性设定好之后,生成一个CriteriaBuilder对象,就可以构建复杂的查询语句。 3.通过Spring Data JPA提供的命名查询实现多表联合 Spring Data JPA提供了命名查询的方式,命名查询是通过在Repository中定义方法的名称和方法的输入参数来实现的。命名查询是一个声明式的查询,开发者可以指定所需的查询字符串和返回值。 总而言之,Spring Data JPA提供了多种方式实现多表联合查询,并且具有简洁、高效、易维护等特点,开发者可以根据需求选择最合适的方式来实现多表联合查询。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pan_junbiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值