简体   繁体   English

在 SQL 或 JPQL 中查询以获取单向关系一对多

[英]Query in SQL or JPQL to fetch unidirectional relationship One-To-Many

I'm building an API for the company where I work and it is my first time using Spring Boot, so I'm having some doubts.我正在为我工作的公司构建一个 API,这是我第一次使用 Spring Boot,所以我有一些疑问。 So I have a One-To-Many unidirectional relationship, from my parent class (Compania) to my child class (Office).所以我有一个一对多的单向关系,从我的父母 class(公司)到我的孩子 class(办公室)。 The thing is that I don't know how to query for the Office objects that are part of the Compania object.问题是我不知道如何查询属于 Compania object 的 Office 对象。 I think it should be a straightforward solution, but I can't manage to find it.我认为这应该是一个简单的解决方案,但我无法找到它。

Hibernate creates for me an extra table that is called COMPANIA_OFFICE and I don't know how to use it with a SQL or JPQL query. Hibernate 为我创建了一个名为 COMPANIA_OFFICE 的额外表,我不知道如何将它与 SQL 或 JPQL 查询一起使用。 So right now in my database, I have a table called COMPANIA, another one called OFFICE, and the last one called COMPANIA_OFFICE (this one contains COMPANIA_ID and OFFICE_ID, as I don't have the FK in either of the 2 classes it uses an auxiliary table to join them, I suppose).所以现在在我的数据库中,我有一个名为 COMPANIA 的表,另一个名为 OFFICE,最后一个名为 COMPANIA_OFFICE(这个包含 COMPANIA_ID 和 OFFICE_ID,因为我在它使用的两个类中都没有 FK辅助表加入他们,我想)。

What I want to achieve is in a GET request like this one:我想要实现的是像这样的 GET 请求:

GET /companias/{companiaId}/office/{officeName} --> Return a list with the offices that have that name from a specified company by id . GET /companias/{companiaId}/office/{officeName} -> 返回一个列表,其中包含来自指定公司的具有该名称的办公室的 id

The classes that I have now are these:我现在的课程是:

Compania公司

@Entity(name = "Compania")
    @Table(
        name = "compania"
    )
    public class Compania {
        @Id
        @SequenceGenerator(
            name = "compania_sequence",
            sequenceName = "compania_sequence",
            allocationSize = 1
        )
        @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "compania_sequence"
        )
        @Column(
            nullable = false
        )
        private Long id;
    
        @Column(
            name = "name",
            nullable = false,
            unique = true
        )
        private String name;
    
        @OneToMany(
            mappedBy = "compania",
            cascade = CascadeType.ALL,
            fetch = FetchType.LAZY,
            orphanRemoval = true
        )
        private List<Office> office;

    ...Constructors...
    ... Getters and Setters...

Office (Child)办公室(儿童)

@Entity()
@Table()
public class Office {
    @Id
    @SequenceGenerator(
        name = "office_sequence",
        sequenceName = "office_sequence",
        allocationSize = 1
    )
    @GeneratedValue(
        strategy = GenerationType.SEQUENCE,
        generator = "office_sequence"
    )
    @Column(
        nullable = false
    )
    @JsonIgnore
    private Long id;

    @Column(
        name = "idRef",
        nullable = false
    )
    private int idRef;

    @Column(
        name = "title",
        nullable = false
    )
    private String title;

    @Column(
        name = "name"
    )
    private String name;

    ...Constructors...
    ... Getters and Setters...

So my problem is that I don't know how to make that query in spring Boot.所以我的问题是我不知道如何在 spring Boot 中进行该查询。 I don't if using straight SQL or JPQL.如果直接使用 SQL 或 JPQL,我不会。

Thanks in advance!提前致谢!

Edit.编辑。 I've tried using a native Query like this:我试过使用这样的本机查询:

@Query(
        value = "select o.* from office o " +
            "inner join compania_office co on o.id = co.office_id " +
            "inner join compania c on c.id = co.compania_id " +
            "where c.id = :companiaId and lower(o.title) like lower(:officeTitle) " +
            "order by o.id_ref asc;",
        nativeQuery = true
    )
    List<Office> findOfficesByTitleLike(@Param("companiaId")Long companiaId,@Param("officeTitle") String officeTitle);

It works when I'm using a Database manager like Navicat or the one embedded in IntelliJ doing a common query.当我使用像 Navicat 这样的数据库管理器或嵌入在 IntelliJ 中的数据库管理器执行常见查询时,它可以工作。 But when I try to use it with my API it gives me this error:但是当我尝试将它与我的 API 一起使用时,它给了我这个错误:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; org.springframework.dao.InvalidDataAccessResourceUsageException:无法提取结果集; SQL [n/a]; SQL [不适用]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet嵌套异常是 org.hibernate.exception.SQLGrammarException:无法提取 ResultSet

Do you know what could be happening?你知道会发生什么吗? Thanks!谢谢!

Recently I had a similar issue.最近我有一个类似的问题。 I managed it to fetch data from two Entities/tables by using JDBC template.我使用 JDBC 模板管理它从两个实体/表中获取数据。 However, first I created a class where are included only the columns that I require.但是,首先我创建了一个 class ,其中仅包含我需要的列。 The following is my solution and the suggestion for your issue:以下是我的解决方案和对您问题的建议:

    @GetMapping("/testi2")
public List<CustomerResponse> getCCP2() {
    String sql = "SELECT top 20 c.ID, c.CustomerNumber, c.Name, c.Surname, c.Area, c.City, c.Address, c.PhoneNumber, c.CustomerTypeID, c.Enabled, c.DateCreated, p.Id, p.Debit, p.Credit\n" +
            "FROM TblCustomer c OUTER APPLY\n" +
            "     (SELECT TOP 1 p.*\n" +
            "      FROM TblPayments p\n" +
            "      WHERE c.CustomerNumber = p.CustomerNumber\n" +
            "      ORDER BY p.id DESC \n" +
            "     ) p;";
    List<CustomerResponse> result = jdbcTemplate.query(
            sql,
            new BeanPropertyRowMapper(CustomerResponse.class));

    return result;
}

where class <CustomerResponse> is holding "ID, CustomerNumber, Name, Surname, Area, City, Address, PhoneNumber, CustomerTypeID, Enabled, c.DateCreated, Id, Debit, Credit".其中 class <CustomerResponse>持有“ID, CustomerNumber, Name, Surname, Area, City, Address, PhoneNumber, CustomerTypeID, Enabled, c.DateCreated, Id, Debit, Credit”。

I don't know if that's your problem, but I had a similar issue recently and the string param, :officeTitle in your case, it wasn't being passed as ':officeTitle' (SQL varchar) to sql, so I have solved it casting the param to varchar(255).我不知道这是否是你的问题,但我最近遇到了类似的问题,字符串参数:officeTitle在你的情况下,它没有作为':officeTitle' (SQL varchar) 传递给 sql,所以我已经解决了它将参数转换为 varchar(255)。

...  like lower(cast(:officeTitle AS varchar(255)))

I think nativeQuery doesn't cast the parameter automatically我认为 nativeQuery 不会自动转换参数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM