How to read bytea image data from PostgreSQL with JPA?

后端 未结 5 948
离开以前
离开以前 2020-12-31 08:56

I have PostgreSQL database and there is column \'image\' with datatype \'bytea\'. I cannot modify columns or database configurations. JPA annotated POJO contains followign m

相关标签:
5条回答
  • 2020-12-31 09:28

    Try to annotate you entity with @Lob

    @Lob
    @Column(name="image")
    private byte[] image;
    

    If you are using hibernate implementation you can add @Type(type="org.hibernate.type.BinaryType") in column too.

    @Lob
    @Column(name="image")
    @Type(type="org.hibernate.type.BinaryType")
    private byte[] image;
    
    0 讨论(0)
  • 2020-12-31 09:37

    The returned Data looks as if it is base64 encoded. You have to decode it back to binary data before writing to file.

    For further information to decode look here

    0 讨论(0)
  • 2020-12-31 09:40

    ImageEntity

    package com.example;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    @Entity
    public class ImageEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(name="image")
        private byte[] image;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public byte[] getImage() {
            return image;
        }
    
        public void setImage(byte[] image) {
            this.image = image;
        }
    }
    

    ImageRepository

    package com.example;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface ImageRepository extends JpaRepository<ImageEntity, Long> {
    }
    

    Test

    package com.example;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.annotation.Resource;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.SpringApplicationConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import junit.framework.TestCase;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = TestApplication.class)
    public class ImageDaoTest {
    
        @Resource
        private ImageRepository imageRepository;
    
        @Test
        public void testImage() throws IOException {
    
            // Read an image from disk. Assume test.png exists
            ByteArrayOutputStream out = new ByteArrayOutputStream();
    
            try (InputStream in = getClass().getResourceAsStream("test.png")) {
                int length;
                byte[] buffer = new byte[1024];
                while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length);
            }
    
            byte[] image = out.toByteArray();
    
            // Store image to DB
            ImageEntity imageEntiry = new ImageEntity();
            imageEntiry.setImage(image);
            long imageEntiryId = imageRepository.save(imageEntiry).getId();
    
            // Retrieve image from DB
            ImageEntity resultImageEntiry = imageRepository.findOne(imageEntiryId);
            byte[] resultImage = resultImageEntiry.getImage();
    
            // Compare retrieved image with source image by byte to byte comparison
            for (int i = 0; i < resultImage.length; i++) {
                TestCase.assertEquals(image[i], resultImage[i]);
            }
    
        }
    
    }
    

    It works against Postgres 9.5.0-1 with 9.4.1207.jre7 jdbc driver.

    0 讨论(0)
  • 2020-12-31 09:43

    insert an image, you would use:

      //Get the Large Object Manager to perform operations with
        LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
    
        // Create a new large object
        int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
    
        // Open the large object for writing
        LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
    
        // Now open the file
        File file = new File("myimage.gif");
        FileInputStream fis = new FileInputStream(file);
    
        // Copy the data from the file to the large object
        byte buf[] = new byte[2048];
        int s, tl = 0;
        while ((s = fis.read(buf, 0, 2048)) > 0) {
            obj.write(buf, 0, s);
            tl += s;
        }
    
        // Close the large object
        obj.close();
    
    // Now insert the row into imageslo
    PreparedStatement ps = conn.prepareStatement("INSERT INTO imageslo VALUES (?, ?)");
    ps.setString(1, file.getName());
    ps.setInt(2, oid);
    ps.executeUpdate();
    ps.close();
    fis.close();
    
    // Finally, commit the transaction.
    conn.commit();
    

    Retrieving the image from the Large Object:

    // All LargeObject API calls must be within a transaction block
    conn.setAutoCommit(false);
    
    // Get the Large Object Manager to perform operations with
    LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
    
    PreparedStatement ps = conn.prepareStatement("SELECT imgoid FROM imageslo WHERE imgname = ?");
    ps.setString(1, "myimage.gif");
    ResultSet rs = ps.executeQuery();
    while (rs.next()) {
        // Open the large object for reading
        int oid = rs.getInt(1);
        LargeObject obj = lobj.open(oid, LargeObjectManager.READ);
    
        // Read the data
        byte buf[] = new byte[obj.size()];
        obj.read(buf, 0, obj.size());
        // Do something with the data read here
    
        // Close the object
        obj.close();
    }
    rs.close();
    ps.close();
    
    // Finally, commit the transaction.
    conn.commit();
    
    0 讨论(0)
  • 2020-12-31 09:48

    I am adding complete code which may be useful for others (skipping try/catch),

    String base64EncryptedImage = new String(image);
    decoded = org.apache.commons.codec.binary.Base64.decodeBase64(base64EncryptedImage);
    ImageOutputStream out = new FileImageOutputStream(new File("D://abc.png"));
    out.write(decoded);
    out.close();
    
    0 讨论(0)
提交回复
热议问题