0

I have read numerous questions on StackOverFlow and other tutorials, that it is always better to store images in a file and then store their unique reference in a database. I am trying to do so but I ended up doing the following. I have created a Maven project and created a folder images under src/main/resources folder in which I have three images. Below is my code:

public class ImageHelper
{
    private static final String IMAGE_FILE = "/images/1984.jpg";

    Connection conn =null;
    Statement statement = null;
    PreparedStatement preparedStatement = null;
    int byteArrayLength =0;
    ConnectionClass newConnection = new ConnectionClass();
    InputStream imageStream = null;
    int imageFileLength;

    //Link reference http://stackoverflow.com/questions/13967307/reading-from-src-main-resources-gives-nullpointerexception
   //Link reference http://stackoverflow.com/questions/19916845/cant-access-to-files-in-resources-directory-with-maven-with-eclipse-ide

    public void getPath(){

        try
        {
            File imageFile = new File(this.getClass().getResource(IMAGE_FILE).toURI());
            //System.out.println("ImageFile is: "+ imageFile.toString()); //Output is the full path starting from C drive till the image
            imageFileLength = (int) imageFile.length();
            //System.out.println("Image File length : "+ imageFileLength);
            imageStream = new FileInputStream(imageFile);
            System.out.println("ImageStream is :"+ imageStream.read()); // Output is 255
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (URISyntaxException e)
        {
            e.printStackTrace();
        }

        //Now insert this image path in table bookInfo in imagePath column

        conn = newConnection.dbConnection();
        String insertImage = "Insert into bookInfo(availability,isbn,hardback,paperback,imagePath) values (?,?,?,?,?)";
        try
        {
            statement = conn.createStatement();
            preparedStatement = conn.prepareStatement(insertImage);
            preparedStatement.setString(1, "yes");
            preparedStatement.setInt(   2, 97815972);
            preparedStatement.setString(3, "hardback");
            preparedStatement.setString(4, "not paperback");
            preparedStatement.setBinaryStream(5, imageStream, imageFileLength);
            preparedStatement.executeUpdate();

        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }

    }
}

On executing this code, I was able to get a BLOB into database. I don't understand what does it mean by just storing reference of image path in database. Also, I have about 10 images in that folder. I need to get all of them inserted in the database. I think I am doing an extra step. I am first getting the image from the file "images" and then converting it to InputStream and storing it as BLOB in MySql. I am confused how should I go about approaching this problem. What should be the correct way of uploading image from a file to database. I am not asking user to upload anything, but just getting the image from database and displaying it to user on clicking of a link. Any help is appreciated. Thank You in advance.

user3044240
  • 621
  • 19
  • 33
  • The most popular method is, as you suggest, to store the image files themselves in the file system and store the path to those images in the database. In purely performance terms (so no other considerations), it can actually be more efficient to store small images (specifically, under 250k) as blobs within the database itself. Both methods are discussed *ad nauseam* elsewhere, so it seems inconceivable that there can be more to add to the subject here... But let's see... – Strawberry May 26 '15 at 00:20
  • Storing a "reference" or "link" to the file suggests that there is some other service available which actually allows clients to read the image. The "link" is a pointer to a location on a disk (where will depend on your setup, it could be contextual to the service which actually provides access to the image) and is simply a `String` value (path). The physical image is NOT stored in the database, but is stored in some central location accessible by the "link" in the database (this could be URL or a service specific path) – MadProgrammer May 26 '15 at 00:39
  • Thank you for replying. I want to do this so that I can on completion of this project, deploy it on cloud service like Amazon. Just fyi, I haven't worked with this kind of deployment. So will this method still work? Thanks. – user3044240 May 26 '15 at 03:34

1 Answers1

0

I'm not understanding what your question is.

You've read recommendations to use a pattern of not storing images as BLOBs in the database. Instead, store the images as files on a filesystem. To establish a "linkage" between the image file and a database row, we create a column like

 image_file_location  VARCHAR(255)

And then store in that column the file location, a character string representation of the location of the image file on the file system. Typically, that's relative location, relative to a directory specified in a configuration file.

 INSERT INTO mytable (..., image_file_location) VALUES (..., '/images/1984.jpg'); 

With that approach, there's no need to store the image (the contents of the image file) in a BLOB column in the database.

There are some downsides to this approach: the database isn't managing the image files. Those are going to need to be backed up separately from the database, and that backup may not be entirely consistent with the database.

Also, it's possible that some other process may rename or delete an image file, without updating the database. That will lead to an inconsistency, a row in the database referencing an image file that doesn't exist.

The benefits of this approach are a smaller database, and no need to muck with the programming for inserting/updating BLOB data.


But the code in your question doesn't appear to be following that pattern. The code appears to be loading the image (read from a file), and storing it in a BLOB column.

If you want to pull that image back out, you need to reverse the process you used to load the BLOB. Run the query, get the handle to the BLOB column, use a stream reader to "read" the contents of the BLOB.

And there's numerous examples of doing that.

Again, I'm not sure what question you are asking.

spencer7593
  • 106,611
  • 15
  • 112
  • 140