Download BLOB data from MySQL database via Java - java

I've a little problem; when I trying to download data (picture,audio...) from Mysql database.I'm getting damaged file so the file size is 1kb.I've changed file extension just in case but always got same results.
Please can anyone help me?
I've tried with this code :
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DownloadFileFromDb {
public static void main(String[] args) {
final String host = "jdbc:mysql://localhost/onurDB";
final String user = "onur";
final String pass = "onurdb958";
String SQL = "SELECT FILENAME FROM `PIC_STORE` WHERE `ID`=?";
Connection conn = null;
java.sql.PreparedStatement smt = null;
InputStream input = null;
FileOutputStream output = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting...");
conn = DriverManager.getConnection(host, user, pass);
System.out.println("Connection successful..\nNow creating query...");
smt = conn.prepareStatement(SQL);
smt.setString(1, "4"); //in this row we have a png picture
rs = smt.executeQuery();
output = new FileOutputStream(new File("/Users/MacbookPro/Downloads/pic.png"));
System.out.println("Getting file please be patient..");
while (rs.next()) {
input = rs.getBinaryStream("FILENAME"); //get it from col name
int r = 0;
/*
*there I've tried with array but nothing changed..Like this :
* byte[] buffer = new byte[2048];
* int r = 0;
* while((r = input.read(buffer)) != -1){
* out.write(buffer,0,r);}
*/
while ((r = input.read()) != -1) {
output.write(r);
}
}
System.out.println("File writing complete !");
} catch (ClassNotFoundException e) {
System.err.println("Class not found!");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("Connection failed!");
e.printStackTrace();
} catch (FileNotFoundException e) {
System.err.println("File not found!");
e.printStackTrace();
} catch (IOException e) {
System.err.println("File writing error..!");
e.printStackTrace();
}finally {
if(rs != null){
try {
input.close();
output.flush();
output.close();
smt.close();
conn.close();
} catch (SQLException e) {
System.err.println("Connot close connecton!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
there is downloaded file : pic.png file size is 12 byte.
THANKS FOR ALL.

Solved :
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DownloadFileFromDb {
public static void main(String[] args) {
final String host = "jdbc:mysql://localhost/onurDB";
final String user = "onur";
final String pass = "onurdb958";
String SQL = "SELECT PICTURE FROM `PIC_STORE` WHERE `ID`=?"; //Here I mistakenly wrote 'FILANAME' here instead of a 'PICTURE'
Connection conn = null;
java.sql.PreparedStatement smt = null;
InputStream input = null;
FileOutputStream output = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting...");
conn = DriverManager.getConnection(host, user, pass);
System.out.println("Connection successful..\nNow creating query...");
smt = conn.prepareStatement(SQL);
smt.setString(1, "4"); //in this row we have a png picture
rs = smt.executeQuery();
output = new FileOutputStream(new File("/Users/MacbookPro/Downloads/pic.png"));
System.out.println("Getting file please be patient..");
while (rs.next()) {
input = rs.getBinaryStream("FILENAME"); //get it from col name
int r = 0;
while ((r = input.read()) != -1) {
output.write(r);
}
}
System.out.println("File writing complete !");
} catch (ClassNotFoundException e) {
System.err.println("Class not found!");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("Connection failed!");
e.printStackTrace();
} catch (FileNotFoundException e) {
System.err.println("File not found!");
e.printStackTrace();
} catch (IOException e) {
System.err.println("File writing error..!");
e.printStackTrace();
}finally {
if(rs != null){
try {
input.close();
output.flush();
output.close();
smt.close();
conn.close();
} catch (SQLException e) {
System.err.println("Connot close connecton!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

Related

Corrupted docx file getting created while reading data from blob

I am trying to read the binary data and create a file with extension also given by user, code is working fine for pdf but for docx file, files are getting created but I am not able to open it as files are being created as corrupted.
Please find below the required details -
Table Schema
CWSMAin.java -
package org.cws;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class CWSMain {
private static DriverManagerDataSource dataSource;
private static BlobDAO blobDAO;
public static void main(String[] args) {
dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/application");
dataSource.setUsername("root");
dataSource.setPassword("admin");
blobDAO = new BlobDAO(dataSource);
//int result = blobDAO.writeData("Resume_Anmol.pdf", "MyReume_Anmol.pdf");
blobDAO.readData(3);
}
}
BlobDAO.java -
package infy.cws;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import com.mysql.jdbc.Blob;
public class BlobDAO {
private JdbcTemplate jdbcTemplate;
public BlobDAO(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int writeData(String inputFile, String outputFile) {
String sql = "INSERT INTO CWSPOC (bdata, file_name) VALUES (?,?)";
File file = new File("C:\\" + inputFile);
try {
FileInputStream input = new FileInputStream(file);
return jdbcTemplate.update(sql, input, outputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return 0;
}
public boolean readData(int id) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection =
DriverManager.getConnection("jdbc:mysql://localhost:3306/application", "root",
"admin");
String sql = "SELECT * FROM CWSPOC WHERE id=?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String fName = rs.getString("file_name");
System.out.println("File Name is " + fName);
File file = new File("E:\\" + fName);
FileOutputStream output = new FileOutputStream(file);
InputStream input = rs.getBinaryStream("bdata");
byte[] buffer = new byte[1024];
while (input.read(buffer) > 0) {
output.write(buffer);
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
}
Please let me know the solution, thanks in advance!
Note - Need to create file with proper extension as inputs given by user.

I have a system.properties file present in WEB-INF/config folder. How to write a code for retrieving data from this file?

Below is my system.properties file:
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:#localhost:1521:xe
duser=kj
dpass=class234
Below is the java code where it is to be put:
AbstractDataAccessObject.java
package com.dts.core.dao;
import com.dts.core.util.LoggerManager;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class AbstractDataAccessObject
{
Connection con;
static Properties props;
public AbstractDataAccessObject() {}
public Properties getProperties()
{
return props;
}
public void setProperties(Properties props)
{
AbstractDataAccessObject.props = props;
}
public Connection getConnection()
{
try {
Properties p = getProperties();
Class.forName(p.getProperty("driver"));
con = DriverManager.getConnection(p.getProperty("url"), p.getProperty("duser"), p.getProperty("dpass"));
}
catch (ClassNotFoundException cnf)
{
LoggerManager.writeLogWarning(cnf);
}
catch (SQLException se)
{
LoggerManager.writeLogWarning(se);
}
return con;
}
public int getSequenceID(String tableName, String pkid)
{
int id = 0;
try
{
con = getConnection();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select max(" + pkid + ") from " + tableName);
if (rs.next())
id = rs.getInt(1);
id++;
}
catch (SQLException se)
{
LoggerManager.writeLogWarning(se);
try
{
con.close();
}
catch (SQLException se1)
{
LoggerManager.writeLogWarning(se1);
}
catch (Exception e)
{
LoggerManager.writeLogWarning(e);
}
}
catch (Exception e)
{
LoggerManager.writeLogWarning(e);
try
{
con.close();
}
catch (SQLException se)
{
LoggerManager.writeLogWarning(se);
}
catch (Exception e1)
{
LoggerManager.writeLogWarning(e1);
}
}
finally
{
try
{
con.close();
}
catch (SQLException se)
{
LoggerManager.writeLogWarning(se);
}
catch (Exception e)
{
LoggerManager.writeLogWarning(e);
}
}
return id;
}
}
Please help me to connect my database through system.properties file and also where should I keep the properties file?
Before use properties which is actually define into properties file , first need to load it,
java.util.Properties properties = new java.util.Properties();
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath);
//load to property file to system...
properties.load(inputStream);
// now, it's ready to use,
properties.getProperty("driver"); // get driver from properties file if is there otherwise gives null...
EDITED :-
public static void main(String... s){
Properties prop = new Properties();
InputStream input = null;
try {
String filename = "app.properties";
input = AbstractDataAccessObject.class.getClassLoader().getResourceAsStream(filename);
if(input==null){
System.out.println("Sorry, unable to find " + filename);
return;
}
//load a properties file from class path, inside static method
prop.load(input);
//get the property value and print it out
System.out.println(prop.getProperty("driver")); // gives, oracle.jdbc.driver.OracleDriver
System.out.println(prop.getProperty("duser")); // gives, kj
System.out.println(prop.getProperty("dpass")); // gives, class234
} catch (IOException ex) {
ex.printStackTrace();
}
}
See properties put into resources directory, so that .properties file comes on classpath.

WARNING: executing transaction with 0 enlisted resource: Bitronix

I am getting this warning "executing transaction with 0 enlisted resource" while executing a distributed transaction with Bitronix into two datasources. Can some one help to understand how to enlist resources to global transaction. My code is:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import bitronix.tm.BitronixTransactionManager;
import bitronix.tm.TransactionManagerServices;
public class TestMain {
public static void main(String[] args) {
new TestMain().TestDT();
}
private void TestDT(){
DataSource dataSourceRemote = ConnectionManager.getDatasourceRemote();
DataSource dataSourceLocal = ConnectionManager.getDatasourceLocal();
Connection con, conn = null;
try {
/*String remoteDS = "remoteDS";
String localDS = "localDS";
InitialContext ctxRemote = new InitialContext();
ctxRemote.bind(remoteDS, dataSourceRemote);*/
String INSERT_QUERY = "insert emp values (?,?,?,?)";
/*InitialContext ctxLocal = new InitialContext();
ctxLocal.bind(localDS, dataSourceLocal);*/
BitronixTransactionManager btx = TransactionManagerServices.getTransactionManager();
//DataSource dsRemote = null;
//btx.ge
//UserTransaction us =
try {
btx.begin();
//DataSource dsRemote = (DataSource) ctxRemote.lookup(remoteDS);
con = dataSourceRemote.getConnection();
//con.setAutoCommit(false);
PreparedStatement pstmt = con.prepareStatement(INSERT_QUERY);
for(int i=1; i<=5; i++){
pstmt.setInt(1, i);
pstmt.setString(2, "Sanjay_"+i);
pstmt.setString(3, "123"+i);
pstmt.setString(4, "1000"+i);
pstmt.execute();
}
//DataSource dsLocal = (DataSource) ctxLocal.lookup(localDS);
conn = dataSourceLocal.getConnection();
//conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement(INSERT_QUERY);
for(int i=1; i<=5; i++){
ps.setInt(1, i);
ps.setString(2, "Nikhil_"+i);
ps.setString(3, "123"+i);
ps.setString(4, "1000"+i);
ps.execute();
}
btx.commit();
con.close();
conn.close();
} catch (NotSupportedException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
}catch (SQLException e) {
try{
btx.rollback();
}catch (Exception ex) {
ex.printStackTrace();
}
e.printStackTrace();
}catch (HeuristicRollbackException e) {
try{
btx.rollback();
}catch (Exception ex) {
ex.printStackTrace();
}
e.printStackTrace();
}catch (HeuristicMixedException e) {
try{
btx.rollback();
}catch (Exception ex) {
ex.printStackTrace();
}
e.printStackTrace();
}catch (RollbackException e) {
try{
btx.rollback();
}catch (Exception ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally{
//try{
btx.shutdown();
//con.close();
//conn.close();
/*}catch (Exception e) {
e.printStackTrace();
}*/
}
//btx.getTransaction()
}catch (Exception e) {
e.printStackTrace();
}
}
}
"executing transaction with 0 enlisted resource" simply means that your data-sources are not mapped with Bitronix transaction manager.

How to store the fetched MySQL data into Optaplanner-examples

I have created a MySQL database with entries similar to nurse roster, i have generated these entries to be in XML format using below code.
package com.jdbcxml;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.w3c.dom.Document;
class EmployeeDAO
{
private Connection conn = null;
static
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public EmployeeDAO()
{
String url = "jdbc:mysql://50.62.23.184:3306/dbname";
String userId = "root";
String passWord = "";
try
{
conn = DriverManager.getConnection(url, userId, passWord);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void finalize()
{
try
{
conn.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public Document getCustomerList()
{
Document doc = null;
try
{
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * from t7_users");
doc = JDBCUtil.toDocument(rs);
rs.close();
stmt.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return doc;
}
public String getCustomerListAsString()
{
String xml = null;
try
{
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * from t7_users");
xml = JDBCUtil.toXML(rs);
rs.close();
stmt.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return xml;
}
public static void main(String argv[]) throws Exception
{
EmployeeDAO dao = new EmployeeDAO();
String xml = dao.getCustomerListAsString();
System.out.println(xml);
Document doc = dao.getCustomerList();
System.out.println(doc);
//PrintWriter out = new PrintWriter(new FileWriter("output.txt"));
//out.write(doc);;
//out.close();
}
}
Now i need this data to be saved in Optaplanner-examples-->data-->nurserostering-->unsolved folder.
Also after doing this will the optaplanner be able to write a solution to the passed data to some file so that i can display those results on my webpage.
Why you storing the data you get from database to xml file? It will be more efficiently feed the data to optaplanner solver and get the best solution. Read my answer from your previous question HERE

MySQL JDBC returning 0 results

It seems a very basic question but I couldn't find any resolution for it.
I have following code with me:
package com.test.db.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCConnect
{
private Connection conn = null;
private final String uname = "root";
private final String passwd = "test#123";
private String url = "jdbc:mysql://127.0.0.1:3306/TrainDB";
private final String className = "com.mysql.jdbc.Driver";
public void initConnection()
{
try
{
if(this.conn == null || this.conn.isClosed())
{
try
{
Class.forName (className).newInstance ();
this.conn = DriverManager.getConnection(url, uname, passwd);
System.out.println("database connection established.");
}
catch(SQLException sqe)
{
sqe.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
catch(SQLException sqle)
{
sqle.printStackTrace();
}
//return this.conn;
}
public void disconnect()
{
if (conn != null)
{
try
{
conn.close ();
System.out.println ("Database connection terminated");
}
catch (Exception e) { /* ignore close errors */ }
}
}
public void insertData(String sql)
{
PreparedStatement s;
try
{
if(conn == null || conn.isClosed())
{
initConnection();
}
s = conn.prepareStatement(sql);
int count = s.executeUpdate ();
s.close ();
System.out.println (count + " rows were inserted");
}
catch (SQLException e)
{
e.printStackTrace();
if (conn != null)
{
try
{
conn.close ();
System.out.println ("Database connection terminated");
}
catch (Exception se) { /* ignore close errors */ }
}
}
}
public ResultSet query(String sql)
{
Statement s = null;
try
{
if(this.conn == null || this.conn.isClosed())
{
initConnection();
}
s = conn.createStatement();
s.executeQuery(sql);
ResultSet rs = s.getResultSet();
System.out.println("lets see " + rs.getFetchSize());
return rs;
}
catch(SQLException sq)
{
System.out.println("Error in query");
return null;
}
finally
{
try {
s.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I am using JDBCConnect in a different class:
import java.sql.ResultSet;
import java.sql.SQLException;
public class traininfo
{
public static void main(String[] args)
{
JDBCConnect jdbcConn = new JDBCConnect();
String sql = "SELECT id FROM testtable";
ResultSet rs = jdbcConn.query(sql);
try {
System.out.println(rs.getFetchSize());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(rs != null)
{
try
{
while(rs.next())
{
System.out.println(rs.getString("id"));
}
rs.close();
}
catch(SQLException sqe)
{
}
}
jdbcConn.disconnect();
}
}
I am not using concurrent calls for insertion and reads. If I use the same query in mysql-workbench (client), I am getting proper results but using the mentioned code, I am getting
database connection established.
lets see 0
0
Database connection terminated
Please suggest me what I am missing?
Most probably it's because you're closing Statement before you are using it's ResultSet. It's strange that it doesn't throw an exception, but this is not correct anyway.
As per Statement.close method JavaDoc:
When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
I suggest to use some kind of callback to retrieve results from ResultSet before it's closed e.g.:
public <T> T query(String sql, IResultSetHandler<T> resultSetHandler ) throws SQLException {
Statement statement = null;
try {
statement = connection.createStatement();
final ResultSet rs = connection.executeQuery(sql);
final T result = resultSetHandler.handle(rs);
return result;
} finally {
if(statement != null) {
statement.close();
}
}
}
public interface IResultSetHandler<T> {
T handle(ResultSet rs);
}
public static void main(String[] args) {
JDBCConnect jdbcConn = new JDBCConnect();
List<String> ids = jdbcConn.query(sql, new IResultSetHandler<List<String>>() {
public List<String> handle(ResultSet rs) {
List<String> ids = new ArrayList<String>();
while(rs.next()) {
ids.add(rs.getString("id"));
}
return ids;
}
});
}
Or to use commons apache dbutils library which does exactly the same.
ResultSet.getFetchSize() lets you know the maximum number of rows that the connection will fetch at once. You can set it with ResultSet.setFetchSize(int). See also the official documentation. It does not tell you how many rows in total you will get. If the fetch size is left to zero, JDBC decides on its own.
Other than that, refer to Yura's answer which addresses the core of your problem.
Could it be because you never call InsertRows, as it never shows that 'X rows were inserted'

Categories