I have the following code using sqlite3 and java which runs without errors:
public class SqLiteDB {
public static void main(final String[] args) {
final SqLiteDB theDatabase = SqLiteDB.initSqLiteDB();
theDatabase.addParametersRow("test", "beam process");
theDatabase.addParametersRow("test", "beam process 1");
theDatabase.addParametersRow("test", "beam process 2");
theDatabase.addParametersRow("test1", "beam process 1");
theDatabase.addParametersRow("test1", "beam process 2");
theDatabase.addParametersRow("test2", "beam process");
theDatabase.addParametersRow("test2", "beam process 1");
theDatabase.addParametersRow("test3", "beam process");
theDatabase.addGroupStatements();
for (final Entry<String, String> result : theDatabase.getParametersAll().entrySet()) {
System.out.print(result.getKey() + ", " + result.getValue() + "\n");
}
}
private static final Logger LOGGER = LoggerFactory.getLogger(SqLiteDB.class);
private Connection dbConnection = null;
private static SqLiteDB myInstance = null;
// *****************************************************************************************************************
// Public methods
// *****************************************************************************************************************
public static SqLiteDB initSqLiteDB() {
if (myInstance == null) {
myInstance = new SqLiteDB();
}
return myInstance;
}
public void addParametersRow(final String parameterName, final String beamProcessName) {
final String sqlInsert = "INSERT INTO PARAMETERS (PARAMETER_NAME, BEAM_PROCESS) VALUES ('" + parameterName
+ "', '" + beamProcessName + "');";
try (Statement insertStatement = dbConnection.createStatement()) {
insertStatement.execute(sqlInsert);
} catch (final SQLException ex) {
ErrorLogger.logError(ex.getStackTrace(), ex);
}
}
public Map<String, String> getParametersAll() {
final String sqlGetParameterCount = "SELECT * FROM PARAMETERS";
final Map<String, String> queryResults = new TreeMap<>();
try (Statement queryParameterCount = dbConnection.createStatement()) {
final ResultSet resultSet = queryParameterCount.executeQuery(sqlGetParameterCount);
getClass();
while (resultSet.next()) {
queryResults.put(resultSet.getString(1), resultSet.getString(2));
}
resultSet.close();
} catch (final SQLException ex) {
ErrorLogger.logError(ex.getStackTrace(), ex);
}
return queryResults;
}
// *****************************************************************************************************************
// Private methods
// *****************************************************************************************************************
private SqLiteDB() {
try {
dbConnection = DriverManager.getConnection("jdbc:sqlite::memory:");
} catch (final SQLException ex) {
ErrorLogger.logError(ex.getStackTrace(), ex);
}
createTableAvailableParameters();
}
private void createTableAvailableParameters() {
if (dbConnection != null) {
final String sqlCreateTable = "CREATE TABLE IF NOT EXISTS PARAMETERS (\n"
+ " PARAMETER_NAME text NOT NULL, BEAM_PROCESS text NOT NULL, PRIMARY KEY (PARAMETER_NAME, BEAM_PROCESS));";
try (final Statement statement = dbConnection.createStatement()) {
statement.execute(sqlCreateTable);
} catch (final SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void addGroupStatements() {
final String sqlGetParameterCount = "SELECT PARAMETER_NAME, COUNT(PARAMETER_NAME) FROM PARAMETERS GROUP BY PARAMETER_NAME HAVING COUNT(PARAMETER_NAME) > 1";
final Map<String, Integer> queryResults = new HashMap<>();
try (Statement queryParameterCount = dbConnection.createStatement()) {
final ResultSet resultSet = queryParameterCount.executeQuery(sqlGetParameterCount);
getClass();
while (resultSet.next()) {
queryResults.put(resultSet.getString(1), resultSet.getInt(2));
}
resultSet.close();
} catch (final SQLException ex) {
ErrorLogger.logError(ex.getStackTrace(), ex);
}
for (final Entry<String, Integer> resultRow : queryResults.entrySet()) {
if (resultRow.getValue() > 1) {
addParametersRow(resultRow.getKey(), "*");
}
}
}
}
When I run the code it produces the following output:
test, *
test1, *
test2, *
test3, beam process
I do not understand where my rows with "test(1,2), beam process(1,2)" are? Why / where are they lost?
Stackoverflow does not accept post with a lot of code. I wouldn't know how to truncate the code without omitting details which might be necessary. That's why I have to put in some more useless text. I hope it helps to make the question postable.
The loss happens in the function getParametersAll(). In this function, you iterate over the available results and add them to a Map. However, if duplicate values occur, you override the already read results in the map. Thus, you only get the last created beam process for each of the parameters.
One way to solve this would be to create a Map<String, List<String>> and return this map instead.
Map<String, List<String>> queryResults = new TreeMap<>();
while (resultSet.next()) {
if (!queryResults.contains(resultSet.getString(1)) {
queryResults.put(resultSet.getString(1), new ArrayList<>());
}
queryResults.get(resultSet.getString(1)).add(resultSet.getString(2));
}
I hope, this answers your question, otherwise I have probably misunderstood your problem.
Based on Illedhar's answer - thanks to that - I implemented the method getParametersAll using the Guava Multimap interface. Here the working code:
public Multimap<String, String> getParametersAll() {
final String sqlGetParameterCount = "SELECT * FROM PARAMETERS";
final Multimap<String, String> queryResults = ArrayListMultimap.create();
try (Statement queryParameterCount = dbConnection.createStatement()) {
final ResultSet resultSet = queryParameterCount.executeQuery(sqlGetParameterCount);
getClass();
while (resultSet.next()) {
queryResults.put(resultSet.getString(1), resultSet.getString(2));
}
resultSet.close();
} catch (final SQLException ex) {
ErrorLogger.logError(ex.getStackTrace(), ex);
}
return queryResults;
}
The output in the main method needs to be changed sightly too:
for (final Entry<String, String> result : theDatabase.getParametersAll().entries()) {
System.out.print(result.getKey() + ", " + result.getValue() + "\n");
}
For cudos please vote 1+ for Illedhar.
Related
I connect to Hive and get id's of my data from row of table. Problems does not happens, when I connect to hive, send request and get response. But when i get id's from ResultSet i get an exception: org.apache.thrift.transport.TTransportException: SASL authentication not complete. Why does this exception arise and what needs to be done to avoid it? Sorry for my bad english.
It's my subsidiary class to create hive connection and send requests:
public class HiveDataSearcher implements AutoCloseable {
private static final String hiveDriverName = "org.apache.hive.jdbc.HiveDriver";
static {
try {
Class.forName(hiveDriverName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private Connection hiveConnection;
private String tableName;
private String whereBody;
public HiveDataSearcher(String url, String login, String password) {
try {
hiveConnection = DriverManager.getConnection(url, login, password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
this.tableName = "";
this.whereBody = "";
}
public HiveDataSearcher(Connection hiveConnection) {
Objects.requireNonNull(hiveConnection, "hiveConnection");
this.hiveConnection = hiveConnection;
this.tableName = "";
this.whereBody = "";
}
public String getTableName() {
return tableName;
}
public HiveDataSearcher setTableName(String tableName) {
Objects.requireNonNull(tableName, "tableName");
this.tableName = tableName;
return this;
}
public String getWhereBody() {
return whereBody;
}
public HiveDataSearcher setWhereBody(String whereBody) {
Objects.requireNonNull(whereBody, "whereBody");
this.whereBody = whereBody;
return this;
}
public ResultSet select(String ... selectParams) {
return select(Arrays.asList(selectParams));
}
public ResultSet select(Iterable<String> selectParams) {
String request = prepareRequest(selectParams);
ResultSet response;
try {
response = hiveConnection
.createStatement()
.executeQuery(request);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return response;
}
private String prepareRequest(Iterable<String> selectParams) {
return new StringBuilder()
.append("select").append(' ').append(selectParamsToHiveFormat(selectParams)).append(' ')
.append("from").append(' ').append(tableName).append(' ')
.append("where").append(' ').append(whereBody)
.toString();
}
private String selectParamsToHiveFormat(Iterable<String> selectParams) {
StringBuilder formattedSelectParams = new StringBuilder();
for (String selectedParam : selectParams) {
formattedSelectParams.append('\'').append(selectedParam).append('\'').append(',');
}
if (formattedSelectParams.length() == 0) {
formattedSelectParams.append('*');
} else {
formattedSelectParams.deleteCharAt(formattedSelectParams.length() - 1);
}
return formattedSelectParams.toString();
}
public void close() {
if (hiveConnection != null) {
try {
hiveConnection.close();
} catch (SQLException e) {
//nothing to do, just close connection
} finally {
hiveConnection = null;
}
}
}
}
This is the code in which i connect to hive:
private static final String HIVE_URL = <hive url>;
private static final String HIVE_LOGIN = <hive login>;
private static final String HIVE_PASSWORD = <hive password>;
private static final String[] SEARCH_FIELDS = new String[] {"rowkey"};
private List<String> getIdsFromHive(String tableName, String whereBody) {
ResultSet hiveResponse;
try (HiveDataSearcher searcher = new HiveDataSearcher(HIVE_URL, HIVE_LOGIN, HIVE_PASSWORD)) {
hiveResponse = searcher
.setTableName(tableName)
.setWhereBody(whereBody)
.select(SEARCH_FIELDS);
}
List<String> ids = new ArrayList<>();
try {
while (hiveResponse.next()) { // in this place throw TTransportException
ids.add(hiveResponse.getString(SEARCH_FIELDS[0]));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return ids;
}
In my case, the reason for this exception is closed the connection before closed the statement. So I suggest you to check whether you has maintain the connection correctly.
Here is my code, wish it will inspire you something:
Wrong code, close connection before closing the statement:
Connection connection = null;
Statement statement = null;
try {
connection = HIVEUTILS.getConnection();
statement = connection.createStatement();
statement.execute("DROP TABLE IF EXISTS tbl1");
statement.execute("CREATE TABLE `tbl1` (`id` int)");
statement.execute("INSERT INTO tbl1 VALUES(1)");
}finally {
if (connection != null){
connection.close();
}
if (statement != null){
statement.close(); // exception occur here.
}
}
The correct order of closing is: close resultSet(if any) -> close statement -> close connection.
Connection connection = null;
Statement statement = null;
try {
connection = HIVEUTILS.getConnection();
statement = connection.createStatement();
statement.execute("DROP TABLE IF EXISTS tbl1");
statement.execute("CREATE TABLE `tbl1` (`id` int)");
statement.execute("INSERT INTO tbl1 VALUES(1)");
}finally {
if (statement != null){
statement.close(); // change the order
}
if (connection != null){
connection.close();
}
}
I have a topology in which I am trying to count word occurrences which are being generated by SimulatorSpout (not real Stream) and after that write to MySQL database table, the table scheme is very simple:
Field | Type | ...
ID | int(11) | Auto_icr
word | varchar(50) |
count | int(11) |
But I am facing weird problem(as I beforementioned)
I successfully submitted The Topology to my Storm Cluster which consists of 4 supervisors, and I can see the flow of the Topology in Storm Web UI
(no exceptions) but when I checked the MySQL table, to my surprise, the table is empty...
ANY COMMENTS, SUGGESTIONS ARE WELCOME...
Here are spouts and bolts:
public class MySQLConnection {
private static Connection conn = null;
private static String dbUrl = "jdbc:mysql://192.168.0.2:3306/test?";
private static String dbClass = "com.mysql.jdbc.Driver";
public static Connection getConnection() throws SQLException, ClassNotFoundException {
Class.forName(dbClass);
conn = DriverManager.getConnection(dbUrl, "root", "qwe123");
return conn;
}
}
============================= SentenceSpout ===============================
public class SentenceSpout extends BaseRichSpout{
private static final long serialVersionUID = 1L;
private boolean _completed = false;
private SpoutOutputCollector _collector;
private String [] sentences = {
"Obama delivered a powerfull speech against USA",
"I like cold beverages",
"RT http://www.turkeyairline.com Turkish Airlines has delayed some flights",
"don't have a cow man...",
"i don't think i like fleas"
};
private int index = 0;
public void open (Map config, TopologyContext context, SpoutOutputCollector collector) {
_collector = collector;
}
public void nextTuple () {
_collector.emit(new Values(sentences[index]));
index++;
if (index >= sentences.length) {
index = 0;
Utils.waitForSeconds(1);
}
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("sentence"));
}
public void ack(Object msgId) {
System.out.println("OK: " + msgId);
}
public void close() {}
public void fail(Object msgId) {
System.out.println("FAIL: " + msgId);
}
}
============================ SplitSentenceBolt ==============================
public class SplitSentenceBolt extends BaseRichBolt {
private static final long serialVersionUID = 1L;
private OutputCollector _collector;
public void prepare (Map config, TopologyContext context, OutputCollector collector) {
_collector = collector;
}
public void execute (Tuple tuple) {
String sentence = tuple.getStringByField("sentence");
String httpRegex = "((https?|ftp|telnet|gopher|file)):((//)|(\\\\))+[\\w\\d:##%/;$()~_?\\+-=\\\\\\.&]*";
sentence = sentence.replaceAll(httpRegex, "").replaceAll("RT", "").replaceAll("[.|,]", "");
String[] words = sentence.split(" ");
for (String word : words) {
if (!word.isEmpty())
_collector.emit(new Values(word.trim()));
}
_collector.ack(tuple);
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}
=========================== WordCountBolt =================================
public class WordCountBolt extends BaseRichBolt {
private static final long serialVersionUID = 1L;
private HashMap<String , Integer> counts = null;
private OutputCollector _collector;
private ResultSet resSet = null;
private Statement stmt = null;
private Connection _conn = null;
private String path = "/home/hduser/logOfStormTops/logger.txt";
String rLine = null;
public void prepare (Map config, TopologyContext context, OutputCollector collector) {
counts = new HashMap<String, Integer>();
_collector = collector;
}
public void execute (Tuple tuple) {
int insertResult = 0;
int updateResult = 0;
String word = tuple.getStringByField("word");
//----------------------------------------------------
if (!counts.containsKey(word)) {
counts.put(word, 1);
try {
insertResult = wordInsertIfNoExist(word);
if (insertResult == 1) {
_collector.ack(tuple);
} else {
_collector.fail(tuple);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
} else {
//-----------------------------------------------
counts.put(word, counts.get(word) + 1);
try {
// writing to db
updateResult = updateCountOfExistingWord(word);
if (updateResult == 1) {
_collector.ack(tuple);
} else {
_collector.fail(tuple);
}
// Writing to file
BufferedWriter buffer = new BufferedWriter(new FileWriter(path));
buffer.write("[ " + word + " : " + counts.get("word") + " ]");
buffer.newLine();
buffer.flush();
buffer.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("{word-" + word + " : count-" + counts.get(word) + "}");
}
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
// *****************************************************
public int wordInsertIfNoExist(String word) throws ClassNotFoundException, SQLException {
String query = "SELECT word FROM wordcount WHERE word=\"" + word + "\"";
String insert = "INSERT INTO wordcount (word, count) VALUES (\"" + word + "\", 1)";
_conn = MySQLConnection.getConnection();
stmt = _conn.createStatement();
resSet = stmt.executeQuery(query);
int res = 0;
if (!resSet.next()) {
res = stmt.executeUpdate(insert);
} else {
System.out.println("Yangi qiymatni kirityotrganda nimadir sodir bo'ldi");
}
resSet.close();
stmt.close();
_conn.close();
return res;
}
public int updateCountOfExistingWord(String word) throws ClassNotFoundException, SQLException {
String update = "UPDATE wordcount SET count=count+1 WHERE word=\"" + word + "\"";
_conn = MySQLConnection.getConnection();
stmt = _conn.createStatement();
int result = stmt.executeUpdate(update);
//System.out.println(word + "'s count has been updated (incremented)");
resSet.close();
stmt.close();
_conn.close();
return result;
}
}
========================= WordCountTopology ==============================
public class WordCountTopology {
private static final String SENTENCE_SPOUT_ID = "sentence-spout";
private static final String SPLIT_BOLT_ID = "split-bolt";
private static final String COUNT_BOLT_ID = "count-bolt";
private static final String TOPOLOGY_NAME = "NewWordCountTopology";
#SuppressWarnings("static-access")
public static void main(String[] args) throws AlreadyAliveException, InvalidTopologyException {
SentenceSpout spout = new SentenceSpout();
SplitSentenceBolt splitBolt = new SplitSentenceBolt();
WordCountBolt countBolt = new WordCountBolt();
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(SENTENCE_SPOUT_ID, spout, 2);
builder.setBolt(SPLIT_BOLT_ID, splitBolt, 4).shuffleGrouping(SENTENCE_SPOUT_ID);
builder.setBolt(COUNT_BOLT_ID, countBolt, 4).fieldsGrouping(SPLIT_BOLT_ID, new Fields("word"));
Config config = new Config();
config.setMaxSpoutPending(100);
config.setDebug(true);
StormSubmitter submitter = new StormSubmitter();
submitter.submitTopology(TOPOLOGY_NAME, config, builder.createTopology());
}
}
It is because the _collector.ack(tuple) is not being called when there is exception thrown. When there are too many pending tuple, spout will stop sending new tuples. Try throwing out RuntimeException instead of printStackTrace.
public class Model
{
public static Connection getConnection()
{
Connection conn = null;
try
{
Class.forName("oracle.jdbc.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "System", "system");
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch(SQLException e)
{
e.printStackTrace();
}
return conn;
}
public static class Cart
{
public String itmName="";
public int howmany=0;
public static long itmQty=0, itmID=0;
public double itmPrice=0.0, itmCost=0.0, totalSum=0.0;
}
public static ArrayList<Cart> getCartDatabase(String user) throws Exception
{
Connection conn = getConnection();
String sql = "select * from userCarts where userID = '" + user + "'";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rst = pstmt.executeQuery();
ArrayList<Cart> al = null;
Cart crt=null;
while(rst.next())
{
System.out.println("CPoint");
try
{
long p = rst.getLong("itemID");
crt.itmID = p; // This is the line thats creating the error
System.out.println(p + " is long! I guess...");
}
catch(NullPointerException e)
{
System.out.println("NPE Caught in Model");
}
System.out.println("CP 1 " + crt.itmID);
ArrayList<row> alr=null;
try
{
alr = Model.getStoreInventory();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("CP 2");
for(int i=0; i<alr.size(); i++)
{
crt.itmName = alr.get(i).itmName;
crt.itmPrice = alr.get(i).itmPrice;
crt.itmQty = alr.get(i).itmQty;
}
System.out.println("CP 3");
crt.howmany = rst.getInt("howmany");
crt.itmCost = crt.itmPrice*crt.howmany;
al.add(crt);
}
return al;
}
}
When I try to access this method of getCartFromDatabase, it gives a NullPointerException however I don't understand why it would do this. Moreover, I tried to make the class as a non static class too, but still it gave the same error:
"Possible deferencing Null Pointer"
Cart crt=null;
while(rst.next())
{
System.out.println("CPoint");
try
{
long p = rst.getLong("itemID");
crt.itmID = p; // This is the line thats creating the error
System.out.println(p + " is long! I guess...");
}
crt is null when you try to access crt.itemID. You have to assign it an instance first.
I think you may simply change the first line from the snippet to
Cart crt = new Cart();
I've ran into a problem of having to run a number of different queries on the DB (different return types, different number of columns, etc).
While writing that i started to wonder if there's a proper way of writing a helper function.
It seemed that it's really easy to write a function that returns a ResultSet.
However since it a) doesn't close connection b) doesn't close the result set it seems as a possibly working, but improper solution. Is there any place to dump in all results so that they can be returned safely.
(Only thing i could come up with, is just returning a 2D string array (after converting all data to strings) and then converting it all back)
EDIT : Sorry for not writing clear, was wondering if there's any way to just store the result of the query as is (don't need to modify it) without writing a separate method for every possible return type.
The idea behind a 2d string list is being able to store the query values as is.
Col1 Row1 | Col2 Row1 | Col3 Row1
Col1 Row2 | Col2 Row2 | Col3 Row2
EDIT 2 Thank you for replies, i guess i'll just write a small parser for it.
You shouldn't be returning resultSets, you should read the results from the resultset into some kind of container object. A ResultSet is a wrapper around a database cursor, it goes away when the connection closes. It's something you read from and close right away, not something you can pass around your application.
Look at how spring-jdbc does it. You implement a resultSetMapper that is passed to the method on the JdbcTemplate.
Several observations:
You don't need to use Spring to use spring-jdbc. However, I see very little value in reimplementing this stuff yourself.
It's not the job of the code that reads the ResultSet to open and close connections, that needs to be elsewhere.
I'd recommend looking at Spring JDBC. Don't write such a thing yourself. It's already been done, and quite well.
For example, I don't like your idea of returning a List of Strings. You lose a lot of info that way. I'd return a Map of Lists (column view) or List of Maps (row view).
If you must, here are some database utilities that would get you started.
package persistence;
import java.sql.*;
import java.util.*;
/**
* util.DatabaseUtils
* User: Michael
* Date: Aug 17, 2010
* Time: 7:58:02 PM
*/
public class DatabaseUtils {
/*
private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DEFAULT_URL = "jdbc:oracle:thin:#host:1521:database";
private static final String DEFAULT_USERNAME = "username";
private static final String DEFAULT_PASSWORD = "password";
*/
/*
private static final String DEFAULT_DRIVER = "org.postgresql.Driver";
private static final String DEFAULT_URL = "jdbc:postgresql://localhost:5432/party";
private static final String DEFAULT_USERNAME = "pgsuper";
private static final String DEFAULT_PASSWORD = "pgsuper";
*/
private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private static final String DEFAULT_URL = "jdbc:mysql://localhost:3306/party";
private static final String DEFAULT_USERNAME = "party";
private static final String DEFAULT_PASSWORD = "party";
public static void main(String[] args) {
long begTime = System.currentTimeMillis();
String driver = ((args.length > 0) ? args[0] : DEFAULT_DRIVER);
String url = ((args.length > 1) ? args[1] : DEFAULT_URL);
String username = ((args.length > 2) ? args[2] : DEFAULT_USERNAME);
String password = ((args.length > 3) ? args[3] : DEFAULT_PASSWORD);
Connection connection = null;
try {
connection = createConnection(driver, url, username, password);
DatabaseMetaData meta = connection.getMetaData();
System.out.println(meta.getDatabaseProductName());
System.out.println(meta.getDatabaseProductVersion());
String sqlQuery = "SELECT PERSON_ID, FIRST_NAME, LAST_NAME FROM PERSON ORDER BY LAST_NAME";
System.out.println("before insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
connection.setAutoCommit(false);
String sqlUpdate = "INSERT INTO PERSON(FIRST_NAME, LAST_NAME) VALUES(?,?)";
List parameters = Arrays.asList("Foo", "Bar");
int numRowsUpdated = update(connection, sqlUpdate, parameters);
connection.commit();
System.out.println("# rows inserted: " + numRowsUpdated);
System.out.println("after insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
} catch (Exception e) {
rollback(connection);
e.printStackTrace();
} finally {
close(connection);
long endTime = System.currentTimeMillis();
System.out.println("wall time: " + (endTime - begTime) + " ms");
}
}
public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
Class.forName(driver);
if ((username == null) || (password == null) || (username.trim().length() == 0) || (password.trim().length() == 0)) {
return DriverManager.getConnection(url);
} else {
return DriverManager.getConnection(url, username, password);
}
}
public static void close(Connection connection) {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement st) {
try {
if (st != null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(Connection connection) {
try {
if (connection != null) {
connection.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static List<Map<String, Object>> map(ResultSet rs) throws SQLException {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
try {
if (rs != null) {
ResultSetMetaData meta = rs.getMetaData();
int numColumns = meta.getColumnCount();
while (rs.next()) {
Map<String, Object> row = new HashMap<String, Object>();
for (int i = 1; i <= numColumns; ++i) {
String name = meta.getColumnName(i);
Object value = rs.getObject(i);
row.put(name, value);
}
results.add(row);
}
}
} finally {
close(rs);
}
return results;
}
public static List<Map<String, Object>> query(Connection connection, String sql, List<Object> parameters) throws SQLException {
List<Map<String, Object>> results = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement(sql);
int i = 0;
for (Object parameter : parameters) {
ps.setObject(++i, parameter);
}
rs = ps.executeQuery();
results = map(rs);
} finally {
close(rs);
close(ps);
}
return results;
}
public static int update(Connection connection, String sql, List<Object> parameters) throws SQLException {
int numRowsUpdated = 0;
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
int i = 0;
for (Object parameter : parameters) {
ps.setObject(++i, parameter);
}
numRowsUpdated = ps.executeUpdate();
} finally {
close(ps);
}
return numRowsUpdated;
}
}
You can write helper functions that parse a ResultSet and convert it into an ArrayList or an array or even the fields of an object. For instance, lets say you have a table of orders and then a query returns all of the rows of that table for a particular user (customer). We could then do something like this:
static List<Order> parseOrder(ResultSet rs) {
ArrayList<Order> orderList = new ArrayList<>();
while(rs.next() ) {
Order order = new Order();
order.setID(rs.getInt(1));
order.setCustomerID(rs.getInt(2));
order.setItemName(rs.getString(3));
orderList.add(order);
}
return orderList;
}
Simply turning the result set into an array of an array of Objects would be more general, but probably less useful.
I would leave it up to the calling function to close this ResultSet and possible the PreparedStatement (or Statement) and database connection.
I am trying to insert some rows in to a table... I am using postgressql-7.2.jar.
I get the following exception
org.postgresql.util.PSQLException: No results were returned by the query.
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:255)
I have already Googled and the possible reasons suggested are
Use executeUpdate() method or execute() method instead of executeQuery() method.
This could possibly be because of jar problem; try other versions of postgres jars.
In some places they save it could be because of heap space error.
I have tried all the three solutions but none of them work...
I am not pasting the code since I have just used statement.executeUpdate(queryString).
The insert statements load the data in to the table but still I get this error.
Can some one help me out in this?
What type of SQL statement are you trying to run with executeQuery()? It should not be an INSERT or UPDATE - these are not queries.
Without posting the actual SQL statement, code samples, or what the table looks like - it's pretty hard to actually help you with your problem. Without specifics all we can do is guess.
This code works perfectly for me running PostgreSQL 8.1 and its driver. Perhaps it can be a template for finding what's wrong with yours.
You need a single table named PERSON with columns PERSON_ID, FIRST_NAME, LAST_NAME. I made PERSON_ID the auto incremented primary key.
package persistence;
import java.sql.*;
import java.util.*;
public class DatabaseUtils
{
private static final String DEFAULT_DRIVER = "org.postgresql.Driver";
private static final String DEFAULT_URL = "jdbc:postgresql://localhost:5432/party";
private static final String DEFAULT_USERNAME = "pgsuper";
private static final String DEFAULT_PASSWORD = "pgsuper";
public static void main(String[] args)
{
String driver = ((args.length > 0) ? args[0] : DEFAULT_DRIVER);
String url = ((args.length > 1) ? args[1] : DEFAULT_URL);
String username = ((args.length > 2) ? args[2] : DEFAULT_USERNAME);
String password = ((args.length > 3) ? args[3] : DEFAULT_PASSWORD);
Connection connection = null;
try
{
connection = createConnection(driver, url, username, password);
DatabaseMetaData meta = connection.getMetaData();
System.out.println(meta.getDatabaseProductName());
System.out.println(meta.getDatabaseProductVersion());
String sqlQuery = "SELECT PERSON_ID, FIRST_NAME, LAST_NAME FROM PERSON ORDER BY LAST_NAME";
System.out.println("before insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
connection.setAutoCommit(false);
String sqlUpdate = "INSERT INTO PERSON(FIRST_NAME, LAST_NAME) VALUES(?,?)";
List parameters = Arrays.asList( "Foo", "Bar" );
int numRowsUpdated = update(connection, sqlUpdate, parameters);
connection.commit();
System.out.println("# rows inserted: " + numRowsUpdated);
System.out.println("after insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
}
catch (Exception e)
{
rollback(connection);
e.printStackTrace();
}
finally
{
close(connection);
}
}
public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException
{
Class.forName(driver);
if ((username == null) || (password == null) || (username.trim().length() == 0) || (password.trim().length() == 0))
{
return DriverManager.getConnection(url);
}
else
{
return DriverManager.getConnection(url, username, password);
}
}
public static void close(Connection connection)
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public static void close(Statement st)
{
try
{
if (st != null)
{
st.close();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public static void close(ResultSet rs)
{
try
{
if (rs != null)
{
rs.close();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public static void rollback(Connection connection)
{
try
{
if (connection != null)
{
connection.rollback();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public static List<Map<String, Object>> map(ResultSet rs) throws SQLException
{
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
try
{
if (rs != null)
{
ResultSetMetaData meta = rs.getMetaData();
int numColumns = meta.getColumnCount();
while (rs.next())
{
Map<String, Object> row = new HashMap<String, Object>();
for (int i = 1; i <= numColumns; ++i)
{
String name = meta.getColumnName(i);
Object value = rs.getObject(i);
row.put(name, value);
}
results.add(row);
}
}
}
finally
{
close(rs);
}
return results;
}
public static List<Map<String, Object>> query(Connection connection, String sql, List<Object> parameters) throws SQLException
{
List<Map<String, Object>> results = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
ps = connection.prepareStatement(sql);
int i = 0;
for (Object parameter : parameters)
{
ps.setObject(++i, parameter);
}
rs = ps.executeQuery();
results = map(rs);
}
finally
{
close(rs);
close(ps);
}
return results;
}
public static int update(Connection connection, String sql, List<Object> parameters) throws SQLException
{
int numRowsUpdated = 0;
PreparedStatement ps = null;
try
{
ps = connection.prepareStatement(sql);
int i = 0;
for (Object parameter : parameters)
{
ps.setObject(++i, parameter);
}
numRowsUpdated = ps.executeUpdate();
}
finally
{
close(ps);
}
return numRowsUpdated;
}
}
A statement inserting rows does not return any rows back as a result, as opposed to a SELECT.