How to read Blob data into String Object using Spring JDBCTemplate - java

I am trying to use Spring JDBCTemplate to read blob data from a table.
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
for(Map<String, Object> row:rows){
row.get("OPERATION_NAME");
row.get("REQUEST_MESSAGE"); // this is blob
}
How can I read blob into a Java String object?

This seemed to work fine -
LobHandler lobHandler = new DefaultLobHandler();
List<FrontendData> frontEndDataList = jdbcTemplate.query(getResponseQuery(sessionId), new RowMapper() {
#Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
// TODO Auto-generated method stub
FrontendData frontEndData = new FrontendData();
String operationName = rs.getString("OPERATION_NAME");
frontEndData.setApiName(operationName);
byte[] requestData = lobHandler.getBlobAsBytes(rs,"RESPONSE_MESSAGE");
frontEndData.setResponse(new String(requestData));
return frontEndData;
}});

You can try retrieving the blob from database as below.
String retrieveBlobAsString = null;
Blob b = row.get("REQUEST_MESSAGE");//cast with (Blob) if required. Blob from resultSet as rs.getBlob(index).
InputStream bis = b.getBinaryStream();
ObjectInputStream ois = new ObjectInputStream(bis);
retrieveBlobAsString = (String) ois.readObject();

Another approach is by using java.sql.ResultSet getBytes() to convert BLOB column to String object,
List<ModelClass> hulaList = jdbcTemplate.query(sql,
new RowMapper<ModelClass>() {
#Override
public ModelClass mapRow(ResultSet rs, int rowNum) throws SQLException {
ModelClass model = new ModelClass();
model.setOperationName(rs.getString("OPERATION_NAME"));
byte[] byteArr = rs.getBytes("REQUEST_MESSAGE");
model.setRequestMessage(new String(byteArr));
return model;
}
});

Java 8+ syntax:
List<MyObject> results = jdbcTemplate.query(
"SELECT x,y FROM ... ",
(rs, n) -> {
MyObject o = new MyObject();
o.setX(rs.getString("x"));
o.setY(rs.getBytes("y")); // <-- a BLOB
return o;
}
);
Or if you query only a BLOB:
List<byte[]> b = jdbc.query("SELECT y FROM ...", (rs, n) -> rs.getBytes(1));

Related

How to fetch database table column names in java

I need to display all the columns from the table in java. So far I have tried resultSet java object but it is not working for me
public class dbtest {
public static Session session = null;
public ArrayList < String > ColValue() throws IOException {
// TODO Auto-generated method stub
FileReader reader = new FileReader("Configuration\\Config.properties");
Properties p = new Properties();
p.load(reader);
String serverIp = p.getProperty("ServerIp");
String keyspace = p.getProperty("ServerPwd");
Cluster cluster = Cluster.builder().addContactPoints(serverIp).withCredentials("user", "password").build();
session = cluster.connect(server);
String query = null;
String cqlStatement = "select * from table_name";
ArrayList < String > casVal1 = new ArrayList < >();
for (Row row: session.execute(cqlStatement)) {
if (!casVal1.contains(query)) {
casVal1.add(query);
}
}
System.out.println(casVal1.size());
System.out.println(casVal1);
return (casVal1);
}
}
Need all the columns in results as outcomes.
You can get the column via the ResultSet.getColumnDefinitions Method
com.datastax.driver.core.ResultSet result = xxxxx;
for (Definition definition : result.getColumnDefinitions()) {
String name = definition.getName();
}

How to return a List in Apache Axis

