java - 在 hibernate 中有效地从数据库加载集合的集合

标签 java hibernate

我有一个带有 hibernate 的 Web 应用程序,它可以管理多种语言的数据。目前,基本上每个请求都会在语言翻译上生成大量的选择语句。模型大致如下:

Data <1-1> Placeholder <1-many> languageTranslation <many-1> language

如果我查询所有/许多数据对象,我会看到很多单选,它们为占位符选择一种语言翻译。我最想生成的 SQL:

SELECT * FROM data join placeholder join languagetranslation 
WHERE data.placeholder_id = placeholder.id 
AND languagetranslation.placeholder_id = placeholder.id 
AND languagetranslation.language_id = ?

这样我就可以在一次调用中获得带有占位符和翻译的所有数据。 languagetranslations 具有 language_id 和 placeholder_id 的复合主键。

我没有 HBM 文件,一切都是通过注释管理的。模型代码(仅显示相关部分):

@Entity
public class Data {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, optional = false)
    @Fetch(FetchMode.JOIN)
    private Placeholder content;
}

public class Placeholder { 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "primaryKey.placeholder", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @Fetch(FetchMode.JOIN)
    private Set<LanguageTranslation> languageTranslations = new HashSet<>();
}

public class LanguageTranslation {

    @EmbeddedId
    private LanguageTranslationPK primaryKey = new LanguageTranslationPK();

    @Type(type = "org.hibernate.type.StringClobType")
    private String text;

}

@Embeddable
public class LanguageTranslationPK {

    @ManyToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private TextPlaceholder textPlaceholder;

    @ManyToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private Language language;
}

public class Language {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

我尝试了 FetchType 和 FetchMode,但无法生成我想要的行为,它总是对单一语言翻译进行单一选择。

我还尝试了多种查询方式:基于条件、HQL 和原始 SQL。我当前的原始 SQL 查询如下:

String sql_query = "select data.*, lt.* from Data as data join languagetranslation as lt on data.content_id = lt.textplaceholder_id";
Query q = getSession().createSQLQuery(sql_query).addEntity("data", Data.class).addJoin("data.content_id", "data.title").addJoin("lt", "data.content.languageTranslations").setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return q.list();

我在这里做错了什么吗?我如何说服 hibernate 在一次数据库调用中获取所有实体?或者还有其他一些方法可以提高我的情况的性能(例如批量选择)?

最佳答案

您可以创建代理 pojo,其中包含所有实体变量以及 getter、setter 和构造函数。然后在 hibernate 查询中初始化此构造函数,以便您从数据库中获取所有需要的数据。

import com.proxy;
 class userProxy{
private string name;
private string password;
private string address;
private int pincode;
private byte[] profilePic;
private int age;

public userProxy(string name,string password){
  this.name = name;
  this.password = password;
}

//Getter and setter of all variable...
}

然后使用这个构造函数来进行 Hibernate 查询,如

select new com.proxy.userProxy(user.name,user.password) from usertable

关于java - 在 hibernate 中有效地从数据库加载集合的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43065694/

相关文章:

java - 具有多级连接的 Hibernate Criteria

java - 在 hibernate 中插入多个对象作为实例变量

java - 如何在 Spring Data JPA 中定义 BigDecimal 的 BigDecimal 舍入策略?

Hibernate 一对多返回 arrayindexoutofbounds

java - 文本文件中的多个数组

java - Object.isArray() 很慢,有没有快速的方法呢?

java - 将一串数字转换为数组

java - 如何可靠地发送 JMS 消息? (故障转移 MessageProducer.send() 错误)

hibernate - 替代grails多列唯一约束(乐观插入)

java - 展开所有实例的抽象 Java 类