# Image in Datenbank speichern



## 5474n (26. Mrz 2012)

Hallo,
ich programmiere gerade ein Servlet und habe hierfür auch eine Datenbank-Anbindung.
Ich möchte jetzt, Bilder, die via einem File-Upload, ausgewählt wurden, in eine Datenbank schreiben.
Ich habe keine Ahnung wie ich das angehen soll, bzw was ich dafür brauche. 
Google spuckt mir aus das ich ein BLOB nutzen soll, doch habe ich keine Ahnung wie ich nun das Bild in die DB speichern soll. 

nutze eine Oracle DB

Danke und Gruß


----------



## VfL_Freak (26. Mrz 2012)

Moin,

BLOB ist schon richtig - das kennt auch Oracle 

Schau' mal hier:
Binary Large Object ? Wikipedia
BLOB - Oracle FAQ

oder verfeinere bitte die Frage ....

Gruß
Klaus


----------



## 5474n (26. Mrz 2012)

Oracle kennt BLOB. 
habe eine Spalte eingefügt und vorest mit EMPTY_BLOB(); gefüllt,
BLOB - Oracle FAQ
mit dem "load an external file" komme ich nun nicht klar. kann mir das jemand vllt kommentieren was in welchem Schritt gemacht wird, das ich das ganze kapiere.


----------



## 5474n (26. Mrz 2012)

Funktion zum speichern habe ich so gelöst:

```
Connection dbCon = null;
				dbCon = hE.getConnection();
				String sFilePathAndName = getServletContext().getRealPath(fileName);
			  File              fl    = new File( sFilePathAndName );
			  FileInputStream   fis   = new FileInputStream( fl );
			  PreparedStatement pstmt = dbCon.prepareStatement(
			                            "update sh_regal set Image = ?");
			  pstmt.setBinaryStream( 1, fis, (int)fl.length() );
			 
			  pstmt.executeUpdate();
			  pstmt.close();
			  dbCon.close();
			  fis.close();
```

in der Datenbank wird auch angezeigt, das ein Blob vorhanden wäre.
Kann ich das nun ausgeben um es zu kontrollieren? oder wie schaue ich am besten nach ob alles richtig gespeichert wurde?

Die Ausgabe versuche ich so zu lösen:


```
PrintWriter out = response.getWriter();
		
		Connection connect = null; //Verbindung erstellt und als null intialisiert
		Statement statm = null; //Aussage objekt
		ResultSet res = null; //Ergebnis Obejekt wird erstellt

		try
		{
			connect = hE.getConnection(); 
			statm = connect.createStatement(); 

			String sql = "SELECT fach,image FROM sh_regal order by fach "; 
			res = statm.executeQuery(sql); 
			
			while (res.next())
			{
				
				Blob bild = null;
				bild= res.getBlob("IMAGE");
				
				
				bild.getBinaryStream();
				InputStream IS = null;
				IS = bild.getBinaryStream();
				byte[] array = IOUtils.toByteArray(IS, bild.length());
				
				
			}
		}catch (ClassNotFoundException e)
		{
			hE.handleException(request, response, e);
		}
		catch (SQLException e)
		{
			hE.handleException(request, response, e);
		}
		finally
		{
			hE.closeConnection(request, response, connect, statm, res);
			
			
		}
```

geht das? 
und wie kann ich das ganze nun ausgeben lassen?


----------



## turtle (26. Mrz 2012)

Ich würde zum Test mir das gelesene Bild als Datei ablegen und mir anschauen:

```
ImageIO.write(...);
```


----------



## 5474n (26. Mrz 2012)

lasse die Datei nun local zwischenspeichern (jedoch mit einem FileOutputStream).
wird richtig angezeigt.


----------



## 5474n (26. Mrz 2012)

Wenn ich die Bilder nun anzeigen möchte, muss ich diese dafür aus der Datenbank laden, in mein Root-Verzeichnis des Tomcat kopieren und über den Pfad ausgeben lassen 
oder gibt es eine Möglichkeit mein Byte-Array direkt als Bild ausgeben zu lassen auf dem Servlet (was mir persönlich lieber wäre)?


----------



## nocturne (26. Mrz 2012)

Also hier meine Richfaces lösung:

