【问题标题】:Hibernate joining two table and fetch all records?Hibernate 加入两个表并获取所有记录?
【发布时间】:2015-10-09 04:00:05
【问题描述】:

我有两个实体类 Category 和 Events。我需要加入两个表并获取与给定条件匹配的所有记录

我的 sql 查询

SELECT * FROM category c  inner join `events` e on e.category_i=c.category_id where c.parent_category_id=1;

如何将此 sql 查询转换为 hql 并获取数据?我在下面尝试但没有得到结果?我对休眠很陌生

用于休眠映射的事件实体类

import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;

/**
 * The persistent class for the user database table.
 *
 */
@Entity
@Table(name = "events")
public class Events implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "event_id")
    private int eventId;

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

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

    @Column(name = "category_i")
    private Integer categoryI;






    public Integer getCategoryI() {
        return categoryI;
    }

    public void setCategoryI(Integer categoryI) {
        this.categoryI = categoryI;
    }

    @Column(name = "is_trending_event")
    private Integer isTrendingEvent;

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

    private Integer status;

    @Column(name = "created_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdDate;

    @Column(name = "last_updated_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date lastUpdatedDate;

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public Date getLastUpdatedDate() {
        return lastUpdatedDate;
    }

    public void setLastUpdatedDate(Date lastUpdatedDate) {
        this.lastUpdatedDate = lastUpdatedDate;
    }

    public int getEventId() {
        return eventId;
    }

    public void setEventId(int eventId) {
        this.eventId = eventId;
    }

    public String getEventName() {
        return eventName;
    }

    public void setEventName(String eventName) {
        this.eventName = eventName;
    }

    public String getEventDescription() {
        return eventDescription;
    }

    public void setEventDescription(String eventDescription) {
        this.eventDescription = eventDescription;
    }



    public Integer getIsTrendingEvent() {
        return isTrendingEvent;
    }

    public void setIsTrendingEvent(Integer isTrendingEvent) {
        this.isTrendingEvent = isTrendingEvent;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

}

类别实体

import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;

/**
 * The persistent class for the user database table.
 *
 */
@Entity
@Table(name = "category")
public class Category implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "category_id")
    private int categoryId;

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

    @Column(name = "parent_category_id")
    private Integer parentCategoryId;

    @Column(name = "created_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdDate;

    @Column(name = "last_updated_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date lastUpdatedDate;


    @ManyToOne
    @JoinTable(name="events", joinColumns = @JoinColumn(name="category_i"))
    private Events events;

    public int getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public Integer getParentCategoryId() {
        return parentCategoryId;
    }

    public void setParentCategoryId(Integer parentCategoryId) {
        this.parentCategoryId = parentCategoryId;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public Date getLastUpdatedDate() {
        return lastUpdatedDate;
    }

    public void setLastUpdatedDate(Date lastUpdatedDate) {
        this.lastUpdatedDate = lastUpdatedDate;
    }

}

获取类别方法

public List<Object[]> getCategoryList(int id) throws SQLException, ClassNotFoundException, IOException {
        List<Object[]> groupList = null;
        try {
            Session session = sessionFactory.getCurrentSession();
            Query query = session.createQuery("select e from Category e inner join e.events where e.parentCategoryId=1");
            //query.setParameter("id", id);
            groupList = query.list();
        } catch (Exception e) {
        }
        return groupList;
    }

【问题讨论】:

  • 您可以使用休眠条件,并且有一个用于获取连接的属性。
  • @Darshan,请帮我做这件事。 :(
  • 您的映射错误,您认为 JDBC 不是休眠,您映射的是对象而不是 id。在您的 Event 中,您应该有一个 Category 对象而不是一个 id。
  • 如果您不介意,请提供答案,以便我清楚地了解映射方式。

标签: java mysql spring hibernate


【解决方案1】:

在使用ORM 工具时,您需要考虑 Java 对象。

根据您的问题,我认为您尝试编写的查询类似于:

public List<Category> getCategoryList(int id) {
    List<Category> groupList;
    Session session = sessionFactory.getCurrentSession();
    Query query = session.createQuery("select c from Category c join fetch c.events where c.parentCategory.categoryId = 1");
    //query.setParameter("id", id);
    groupList = query.list();
    return groupList;
}

使用 ORM 的好处之一是它可以为您计算出完整的连接查询。

为此,您需要按如下方式更新您的类模型:

import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;

@Entity
@Table(name = "events")
public class Event implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "event_id")
    private int eventId;

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

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

    @ManyToOne
    @JoinColumn(name = "category_i")
    private Category category;

    @Column(name = "is_trending_event")
    private Integer isTrendingEvent;

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

    private Integer status;

    @Column(name = "created_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdDate;

    @Column(name = "last_updated_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date lastUpdatedDate;

    ...

}

import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;

@Entity
@Table(name = "category")
public class Category implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "category_id")
    private int categoryId;

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

    @ManyToOne
    @JoinColumn(name="parent_category_id")
    private Category parentCategory;

    @Column(name = "created_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdDate;

    @Column(name = "last_updated_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date lastUpdatedDate;

    @OneToMany(mappedBy="category")
    private List<Event> events;

    ...

}

【讨论】:

  • 这是我的 sql 查询 SELECT * FROM category c inner join events e on e.category_i=c.category_id where c.parent_category_id=1; 为什么我需要在 Category 实体中加入 parent_category_id?你能解释一下吗?
  • 您需要考虑 SELECT * FROM category c inner join events e 返回的数据以及这些数据如何映射回您的 java 对象。看起来您正在查找所有 Event 对象及其关联的 Category,其中类别的父级具有 categoryId = 1
  • 有关表格和数据获取的更多详细信息,请查看我提出的问题,但我没有得到答案 stackoverflow.com/questions/31476416/…
  • 根据您的评论,我已更新解决方案以返回包含 Event 对象的填充集合的 Category 对象,这些对象将直接映射到您所追求的 JSON。请注意,我更新了 Category 模型以及查询。
  • 你可以在我的getCategoryList 方法中看到返回类型为List&lt;Object[]&gt;..合适吗?
【解决方案2】:

Hibernate 是关于映射对象和关系的,但是您正在映射简单的 id 字段。

在您的Events 课程中,您有以下L

@Entity
@Table(name = "events")
public class Events implements Serializable { 

    @Column(name = "category_i")
    private Integer categoryI;

}

但是它应该是Category 而不是Integer

@Entity
@Table(name = "events")
public class Events implements Serializable { 

    @ManyToOne
    @Column(name = "category_i")
    private Category category;

}

然后在您的Category 中,您应该将mappedBy 字段添加到events 字段上的@ManyToOne 并删除@JoinColumn

@Entity
@Table(name = "category")
public class Category implements Serializable {

    @OneToMany(mappedBy="category")
    private Events events;
}

这同样适用于Category 类的parentCategoryId

现在您已经更正了映射,您应该可以根据需要编写查询了。

【讨论】:

  • 所以?列名仍然可以,只需添加注释即可。我强烈建议阅读 JPA 及其工作原理。它是关于将对象映射到您的数据库结构。按预期使用技术,您正在解决它。
  • 你能解释一下我们在哪里做on关键字的功能吗?
  • @ManyToOne(mappedBy="category") 显示错误找不到符号。您的意思是 OneToMany 吗?
  • 是的,我愿意。错字修正了答案。
【解决方案3】:

输入下面的代码

public List<Object[]> getCategoryList(int id) throws SQLException, ClassNotFoundException, IOException {


        Session session = sessionFactory.getCurrentSession();
        return session.createCriteria(Catagory.class)
        .setFetchMode("events", FetchMode.JOIN)
        .add(Restrictions.eq("parentCatagoryId", 1))
        .list();

}

希望这些东西有用。

【讨论】:

  • 在这里我们提到了在我的情况下我们需要加入哪些列,我必须加入类别表'category_id'和事件表'category_i'(不是主键)。
  • 即,c类内连接eventse on e.category_i=c.category_id
  • 这里我们不需要定义我们要加入的列基础......我们已经在 bean 定义上定义了。
  • 你能解释一下我们在哪里做on关键字的功能吗?
  • 在 setFectchMode 属性上。
【解决方案4】:

这个查询应该可以完成这项工作:

from Category as c
inner join c.events as e
where c.parentCategoryId = 1

另外,您似乎在这里有一个错字(最后缺少“d”):

@JoinColumn(name="category_i"))

【讨论】:

  • @JoinColumn(name="category_i")) 这实际上是加入事件表的列名。我更新了事件实体。没有错过。
  • 显示错误 ERROR JDBCExceptionReporter:101 - Unknown column 'category0_1_.events_event_id' in 'field list' when using this
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 2018-10-09
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多