Inserting/Retrieving a file from Sybase - java

I am trying to insert a file containing into a Sybase database. I am using JConnect-7.0.7
Here is my table:
CREATE TABLE blob_test (
blobVar IMAGE
)
I am inserting the image using:
String sql = "INSERT INTO blob_test VALUES (convert(binary,?))";
PreparedStatement stmt = conn.prepareStatement(sql);
File image = new File(filePath);
InputStream fis = new FileInputStream(image);
int ilen=(int) image.length();
stmt.setBinaryStream(1, fis, ilen);
stmt.execute();
And trying to retrieve the image using:
JdbcTemplate jdbcTemplate= new JdbcTemplate(dataSource);
List<Blob> result = jdbcTemplate.query(
"SELECT blobVar FROM blob_test", new Object[] {}, new RowMapper() {
#Override
public Blob mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getBlob(1);
}
});
for(int i=0;i<result.size();i++){
Blob b = result.get(i);
BufferedOutputStream os;
os = new BufferedOutputStream(new FileOutputStream(new File("output"+i+".zip")));
os.write(b.getBytes(1, (int) b.length()));
os.flush();
os.close();
}
However, when I execute my code it outputs 1kb zip files that are corrupted. My code works exactly as it should for an oracle database.
Alternatively, I have also tried this code to retrieve the file:
JdbcTemplate jdbcTemplate= new JdbcTemplate(dataSource);
List<InputStream> result = jdbcTemplate.query(
"SELECT * FROM blob_test", new Object[] {}, new RowMapper() {
#Override
public InputStream mapRow(ResultSet rs, int rowNum) throws SQLException {
return lobHandler.getBlobAsBinaryStream(rs, 1);
}
});
for(int i=0;i<result.size();i++){
InputStream in = result.get(i);
OutputStream out = new FileOutputStream(new File("outputTest"+i+".zip"));
byte[] buff = new byte[4096];
int len = 0;
while ((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
out.flush();
out.close();
}
However, when I run this code I get an exception:
java.io.IOException: JZ0I9: This InputStream was closed.
at com.sybase.jdbc4.jdbc.ErrorMessage.raiseIOException(Unknown Source) at com.sybase.jdbc4.jdbc.ErrorMessage.raiseIOException(Unknown Source)
at com.sybase.jdbc4.jdbc.RawInputStream.checkMe(Unknown Source)
at com.sybase.jdbc4.jdbc.RawInputStream.read(Unknown Source)
at com.sybase.jdbc4.jdbc.RawInputStream.read(Unknown Source)
at blobtester.BlobTester.getOracleBlob(BlobTester.java:86)
at blobtester.BlobTester.main(BlobTester.java:34)
Again, this works for oracle. Is there anything I'm missing that is different about Sybase? Is the file being saved/retrieved correctly?
edit:
It turns out the problem was inserting the file into Sybase. I changed the code to:
File image = new File(filePath);
InputStream fis = new FileInputStream(image);
LobHandler lobHandler = new DefaultLobHandler();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("INSERT INTO blob_test VALUES (?)", new Object[] {new SqlLobValue(fis, (int)image.length(), lobHandler)}, new int[] {Types.BLOB});
And it worked for both Sybase and oracle. Thanks.

Code from this link worked: http://forum.spring.io/forum/spring-projects/data/9931-sybase-and-blob-storing
[Just adding an answer, to close the question.]

Related

java read arrayList<Integer> - objectInputStream EOFEXception

Hi i am trying to read an ArrayList of Integer and get EOFException.
i have a ArrayList of Question which is serialized and i do the same thing for reading it no problem, but with ArrayList Integer dont work.
i write the two ArrayList like so: (im ommiting all the other fields that are not relevant)
String sqlQuery = "insert into test values (?,?,?,?,?,?,?,?,?)";
PreparedStatement pst = null;
try {
if (DBConnector.myConn != null) {
pst = DBConnector.myConn.prepareStatement(sqlQuery);
// serialize object
Blob questionsBlob = DBConnector.myConn.createBlob();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(t.getQuestions());
oos.close();
Blob pointsBlob = DBConnector.myConn.createBlob();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ObjectOutputStream oos2 = new ObjectOutputStream(baos2);
oos.writeObject(t.getPointsPerQuestion());
oos2.close();
// store in byte array
byte[] questionsAsByte = baos.toByteArray();
byte[] pointsAsByte = baos2.toByteArray();
// fill blob object with byte array
questionsBlob.setBytes(1, questionsAsByte);
pointsBlob.setBytes(1, pointsAsByte);
pst.setBlob(3, questionsBlob);
pst.setBlob(4, pointsBlob);
pst.executeUpdate();
and read the objects:
String sqlQuery = "select * from test where teacherUsername = \"" + username + "\";";
ArrayList<Test> arr = new ArrayList<Test>();
ArrayList<Question> questions;
ArrayList<Integer> points;
try {
if (DBConnector.myConn != null) {
Statement st = DBConnector.myConn.createStatement();
ResultSet rs = st.executeQuery(sqlQuery);
while (rs.next()) {
questions = new ArrayList<>();
points = new ArrayList<>();
Blob questionsBlob = rs.getBlob(3);
BufferedInputStream bis = new BufferedInputStream(questionsBlob.getBinaryStream());
ObjectInputStream ois = new ObjectInputStream(bis);
questions = (ArrayList<Question>) ois.readObject();
System.out.println(questions);
Blob qPointsBlob = rs.getBlob(4);
BufferedInputStream bis1 = new BufferedInputStream(qPointsBlob.getBinaryStream());
ObjectInputStream ois1 = new ObjectInputStream(bis1);
try {
points = (ArrayList<Integer>) ois1.readObject(); // PROBLEM HERE
}catch(EOFException e) {
System.out.println(points);
}
when i try to read the data - it works with the ArrayList of Question and really shows me the questions, but with the ArrayList of Integer it gives me the EOFException.
any ideas ?

Connection Closed error on querying BLOBs from JdbcTemplate

I am querying a BLOB object from database and trying to write it in file system but I keep running into connection closed error. Here's the code
FileOutputStream out;
out = new FileOutputStream(filePathtoCreate+File.separator+filename);
Blob inBlob= jdbcTemplate.queryForObject("select BLOB_CONTENT from Table_A where name = ?" , Blob.class,new Object[] { filename});
InputStream in = inBlob.getBinaryStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (SQLException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
When I run this code I get
java.sql.SQLRecoverableException: Closed Connection
at oracle.sql.BLOB.getDBAccess(BLOB.java:1122)
at oracle.sql.BLOB.getBinaryStream(BLOB.java:265)
I do not get this issue if I go by regular JDBC Connection, so why is this happening and how do I resolve it. Thanks in advance.
You can read Blob inside jdbcTemplate's query with RowMapper, example:
jdbcTemplate.query("select * from Report where id =?",
new Object[]{id}, (resultSet, i) -> {
return toReport(resultSet);
});
private Report toReport(ResultSet resultSet) throws SQLException {
InputStream contentStream = resultSet.getClob("CONTENT")
.getAsciiStream();
String content =
new Scanner(contentStream, "UTF-8").useDelimiter("\\A").next();
report.setContent(content);
Blob blob = resultSet.getBlob("IMAGE");
Query given SQL to create a prepared statement from SQL and a list of arguments to bind to the query, mapping each row to a result object via a RowMapper.

Trying to insert image/xml file as blob in cassandra database

Actually I need to insert xml file in cassandra database. So initially am trying to insert image as a blob content later I change the code to insert xml but am facing issues in insert and retrieve the blob content as image. Can anyone suggest which is the best practice to insert image/xml file in cassandra database.
FileInputStream fis=new FileInputStream("C:/Users/anand.png");
byte[] b= new byte[fis.available()+1];
int length=b.length;
fis.read(b);
System.out.println(length);
ByteBuffer buffer =ByteBuffer.wrap(b);
PreparedStatement ps = session.prepare("insert into usersimage (firstname,lastname,age,email,city,length,image) values(?,?,?,?,?,?,?)");
BoundStatement boundStatement = new BoundStatement(ps);
int age=22;
//System.out.println(buffer);
session.execute( boundStatement.bind( "xxx","D",age,"xxx#gmail.com","xxx",length,buffer));
//session.execute( boundStatement.bind( buffer, "Andy", length));
PreparedStatement ps1 = session.prepare("select * from usersimage where email =?");
BoundStatement boundStatement1 = new BoundStatement(ps1);
ResultSet rs =session.execute(boundStatement1.bind("ramya1#gmail.com"));
ByteBuffer bImage=null;
for (Row row : rs) {
bImage = row.getBytes("image") ;
length=row.getInt("length");
}
byte image[]= new byte[length];
image=Bytes.getArray(bImage);
HttpServletResponse response = null;
#SuppressWarnings("null")
OutputStream out = response.getOutputStream();
response.setContentType("image/png");
response.setContentLength(image.length);
out.write(image);
Am facing issues while retrieving the blob content as image. could anyone please help me on this.
You are inserting data to an email and selecting from another;
A better way to read the bytes of an image would be:
BufferedImage originalImage = ImageIO.read(new File("C:/Users/anand.png"));
ByteArrayOutputStream imageStream = new ByteArrayOutputStream();
ImageIO.write(originalImage, "png", imageStream );
imageStream.flush();
byte[] imageInByte = imageStream.toByteArray();

Prevent downloaded files from replacing or overwriting each other

How to download all file types in MySQL database using Java app and prevent one file from replacing the other?
How can I include all file types in my filepath=("D:\\sch work\\skirt\\filename.pdf"); so that I am able to download pdf, docx, jpeg etc, from a MySQL database using Java mouse click event on a JTable?
I have two problems.
I can only open a PDF files although I want to open docs, JPEG and img files.
Every time I download another file from a different row it replaces the existing one. I would like to keep all of them
Below please find my code for mouse click event and please suggest what I should add for it to work as I need it.
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
String filePath =("D:\\sch work\\skirt\\filename.pdf");
int BUFFER_SIZE = 4096;
try {
int cert_code= jTable1.getSelectedRow();
String tableClick=(jTable1.getModel().getValueAt(cert_code,3).toString());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee_certificate","root","");
String sql= "SELECT cert FROM certificate WHERE cert_code =?" ;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, tableClick);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
Blob blob = rs.getBlob("cert");
InputStream inputStream = blob.getBinaryStream();
OutputStream outputStream = new FileOutputStream(filePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//JOptionPane.showMessageDialog(null,"file saved")
} }
catch (Exception e)
{JOptionPane.showMessageDialog(null,e);}
}
If you want something other than PDF, you should store what's in that cert blob, so you can send out the appropriate filename/type:
You get PDF because that's the exact+only file type you write out to:
String filePath =("D:\\sch work\\skirt\\filename.pdf");
^^^
Perhaps something more like (in pseudo-code):
select cert,filename,filetype from ...
filepath = 'd:\sch work\skirt' + filename
header('Content-type: ' + filetype);
here is my answer.God bless Marc B abundantly.
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
int BUFFER_SIZE = 4096;
try {
int cert_code= jTable1.getSelectedRow();
String tableClick=(jTable1.getModel().getValueAt(cert_code,3).toString());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee_certificate","root","");
String sql= "SELECT cert, cert_name FROM certificate WHERE cert_code =?" ;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, tableClick);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
String filename = rs.getString("cert_name");
Blob blob = rs.getBlob("cert");
InputStream inputStream = blob.getBinaryStream();
String filePath ="D:\\sch work\\skirt\\"+filename;
OutputStream outputStream = new FileOutputStream(filePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//JOptionPane.showMessageDialog(null,"file saved")
} }
catch (Exception e)
{JOptionPane.showMessageDialog(null,e);}
}

Saving an image in MySQL from Java

I am trying to save images in MySQL database from a Java swing application. I am using JFileChsoser to get the path of the image. Then after that converting the file so that it can be saved in the MySQL column which is of BLOB type. But every image I try to save does not save properly or get converted properly. Could someone tell me what I'm doing wrong over here?
private void btn_choosepicActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser picchooser = new JFileChooser();
picchooser.setDialogTitle("Select Image");
picchooser.showOpenDialog(null);
File pic=picchooser.getSelectedFile();
path= pic.getAbsolutePath();
txt_path.setText(path.replace('\\','/'));
try{
File image = new File(path);
FileInputStream fis = new FileInputStream(image);
ByteArrayOutputStream baos= new ByteArrayOutputStream();
byte[] buff = new byte[1024];
for(int readNum; (readNum=fis.read(buff)) !=-1 ; ){
baos.write(buff,0,readNum);
}
userimage=baos.toByteArray();
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
And then after this Im saving it to the database like so.
private void btn_saveActionPerformed(java.awt.event.ActionEvent evt) {
String user= txt_username.getText();
try{
String sql="insert into imgtst (username,image) values ('"+user+"','"+userimage+"')";
pst=con.prepareStatement(sql);
pst.executeUpdate();
JOptionPane.showMessageDialog(null, "Saved");
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
and I have declared the variable userimage and path as a global variables
String path=null;
byte[] userimage=null;
You are converting the byte[] to a String in your sql statement, and you will end up with incorrect data.
The right way to use a BLOB would be to pass the InputStream itself. You can use the FileInputStream you are using to read the file.
File image = new File(path);
FileInputStream fis = new FileInputStream ( image );
String sql="insert into imgtst (username,image) values (?, ?)";
pst=con.prepareStatement(sql);
pst.setString(1, user);
pst.setBinaryStream (2, fis, (int) file.length() );
When you retrieve it back you can similarly get an InputStream from the ResultSet:
InputStream imgStream = resultSet.getBinaryStream(2);

Categories

Resources