```
public class ImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * Recivies an image from database, depend on the DiaPictureID.
	 * 
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		ServletOutputStream os = response.getOutputStream();
		HttpSession session = request.getSession();

		if (request.getParameter("DiaPictureID") != null) {
			int diaId = Integer.parseInt(request.getParameter("DiaPictureID"));

			Navigation n;
			if (session == null)
				n = new Navigation();
			else {
				n = (Navigation) session.getAttribute("nav");
			}

			if (n != null && n.getSession() != null) {
				
				DiaPicture pic = (DiaPicture) n.getSession().get(
						DiaPicture.class, diaId);
				response.setContentType(pic.getMimeFiletype());
				os.write(pic.getByteData());
			}
		} else
			os.write("Require DiaPictureID!".getBytes());

	}

}
```
 zum anzeigen und zu hochladen:

```
public void diaUploadListener(UploadEvent ue) throws IOException {

		UploadItem uploadItem = ue.getUploadItem();

		String contentType = new MimetypesFileTypeMap()
				.getContentType(uploadItem.getFileName());

		getDias().getSelected().setMimeFiletype(contentType);
		getDias().getSelected().setFilename(uploadItem.getFileName());
		getDias().getSelected().setByteData(
				FileUtils.getBytesFromFile(uploadItem.getFile()));
	}
```


----------



## 5474n (28. Mrz 2012)

so, Bilder lassen sich speichern und laden (direkt Streamen über InputStream)
Da ich jetzt mein Servlet auf einem anderen Server/Rechner ausprobieren will, 
will ich die Bilder aus der Datenbank ziehen und neu abspeichern.

```
while (res.next())
			{
				array = null;
				pfad = savePath(request, response);

				String typ = res.getString("TYP");
				String interpret = res.getString("Interpret");
				fach = res.getInt("FACH");
				String stitel = res.getString("TITEL");
				String kaufdatum = res.getString("KAUFDATUM");
				String genre = res.getString("GENRE");
				String path = res.getString("BILDPATH");
				bild = res.getBlob("IMAGE");

				
				
				String neuTitel = stitel.replace(" ", ".");
				String neuInt = interpret.replace(" ", ".");
				pfad =pfad+ fach+"-"+neuInt+"-"+neuTitel+".jpg";
				
				IS = bild.getBinaryStream();
				array = IOUtils.toByteArray(IS, bild.length());

				fos = new FileOutputStream(new File(pfad));
				fos.write(array);

				String neuPfad = this.infoPath(request, response) + pfad;
				this.saveDatabase(fach, typ, interpret, stitel, genre, kaufdatum, neuPfad);
				pfad = "";

			}
```

Ich bekomme keine Exception oder ähnliches nur wird mir ausschließlich das Letzte Bild das ich hochgeladen habe, immer wieder in den Ordner unter neuem Namen gespeichert. (Auch wenn das Bild nicht mehr in der DB ist) 

in meinem Finally Block 

```
finally
		{
			hE.closeConnection(request, response, connect, statm, res);
			IS = null;
			array = null;
 

		}
```
setze ich alles wieder null damit keine Überschneidung vorliegt.
warum wird nur das eine BIld gespeichert, wenn alle anderen Attribute richtig geladen werden?


----------



## mcShredder (29. Mrz 2012)

5474n hat gesagt.:


> Wenn ich die Bilder nun anzeigen möchte, muss ich diese dafür aus der Datenbank laden, in mein Root-Verzeichnis des Tomcat kopieren und über den Pfad ausgeben lassen
> oder gibt es eine Möglichkeit mein Byte-Array direkt als Bild ausgeben zu lassen auf dem Servlet (was mir persönlich lieber wäre)?



Du kannst im <img>-Tag als src dein Byte-Array direkt einfügen, allerdings dann BASE64 kodiert. Also so: 
	
	
	
	





```
<img src="data:image/(Dateityp, also png oder jpg);base64,(hier dann dein Base64-kodiertes Byte-Array)" />
```


----------



## 5474n (29. Mrz 2012)

mcShredder hat gesagt.:


> Du kannst im <img>-Tag als src dein Byte-Array direkt einfügen, allerdings dann BASE64 kodiert. Also so:
> 
> 
> 
> ...



das mit dem direkt anzeigen, habe ich über den InputStream gelöst

```
Blob bild = null;
			Image image = null;
			while (res.next())
			{
				bild = res.getBlob("IMAGE");
			}

			InputStream IS = null;
			IS = bild.getBinaryStream();

			image = ImageIO.read(IS);

			JFrame frame = new JFrame();
			JLabel label = new JLabel(new ImageIcon(image));
			frame.getContentPane().add(label, BorderLayout.CENTER);
			frame.pack();
			frame.setVisible(true);

			IS = null;
		}
```


----------



## 5474n (29. Mrz 2012)

Habe mein Problem, muss nochmal mein Upload kontrollieren, nach dem hochladen wird das richtige Bild zwar angezeigt, aber nach einem neuUpload werden alle überspeicher


----------

