JPA 连表查询

本文详细介绍了如何在Java持久化API(JPA)中实现A表和B表的关联查询,通过示例代码展示了如何在实体类中定义一对一关联关系,并在DAO层使用Specification和@Query注解进行复杂查询。

A表和B表

@Entity
@Table(name = "A", schema = "kps", catalog = "kps")
@DynamicUpdate
public class A implements java.io.Serializable {

private String aUUID;
//关联B
private B b;

@OneToOne(fetch = FetchType.EAGER, optional = true)
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "aUUID", referencedColumnName = "aUUID", insertable = false, updatable = false)
public B getB() {
return b;
}

public void setB(B b) {
this.b= b;
}


}

@Entity
@Table(name = "B", schema = "kps", catalog = "kps")
@DynamicUpdate
public class B implements java.io.Serializable {

private String bUUID;
private Integer age;


}

 


 

JPA查询时

@Override
public PageResult<A> pagedListForVaild(A entity, Integer currentPage, Integer pageSize,
Order... orders) throws Exception {
// 构建查询条件
Specification<A> sf = new Specification<A>() {
@Override
public Predicate toPredicate(Root<A> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>();
Join<A, B> join = root.join("b", JoinType.INNER);
list.add(cb.equal(join.<String>get("age"), Age));
return cb.and(list.toArray(p));
}
};

return super.gerPageResult(currentPage, pageSize, sf, orders);

}

 

PS:Dao使用@Query注解,也会查询到关联对象。

转载于:https://www.cnblogs.com/hanjun0612/p/10343151.html

在使用 Spring Data JPA 进行多关联查询时,虽然其对单操作非常友好,但在面对多连接查询时相对复杂。以下是几种实现 JPA连接查询的方法,结合实体关系注解和自定义查询方式。 ### 1. 使用实体关系注解建立关联 JPA 通过注解方式定义实体之间的关系,包括 `@ManyToOne`、`@OneToMany`、`@OneToOne` 和 `@ManyToMany` 等。通过这些注解可以建立实体之间的关联关系,从而实现多查询。 例如,定义两个实体 `City` 和 `Country` 示城市和国家之间的关系: ```java @Entity public class City { @Id private Long id; private String name; @ManyToOne @JoinColumn(name = "country_id") private Country country; // getters and setters } @Entity public class Country { @Id private Long id; private String name; @OneToMany(mappedBy = "country") private List<City> cities; // getters and setters } ``` 通过 `@ManyToOne` 注解定义了 `City` 与 `Country` 的多对一关系,并使用 `@JoinColumn` 指定外键字段名称。这样可以通过 `City` 查询其所属的 `Country`,也可以通过 `Country` 查询其所有 `City` 记录 [^4]。 ### 2. 使用 JPQL 编写多查询语句 JPA 提供了 JPQL(Java Persistence Query Language),支持面向对象的查询语言。可以通过 JPQL 编写多连接查询语句,实现复杂的关联查询。 例如,查询所有城市及其所属国家的名称: ```java @Query("SELECT c.name AS cityName, co.name AS countryName FROM City c JOIN c.country co") List<Object[]> findCityAndCountry(); ``` 通过 `JOIN` 关键字实现 `City` 和 `Country` 的连接查询,返回城市名称和国家名称的组合结果 [^3]。 ### 3. 使用原生 SQL 查询 如果 JPQL 无法满足复杂的多查询需求,可以通过 `@Query` 注解配合 `nativeQuery = true` 使用原生 SQL 查询。 例如,查询每个城市的编号、名称、人口、所属国家和所在洲: ```java @Query(value = "SELECT c.id, c.name, c.population, co.name AS country, co.continent " + "FROM city c JOIN country co ON c.country_id = co.id", nativeQuery = true) List<Object[]> findCityDetails(); ``` 该查询使用原生 SQL 实现 `city` 和 `country` 的连接查询,返回城市编号、名称、人口、国家名称和所属洲的信息 [^3]。 ### 4. 使用 Specification 实现动态查询 Spring Data JPA 提供了 `JpaSpecificationExecutor` 接口,支持基于 `Specification` 的动态查询,适用于多条件组合查询的场景。 例如,定义 `CityRepository` 接口: ```java public interface CityRepository extends JpaRepository<City, Long>, JpaSpecificationExecutor<City> { } ``` 然后编写动态查询逻辑: ```java Specification<City> spec = (root, query, criteriaBuilder) -> { Join<City, Country> countryJoin = root.join("country", JoinType.INNER); List<Predicate> predicates = new ArrayList<>(); // 添加查询条件 if (countryName != null && !countryName.isEmpty()) { predicates.add(criteriaBuilder.equal(countryJoin.get("name"), countryName)); } return criteriaBuilder.and(predicates.toArray(new Predicate[0])); }; List<City> cities = cityRepository.findAll(spec); ``` 通过 `root.join` 实现 `City` 和 `Country` 的连接,并根据条件动态构建查询语句 [^2]。 ### 5. 使用 DTO 接收查询结果 对于复杂的多查询结果,建议使用 DTO(Data Transfer Object)接收数据,避免直接使用实体类或 `Object[]`,提高代码可读性和维护性。 例如,定义 `CityDTO`: ```java public class CityDTO { private Long id; private String cityName; private Integer population; private String countryName; private String continent; // constructor, getters and setters } ``` 然后在 Repository 中定义查询方法: ```java @Query(value = "SELECT new com.example.dto.CityDTO(c.id, c.name, c.population, co.name, co.continent) " + "FROM City c JOIN c.country co") List<CityDTO> findCityDTOs(); ``` 通过构造函数方式将查询结果映射到 `CityDTO` 对象中,提高数据结构的清晰度 [^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值