On tomcat, I have a class that return a list of objects from the database, something like this:
List<Entity> list = null;
Connection con = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try {
con = Connector.getConexion();
String sql = "SELECT * FROM some_table LIMIT 10;";
pstm = con.prepareStatement(sql);
rs = pstm.executeQuery();
list = new ArrayList<>();
EntityCrimesChicago ecc = null;
while (rs.next()) {
e = new Entity();
e.setID(rs.getString(1));
e.setCase_Number(rs.getString(2));
list.add(e);
}
return list;
catch { ... }
finally { ... }
The entity and table have all fields as String/varchar, even the ID.
The service gets the list with (this is a web method):
public List<Entity> someThing(String q) {
DAOThings controller = new DAOThings();
List<Entity> things = controller.getSomeThings(Integer.parseInt(q));
return things;
}
This return
java.io.IOException: No serializer found for class Entity in registry org.apache.axis.encoding.TypeMappingDelegate#26a0e5e4
But, If I change the web method to return a String and I use return things.toString(); that return the objects, but doesn't the his content.
What can I do to return the list correctly?
I try returning a manueally added string list and works fine.
I solve my problem passing the object to a String array.
When I get the object list:
public List<Entity> someThing(String q) {
DAOThings controller = new DAOThings();
List<Entity> things = controller.getSomeThings(Integer.parseInt(q));
return things;
}
I only need to do this:
public List<String[]> someThing(String q) {
DAOThings controller = new DAOThings();
List<Entity> things = controller.getSomeThings(Integer.parseInt(q));
List<String[]> list = new ArrayList<>;
for (Entity value : things) {
String[] array = new String[obj_fields];
array[0] = value.getAny();
...
array[n] = value.getAny();
list.add(array);
}
return list;
}
And Apache Axis does the magic.

where is the error in this RowMapper

I have this Request SQL :
private List<IWsResponse> getBPartnerDetails(String valueNetwork, String reportLevel2) {
JdbcTemplate tm = new JdbcTemplate(ds.getDataSource());
StringBuffer sql = new StringBuffer("SELECT * FROM XRV_BPARTNERDETAILS order by BPartner_ID");
ArrayList<Object> params = new ArrayList<Object>();
response = tm.query(sql.toString(), new BPartnerMapper());
return response;
}
i create a new RowMapper (BPartnerMapper) like this
public class BPartnerMapper implements RowMapper<IWsResponse> {
#Override
public List<IWsResponse> mapRow(ResultSet rs, int rowNum) throws SQLException {
List<IWsResponse> bps = new ArrayList<IWsResponse>();
while (rs.next()) {
bp = new BPartner();
bp.setBPartnerValue(rs.getString("BPartnerValue"));
//adress
adr = new Adress();
adr.setBPartnerLocation_ID(BPartner_Location_ID);
bp.getAdress().add(adr);
//user
usr = new User();
usr.setUser_ID(User_ID);
bp.getUsers().add(usr);
bps.add(bp)
}
return bps;
}
the Class BPartner is
public class BPartner implements IWsResponse {
private String BPartnerValue;
private ArrayList<Adress> adress = new ArrayList<Adress>();
private ArrayList<User> users = new ArrayList<User>();
}
so i get this Error
The return type is incompatible with RowMapper<IWsResponse>.mapRow(ResultSet, int)
Take a look at the documentation. A row mapper maps objects for a single row.
This method should not call next() on the ResultSet; it is only supposed to map values of the current row.
So your return type should be IWsResponse rather than List. Additionally you must only map the current row. Not all of them.

Calling Oracle procedure that returns rows using SimpleJdbcCall in Spring

I have written the following code
MapSqlParameterSource in = new MapSqlParameterSource();
in.addValue("V_OPP_ID", bean.getOpportunityId());
in.addValue("V_NAME",bean.getName());
in.addValue("V_FROM_DATE", bean.getStdate());
in.addValue("V_TO_DATE", bean.getEddate());
in.addValue("V_USERTYPE", bean.getUserType());
jdbcCall.execute(in);
Here the jdbcCall.execute(in) returns me resultset/table corresponding to Arraylist. How do i extract this ArrayList
Is using jdbcCall a correct Approach ? If not what is Adviced ?
This is the code I use for a call to a function:
RowMapper<String> rm = new ParameterizedRowMapper<String>() {
#Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString(1);
}
};
myStoredProcedure = new SimpleJdbcCall(DataSourceConnection.getDataSource())
.withCatalogName("PACKAGE")
.withFunctionName("GET_ALIAS")
.returningResultSet("return", rm);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("P_ID",userStr);
params.addValue("P_DOMAIN_ALIAS", domain[0]);
List<String> list = myStoredProcedure.executeFunction(List.class,params);
and if you are not able to use the metadata then this is the code:
RowMapper<String> rm = new ParameterizedRowMapper<String>() {
#Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString(1);
}
};
SqlParameter emailParam = new SqlParameter("P_ID", OracleTypes.VARCHAR);
SqlParameter domainParam = new SqlParameter("P_DOMAIN_ALIAS", OracleTypes.VARCHAR);
SqlOutParameter resultParam = new SqlOutParameter("return", OracleTypes.CURSOR);
myStoredProcedure = new SimpleJdbcCall(DataSourceConnection.getDataSource())
.withCatalogName("PACKAGE")
.withFunctionName("GET_ALIAS")
.withoutProcedureColumnMetaDataAccess()
.returningResultSet("return", rm)
.declareParameters(resultParam, emailParam, domainParam);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("P_ID",userStr);
params.addValue("P_DOMAIN_ALIAS", domain[0]);
List<String> list = myStoredProcedure.executeFunction(List.class,params);

