Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wyświetlanie obrazów z bazy danych MySQL w tabeli danych JSF

Możesz użyć <p:graphicImage> aby wyświetlić obrazy przechowywane w byte[] , niezależnie od byte[] źródło (DB, dyskowy system plików, sieć itp.). Najprostszy przykład to:

<p:graphicImage value="#{bean.streamedContent}" />

który odwołuje się do StreamedContent właściwość.

Ma to jednak pewną pułapkę, szczególnie gdy jest używana w komponencie iteracyjnym, takim jak tabela danych:metoda pobierająca zostanie wywołana dwukrotnie; po raz pierwszy przez samo JSF, aby wygenerować adres URL dla <img src> i drugi raz przez przeglądarkę internetową, gdy musi pobrać zawartość obrazu na podstawie adresu URL w <img src> . Aby być wydajnym, nie powinieneś uderzać DB w pierwszym wywołaniu gettera. Ponadto, aby sparametryzować wywołanie metody pobierającej, aby można było użyć metody ogólnej, w której przekazujesz określony identyfikator obrazu, powinieneś użyć <f:param> (proszę zauważyć, że funkcja przekazywania argumentów metody w wersji EL 2.2 nie będzie działać w ogóle, ponieważ nie kończy się to na adresie URL <img src> !).

Podsumowując, powinno to wystarczyć:

<p:dataTable value="#{bean.items}" var="item">
    <p:column>
        <p:graphicImage value="#{imageStreamer.image}">
            <f:param name="id" value="#{item.imageId}" />
        </p:graphicImage>
    </p:column>
</p:dataTable>

#{item.imageId} oczywiście zwraca unikalny identyfikator obrazu w bazie danych (klucz podstawowy), a zatem nie byte[] zawartość. #{imageStreamer} to bean o zakresie aplikacji, który wygląda tak:

@ManagedBean
@ApplicationScoped
public class ImageStreamer {

    @EJB
    private ImageService service;

    public StreamedContent getImage() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
            return new DefaultStreamedContent();
        } else {
            // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
            String imageId = context.getExternalContext().getRequestParameterMap().get("imageId");
            Image image = imageService.find(Long.valueOf(imageId));
            return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
        }
    }

}

Image klasa jest w tym konkretnym przykładzie po prostu @Entity z @Lob na bytes właściwość (ponieważ używasz JSF, oczywiście zakładam, że używasz JPA do interakcji z bazą danych).

@Entity
public class Image {

    @Id
    @GeneratedValue(strategy = IDENTITY) // Depending on your DB, of course.
    private Long id;

    @Lob
    private byte[] bytes;

    // ...
}

ImageService to tylko standardowy @Stateless EJB, nic specjalnego do zobaczenia:

@Stateless
public class ImageService {

    @PersistenceContext
    private EntityManager em;

    public Image find(Long id) {
        return em.find(Image.class, id);
    }

}

Zobacz też:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak obliczyć sumę bieżącą w MySQL

  2. problem z nazwą kolumny „typ” w szynach 3

  3. Błąd składni SQL 1064 przy użyciu przygotowanej instrukcji JDBC

  4. Zrozumienie indeksów wielu kolumn w zapytaniu MySQL

  5. Jak przekonwertować kolumnę na ASCII w locie bez zapisywania w celu sprawdzenia dopasowań z zewnętrznym ciągiem ASCII?