【问题标题】:How to create Many-One Mapping in hibernate?如何在休眠中创建多一映射?
【发布时间】:2010-09-22 06:39:41
【问题描述】:

我想在 Expense(ID, NAME, CATEGORY) 和两个表之间创建多对一映射 类别(ID,名称)。 在我的课堂上,我创建了一个字段“类别类别”及其设置器和获取器。 我是在网上看到一些东西后才做的。我必须在 Category.java 类中进行哪些更改。就目前而言,它看起来像,

public class Category{
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int catId;
private String catName;

public Category() {
}

public int getCatId() {
    return this.catId;
}

public void setCatId(int catId) {
    this.catId = catId;
}

public String getCatName() {
    return this.catName;
}

public void setCatName(String catName) {
    this.catName = catName;
}

}

我不想使用 xml 配置进行映射。我认为,注解对我这样的初学者来说是件好事。

还有我的老! SQL 查询看起来像,

SELECT EXPENSES.EXPNS_ID, EXPENSES.CAT_ID, EXPENSES.NAME, CATEGORY.CAT_NAME FROM EXPENSES INNER JOIN CATEGORY ON EXPENSES.CAT_ID = CATEGORY.CAT_ID WHERE USER_NAME="+currentUserName

如何在 Hibernate 中使用内连接?

任何建议!!

谢谢!


更新

感谢所有回答者, 我试过你所说的,它返回一个空列表。

测试我设置了表中的“用户名=泰米尔语”。 Hibernate 生成的查询如下所示,

select expens0_.expnsId as expnsId1_, expens0_.catId as catId1_, expens0_.category_catId as category7_1_, expens0_.userName as userName1_ from Expens expens0_ inner join Category category1_ on expens0_.category_catId=category1_.catId where expens0_.userName=?

作为一个初学者,我对 JPQL 有一些疑问,我想要来自 Category[catId, catName] 表的 catNamecatId 也可以在 Expens[expnsId, catId, userName] 中使用。

通过在 Expens.java 类中添加以下行,它将如何为我提供 catName 以及 Expens 表中的其他变量。

@ManyToOne
private Category category

// getters, setters

我无法理解它。在不理解这一点的情况下,我无法更进一步,我必须在我的项目中提供更多映射。如果这个映射清楚,我可以放心地进行其他操作。

我使用的查询是pascal的版本:Query query = hSession.createQuery("SELECT e FROM Expens e JOIN e.category c WHERE e.userName = :userName").setParameter("userName", userName);

对我来说,hibernate 生成的查询看起来和我的旧 SQl 查询一样。我在这里找不到问题。

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    实际上,对您的案例有用的文档的很大一部分位于 Hibernate Annotations Reference Guides(下面提供的链接)中。阅读它会非常值得。

    话虽如此,关于您的具体问题,最简单的可能映射是:

    @Entity
    public class Expense {
        @Id @GeneratedValue
        private Long;
    
        @ManyToOne
        private Category category
    
        // getters, setters
        ...
    }
    

    就是这样。

    如果你想让它成为双向的,你必须在另一边添加一个OneToMany(不要忘记mappedBy元素,因为关联是双向的):

    @Entity
    public class Category {
        @Id @GeneratedValue
        private Long id;
    
        @OneToMany(mappedBy="category")
        private Set<Expense> expenses = new HashSet<Expense>();
        ....
    }
    

    一个可能的 JPQL 查询是:

    SELECT e FROM Expense e JOIN e.category c WHERE e.username = :username  
    

    更新: Hibernate 和 JDBC 是不同的。使用 Hibernate,您需要考虑对象,并且上面的 HQL 查询(这是一个示例)实际上将返回 List&lt;Expense&gt;。要获取类别名称,请遍历结果并浏览关联。例如:

    List<Expense> expenses = ... // some code to retrieve a list by username
    
    for (Expense expense : expenses) {
        System.out.println(expense.getCategory().getName());
    }
    

    参考文献

    【讨论】:

    • 谢谢!我试过你所说的。我更新了我的问题的结果和一些疑问。我希望你能回答他们。
    • 我还想告诉你,你提供的链接对我很有帮助。我只是单独红色了多对一部分。看到链接后,它让我想起了我浪费在互联网上搜索多对一的时间。
    • @pascal:是的,它有帮助,但是,您从未在我的问题中回复我的更新。我在那里有一个巨大的清单。你知道,我仍然对它们感到震惊。
    • @MaRaVan 也许我也有一个巨大的列表。也许我没有 your 数据库,无法为您调试它。也许我不明白“问题”没有解决。对我来说,原来的问题已经解决了。
    • @Pascal:嘿,别误会。实际上我正在尝试的是,我有一个对象,它的一个属性在另一个表中。如果你看到hibernate方式生成的Query,就可以完全理解我的问题了。在on expens0_.category_catId=category1_.catId 之后,查看它是否使用同一张表中的相同值进行检查。我做了你建议的事情。创建类别类别;及其二传手吸气剂。用@ManyToOne 注释。然后,仍然为什么要检查同一实体的相同值。我是初学者,看不懂。帮我一把!!!
    【解决方案2】:

    正如博卓建议的那样,

    @ManyToOne(fetch=FetchType.EAGER) // Gonna be eager by default anyway
    @JoinColumn(name="CATEGORY_ID")
    private Category category;
    

    在您的 Category 类中加上这个,使其成为双向的,

    @OneToMany(mappedBy="category")
    private List<Expense> expense;
    

    你不需要做这样的内部连接。当您查询费用时,相关类别将自动加载,很可能使用连接。

    【讨论】:

    • @Pascal Thivent:谢谢,Pascal。但你总是会得到一个详细、格式良好且更有帮助的答案。 :)
    【解决方案3】:

    在你的Expense 班级有:

    @ManyToOne
    @JoinColumn(name="CATEGORY_ID")
    private Category category
    

    正如 cmets 中所指出的,如果您需要访问给定类别中的所有费用,即具有一对多关系,您可以:

    @OneToMany
    private List<Expense> expenses;
    

    例如,我更喜欢使用尽可能少的 @OneToMany 映射 - 您必须管理急切/延迟加载,在某些时候限制结果数量等。对于他们,我倾向于使用 HQL 查询获取我需要的对象子集(在您的情况下为费用)。

    【讨论】:

    • 我认为双向是个好主意。你说什么?您只需要在此处添加关于Category 类的更多建议。
    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多