Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Hiển thị hình ảnh từ cơ sở dữ liệu MySQL trong dữ liệu JSF

Bạn có thể sử dụng <p:graphicImage> để hiển thị hình ảnh được lưu trữ trong một byte[] , bất kể byte[] nguồn (DB, hệ thống tệp đĩa, mạng, v.v.). Ví dụ đơn giản nhất là:

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

trong đó đề cập đến một StreamedContent tài sản.

Tuy nhiên, điều này có một cạm bẫy, đặc biệt khi được sử dụng trong một thành phần lặp lại chẳng hạn như bảng dữ liệu:phương thức getter sẽ được gọi hai lần; lần đầu tiên do chính JSF tạo URL cho <img src> và lần thứ hai bằng trình duyệt web khi cần tải xuống nội dung hình ảnh dựa trên URL trong <img src> . Để hiệu quả, bạn không nên nhấn DB trong lần gọi đầu tiên. Ngoài ra, để tham số hóa lệnh gọi phương thức getter để bạn có thể sử dụng một phương pháp chung trong đó bạn chuyển một ID hình ảnh cụ thể, bạn nên sử dụng <f:param> (xin lưu ý rằng tính năng EL 2.2 truyền đối số phương thức hoàn toàn không hoạt động vì nó không xuất hiện trong URL của <img src> !).

Tóm lại, điều này nên làm:

<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} rõ ràng trả về idenfitier duy nhất của hình ảnh trong DB (khóa chính) và do đó không byte[] các nội dung. #{imageStreamer} là một bean phạm vi ứng dụng trông giống như sau:

@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 trong ví dụ cụ thể này chỉ là một @Entity với một @Lob trên bytes thuộc tính (vì bạn đang sử dụng JSF, tôi cho rằng bạn đang sử dụng JPA để tương tác với DB).

@Entity
public class Image {

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

    @Lob
    private byte[] bytes;

    // ...
}

ImageService chỉ là một @Stateless tiêu chuẩn EJB, không có gì đặc biệt để xem ở đây:

@Stateless
public class ImageService {

    @PersistenceContext
    private EntityManager em;

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

}

Xem thêm:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng Python và MySQL trong Quy trình ETL

  2. Cách tốt nhất để không chuẩn hóa dữ liệu trong Django?

  3. ĐẶT HÀNG tùy chỉnh BẰNG để bỏ qua 'the'

  4. Cách tạo bảng dựa trên Tập kết quả JDBC

  5. SELECT COUNT (*) AS count - Cách sử dụng số đếm này