Hello!
First of all, I'm new to Java.
I'm trying to figure out what would be a good/handy way to work with DB from Java. I'm using c3p0 for connection pooling. Hibernate or other ORM is not an option this time, we decided to stick with "plain SQL" for now.
Currently basic retrieval of data looks like this:
private int getUserID(int sessionID, String userIP) {
int result = 0;
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
// Application.cpds is an instance of c3p0's ComboPooledDataSource
conn = Application.cpds.getConnection();
st = conn.prepareStatement("SELECT user_id, user_ip, is_timed_out FROM g_user.user_session WHERE id = ?");
st.setInt(1, sessionID);
rs = st.executeQuery();
if ( rs.next() ) {
if ( !rs.getBoolean("is_timed_out") && userIP.equals(rs.getString("user_ip")) ) {
result = rs.getInt("user_id");
}
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally {
if ( rs != null ) {
try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }
}
if ( st != null ) {
try { st.close(); } catch (SQLException e) { e.printStackTrace(); }
}
if ( conn != null ) {
try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
return result;
}
The code looks very long for such a basic operation. Another problem is that most of the code would have to be repeated in many places (declaring Connection, PreparedStatement, ResultSet, closing them, catching exceptions). Though, this is what I see in most examples when googling.
In PHP I would create a wrapper class that would have method select() that accepts 2 arguments (string)sqlQuery and (array)parameters and would return simple array of data. Wrapper class would also have few more specific methods, like:
- selectValue() for single value (e.g.,
select count(*) from user
) - selectRow() for single row (e.g.,
select name, surname from user where id = :user_id
) - selectColumn for single column (e.g.,
select distinct remote_address from user
)
Is anything like this practiced in Java? Or is there anything better / handier? Or should I use same style as in getUserID()
example above? As I said, ORM is not an option this time.
Thanks in advance :)
edit: Currently DBConnection
class is written. It gets connection from c3p0 connection pool in constructor. It has few public methods for working with DB: select()
for tabular data, selectValue()
for single value, selectRow()
and selectColumn()
for single row or column, as well as insert()
, update()
, delete()
and ddl()
. Methods accept String query, Object[] params
arguments, with params
being optional. insert()
, update()
and delete()
return Integer
which is result of PreparedStatement.executeUpdate()
. select
methods return different results:
ArrayCollection<HashMap<String, Object>> select()
Object selectValue()
HashMap<String, Object> selectRow()
ArrayCollection<Object> selectColumn()
The last problem is with compiler warnings - "warning: [unchecked] unchecked cast"
. This is because all methods call single private method that returns Object
and cast its result to mentioned types. As I am new to Java, I'm also not sure if I have chosen appropriate types for selects. Other than that, everything seems to work as expected.