gpt4 book ai didi

java - 在处理 BLOB 字段时如何提高 EclipseLink 的性能?

转载 作者:行者123 更新时间:2023-11-30 06:08:47 25 4
gpt4 key购买 nike

由于每个实体都有 BLOB 字段,我的 Java 应用程序变得非常慢。该字段通常用于存储 PDF 文件,每当我必须列出所有对象时,持久性提供程序需要花费大量时间才能完成其工作。我寻找有关如何处理此类数据的答案,但其中一些讨论将 BLOB 存储在单独的表中,然后使用 FetchType.LAZY。有没有办法只在需要时获取该字段,而无需创建另一个表?如果不是,创建另一个表是最合适的解决方案吗?

实体代码

@Cache(alwaysRefresh = true)
public class ScdDocumento implements Serializable, MultipleSelector {
@Transient
public static final String QUERY_RELATORIO_DOC_LOC = "consultas/ctrl_docs/consulta_relatorio_doc_local.txt";

@Transient
public static final String QUERY_RELATORIO_DOC_GRUPO = "consultas/ctrl_docs/consulta_relatorio_doc_grupo.txt";

@Id
@Column(name = "nome", length = 50)
private String nome;

@Column(name = "revisao")
private int revisao;

@Column(name = "id_tipo")
private int id_tipo;

@Column(name = "situacao", length = 1)
private String situacao;

@Column(name = "doc_blob_nome", length = 50)
private String doc_blob_nome;

@Lob
@Basic(fetch = FetchType.LAZY)
@Column(name = "documento_blob", nullable = false)
private byte[] documento_blob; //The field that impacts the application perfomance

@Column(name = "abrangencia_geral")
private int abrangencia_geral;

@ManyToMany
@JoinTable(name = "SCD_DOC_GRUPO", joinColumns = {@JoinColumn(name = "id_doc")},
inverseJoinColumns = {@JoinColumn(name = "id_grupo")})
private Set<SosGrupo> grupos;

@ManyToOne
@JoinColumn(name = "id_tipo", insertable = false, updatable = false)
private ScdTipo tipo;

@ManyToMany
@JoinTable(name = "SCD_REFERENCIA", joinColumns = {@JoinColumn(name = "doc_pai")},
inverseJoinColumns = {@JoinColumn(name = "doc_filho")})
private Set<ScdDocumento> referencias;

@ManyToMany
@JoinTable(name = "SCD_REFERENCIA", joinColumns = {@JoinColumn(name = "doc_filho")},
inverseJoinColumns = {@JoinColumn(name = "doc_pai")})
private Set<ScdDocumento> referenciadoPor;

@ManyToMany
@JoinTable(name = "SCD_PALAVRA_REFERENCIA", joinColumns = {@JoinColumn(name = "documento")},
inverseJoinColumns = {@JoinColumn(name = "palavra")})
private Set<ScdPalavraChave> palavrasChaves;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "documento")
private Set<ScdOrdem> ordens;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "documento")
private Set<ScdArquivoOs> arquivosOs;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "documento")
private Set<ScdArquivoHistorico> arquivosHistorico;

@ManyToMany(cascade = {CascadeType.REFRESH, CascadeType.MERGE})
@JoinTable(name = "SCD_LOCAL_DOC", joinColumns = {@JoinColumn(name = "id_doc")},
inverseJoinColumns = {@JoinColumn(name = "id_local")})
private Set<ScdLocal> locais;

@Override
public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}

public int getRevisao() {
return revisao;
}

public void setRevisao(int revisao) {
this.revisao = revisao;
}

public int getIdTipo() {
return id_tipo;
}

public void setIdTipo(int id_tipo) {
this.id_tipo = id_tipo;
}

public String getSituacao() {
return situacao;
}

public void setSituacao(String situacao) {
this.situacao = situacao;
}

public String getDocBlobNome() {
return doc_blob_nome;
}

public void setDocBlobNome(String doc_blob_nome) {
this.doc_blob_nome = doc_blob_nome;
}

public byte[] getDocumentoBlob() {
return documento_blob;
}

public void setDocumentoBlob(byte[] documento_blob) {
this.documento_blob = documento_blob;
}

public int getAbrangenciaGeral() {
return abrangencia_geral;
}