JdbcTemplate multiple result sets

I am trying to find an easy way to deal with Stored Procedures / SQL returning multiple result sets. I have been using the SimpleJdbcOperations#queryForList() method however this will only return the first result set as a List<Map<String, Object>>. I need to be able to get multiple result sets, ideally as a Collection of List<Map<String, Object>> or something. The program I am writing is a middleware component so I don't know what the SQL will be, or the form of the result set.
I think I have to use the JdbcOperations class which gives me access to more methods, including execute(CallableStatementCreator csc, CallableStatementCallback<T> action) but now I am stuck.
CallableStatementCallback<T> callback = new CallableStatementCallback<T>() {
#Override
public T doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException
{
boolean results = cs.execute(request);
while(results)
{
ResultSet result = cs.getResultSet();
results = cs.getMoreResults();
}
return null;
}
};
I am not really sure how to use the method though, or what to do with the ResultSet to get my generic List<Map<String, Object>>s.
I managed to get a Set<ResultSet> using this code,
private Set<ResultSet> executeProcedure(final String sql)
{
return jdbc.execute(new CallableStatementCreator() {
#Override
public CallableStatement createCallableStatement(Connection con) throws SQLException
{
return con.prepareCall(sql);
}
}, new CallableStatementCallback<Set<ResultSet>>() {
#Override
public Set<ResultSet> doInCallableStatement(CallableStatement cs) throws SQLException
{
Set<ResultSet> results = new HashSet<>();
boolean resultsAvailable = cs.execute();
while (resultsAvailable)
{
results.add(cs.getResultSet());
resultsAvailable = cs.getMoreResults();
}
return results;
}
});
}
Just going to look at translating a ResultSet into List<Map<String, Object>>.
You can use the resultSet.getMetaData() method to work out what columns are in the data:
ResultSetMetaData meta = resultSet.getMetaData();
int colcount = meta.getColumnCount();
for (int i = 1; i <= colcount; i++)
{
String name = meta.getColumnLabel(i); // This is the name of the column
int type = meta.getColumnType(i); // from java.sql.Types
// Maybe add to a Map,List, etc...
}
You can then do as the other commentors have mentioned do a loop through the ResultSet pulling out the data you need:
while (resultSet.hasNext())
{
resultSet.next();
// Find the columns you want to extract (via the above method maybe) and add to your row.
}
This code might be easier to use in most cases:
Map<String,Object> resultSets = new JdbcTemplate(dataSource)
.call(con -> con.prepareCall(query), new ArrayList<>());
I have used below method to get List of ResultSet in form of List<Map<String, Object>>
public List<List<Map<String, Object>>> executeProcedure(final String sql) {
return jdbcTemplate.execute(new CallableStatementCreator() {
#Override
public CallableStatement createCallableStatement(Connection con) throws SQLException {
return con.prepareCall(sql);
}
}, new CallableStatementCallback<List<List<Map<String, Object>>>>() {
#Override
public List<List<Map<String, Object>>> doInCallableStatement(CallableStatement cs) throws SQLException {
boolean resultsAvailable = cs.execute();
List<List<Map<String, Object>>> list = new ArrayList<List<Map<String, Object>>>();
while (resultsAvailable) {
ResultSet resultSet = cs.getResultSet();
List<Map<String, Object>> subList = new ArrayList<Map<String, Object>>();
while (resultSet.next()) {
ResultSetMetaData meta = resultSet.getMetaData();
int colcount = meta.getColumnCount();
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 1; i <= colcount; i++) {
String name = meta.getColumnLabel(i);
map.put(name, resultSet.getString(i));
}
subList.add(map);
}
list.add(subList);
resultsAvailable = cs.getMoreResults();
}
return list;
}
});
}

Categories