public void setAbrangenciaGeral(int abrangencia_geral) {
this.abrangencia_geral = abrangencia_geral;
}

public Set<SosGrupo> getGrupos() {
return grupos;
}

public void setGrupos(Set<SosGrupo> grupo) {
this.grupos = grupo;
}

public ScdTipo getTipo() {
return tipo;
}

public void setTipo(ScdTipo tipo) {
this.tipo = tipo;
}

public Set<ScdDocumento> getReferencias() {
return referencias;
}

public void setReferencias(Set<ScdDocumento> referencias) {
this.referencias = referencias;
}

public Set<ScdDocumento> getReferenciadoPor() {
return referenciadoPor;
}

public void setReferenciadoPor(Set<ScdDocumento> referenciadoPor) {
this.referenciadoPor = referenciadoPor;
}

public Set<ScdPalavraChave> getPalavrasChaves() {
return palavrasChaves;
}

public void setPalavrasChaves(Set<ScdPalavraChave> palavrasChaves) {
this.palavrasChaves = palavrasChaves;
}

public Set<ScdOrdem> getOrdens() {
return ordens;
}

public void setOrdens(Set<ScdOrdem> ordens) {
this.ordens = ordens;
}

public Set<ScdArquivoOs> getArquivosOs() {
return arquivosOs;
}

public void setArquivosOs(Set<ScdArquivoOs> arquivosOs) {
this.arquivosOs = arquivosOs;
}

public Set<ScdArquivoHistorico> getArquivosHistorico() {
return arquivosHistorico;
}

public void setArquivosHistorico(Set<ScdArquivoHistorico> arquivosHistorico) {
this.arquivosHistorico = arquivosHistorico;
}

public Set<ScdLocal> getLocais() {
return locais;
}

public void setLocais(Set<ScdLocal> locais) {
this.locais = locais;
}

@Override
public String getIdRef() {
return nome;
}

@Override
public String getDesc() {
return tipo.getNome();
}
}

导致问题的方法

图形用户界面

private void loadDocumentTable(String situacao) {
mapaDocumentos = new TreeMap<>();
modelDocumentos.setRowCount(0);

docdao.getCriteria("situacao", situacao).forEach((e) -> {
mapaDocumentos.put(e.getNome(), e);
});

mapaDocumentos.entrySet().forEach((e) -> {
String desc = e.getValue().getDocBlobNome();
modelDocumentos.addRow(new Object[]{e.getKey(), desc.substring(0, desc.length() - 3), e.getValue().getRevisao()});
});
}

通用 Dao

@Override
public List<T> getCriteria(String column, Object value){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(clazz);
Root<T> root = cq.from(clazz);
EntityType<T> ent = root.getModel();
cq.where(cb.equal(root.get(ent.getSingularAttribute(column)), value.toString()));

return em.createQuery(cq).getResultList();
}

表格模型

enter image description here

坚持

将其添加到我的 persistence.xml 中,但 eclipselink 仍然急切地获取 byte[] 字段。

enter image description here

Maven 插件

         <plugin>
<groupId>de.empulse.eclipselink</groupId>
<artifactId>staticweave-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>weave</goal>
</goals>
<configuration>
<persistenceXMLLocation>META-INF/persistence.xml</persistenceXMLLocation>
<logLevel>FINE</logLevel>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.5.2</version>
</dependency>
</dependencies>
</plugin>

最终编辑

staticweave-maven-plugin 实际上有效,但每次更改某些内容时我都需要构建项目以提高性能。发生这种情况是因为编织是静态的,因此它是在构建时应用的,而不是在使用 IDE 运行项目时应用。

最佳答案

JPA basics还允许指定 LAZY 的获取类型,这将阻止加载 BLOB,直到您在实体中访问它。 OneToOne、ManyToOne 和基本映射需要对实体进行字节码增强,以便 EclipseLink 在访问惰性属性并加载它时获得通知,如 here as weaving 中所述。 。这将确保默认情况下不会加载它。

随着编织的使用,还可以使用entity graphs指定加载内容和加载时间。这可以允许在使用实体时将 blob 与实体的其余部分一起加载到单个查询中,并在其他地方默认排除它。请参阅What is the diffenece between FETCH and LOAD for Entity graph of JPA?有关加载和获取图表的信息。

关于java - 在处理 BLOB 字段时如何提高 EclipseLink 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50681203/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com