how to get a ResultSet from an outside java class - java

I have a ResultSet object
ResultSet theInfo = stmt.executeQuery(sqlQuery);
but I want to have a function that can be called from another java class
public Vector loadStuff(){
try {
while (theInfo.next()){
aVector.addElement(new String(theInfo.getString("aColumn"))); // puts results into vectors
}
} catch (SQLException e) {
e.printStackTrace();
}
return aVector;
}
I'm not entirely sure how to go about this. I want to some how call a void method that returns a populated vector. is this possible?

Suppose you have a class Demo and it has method getVector follow the given approach.
class Demo {
public Vector getVector(ResultSet theInfo) {
if(theInfo==null){
throw new IllegalArgumentException("ResultSet is null");
}
Vector aVector = new Vector();
try {
while (theInfo.next()) {
aVector.addElement(new String(theInfo.getString("aColumn")));
}
} catch (SQLException e) {
e.printStackTrace();
}
return aVector;
}
}
Now call the getVector after the getting the ResultSet.
ResultSet theInfo = stmt.executeQuery(sqlQuery);
Demo demo =new Demo();
Vector vector=demo.getVetor(theInfo );

Related

SortedSet not adding new constructed objects from certain sql queried results data

The answer to the following described issue may be as simple as that I am not using SortedSet correctly, but I wouldn't know if that is the case.
void SQLRankGuildsByPoints(final CallbackReturnIntegerStringSortedSet callback)
{
java.sql.Connection cn = null;
try {
cn = DataSource.getConnection();
if(cn != null)
{
PreparedStatement query = cn.prepareStatement("SELECT GuildName, TotalActivityPoints FROM Guilds");
ResultSet result = query.executeQuery();
SortedSet<Pair_IntString> GuildsRanking = new TreeSet(new ComparatorGuildsRanking());
while(result.next())
{
int resultInt = result.getInt("TotalActivityPoints");
String resultString = result.getString("GuildName");
GuildsRanking.add(new Pair_IntString(resultInt, resultString));
}
Bukkit.getScheduler().runTask(MainClassAccess, new Runnable() { //Callback to main thread
#Override
public void run() {
callback.onDone(GuildsRanking);
}
});
}
} catch (SQLException e) {
System.err.print(e);
} finally {
try {
cn.close();
} catch (SQLException e) {
System.err.print(e);
}
}
}
All 8 results from the Guilds table are present in "result" ResultSet.
GuildsRanking.add() isn't adding the new custom Pair_IntString object constructed with the query results, specifically for guilds "test" and "lilo" in Guilds table.
SQLRankGuildsByPoints method finishes it's execution, calling back the GuildsRanking SortedSet without 2 of the iterated results.
This behaviour is unintended and I can't find an explanation for it.
The comparator used for TreeSet:
public class ComparatorGuildsRanking implements Comparator<Pair_IntString> {
#Override
public int compare(Pair_IntString intStr1, Pair_IntString intStr2) {
return intStr2.integer.compareTo(intStr1.integer);
}
}
Custom Pair_IntString class:
public class Pair_IntString {
public Integer integer;
public String string;
Pair_IntString(Integer i, String s)
{
integer = i;
string = s;
}
}
No error messages with the skipped add iterations.

requested operation is not supported in result sets

I need to display the data returned from a SQL SERVER stored procedure in a Jtable, and yet I have not been able to do it because it gives me the following error: the requested operation is not supported on forwarding-only result sets.
this is the code that I implemented:
try
{
CallableStatement mostararPacientesAusentes = conexionBBDD.getConexionBBDD()
.prepareCall("{call mostararPacientesAusentes()}");
ResultSet tabla = mostararPacientesAusentes.executeQuery();
AbstractTableModel mTN=new ModeloTabla(tabla);
ventanaNotificacion.getTabla().setModel(mTN);
ventanaNotificacion.getTabla().validate();
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage(), "BBDD", 2, null);
}
and this is the class that inherits AbstractTableModel
public class ModeloTabla extends AbstractTableModel {
private ResultSet tabla;
private ResultSetMetaData datosBBDD;
public ModeloTabla(ResultSet unResulset)
{
tabla=unResulset;
try
{
datosBBDD=tabla.getMetaData();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
try
{
tabla.absolute(rowIndex+1);
return tabla.getObject(columnIndex+1);
}
catch (SQLException e)
{
e.printStackTrace();
return null;
}
}
public String getColumnName(int c)
{
try
{
return datosBBDD.getColumnName(c+1);
}
catch (SQLException e) {
e.printStackTrace();
return null;
}
}
#Override
public int getRowCount() {
try {
tabla.last();
return tabla.getRow();
}
catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
#Override
public int getColumnCount()
{
try
{
return datosBBDD.getColumnCount();
}
catch (SQLException e)
{
e.printStackTrace();
}
return 0;
}
}
The titles of the columns of the table show it in the JTable, but the data does not.
I have already searched unsuccessfully for information to solve the problem.
Thank you very much.
Documentation of ResultSet:
... A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, you can iterate through it only once and only from the first row to the last row. It is possible to produce ResultSet objects that are scrollable and/or updatable. ...
There is a version of prepareCall() that accepts additional arguments to do that, like in:
...prepareCall("{call mostararPacientesAusentes()}",
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
Please check the documentation for other constants/types.
I am not sure if using a ResultSet to maintain the data is such a good idea - it is probably holding a lot of resources (connection, statement, ...) - IMHO better read the data once and save it in a list or similar structure; releasing the database resources ASAP.

Java: check if a class exists and call a specific method if it exists

Is there a way to do the following? Check if a class exists (in the same package) and if it does exist, check if a particular method exists, and if so, calling it?
Say that I have class X. In some method of class X, I want to do the following:
if (class Y exists) { //Maybe use Class.forName("Y")?
if ( Y has method a(String, String) ) {
call Y.a("hello", "world");
}
}
Is such a thing possible? And is doing such a thing reasonable? Thanks.
Is such a thing possible? And is doing such a thing reasonable?
Thanks.
Of course it is possible.
If you develop a program or a library that has to discover dynamically some classes, it is a very reasonable thing.
If it is not the case, it could not be.
If your need makes sense, you should ask you an additional question : should you invoke a static or instance method ?
Here is a sample example with both solutions :
ReflectionClass that contains the logic using reflection :
import java.lang.reflect.Method;
public class ReflectionCalls {
public static void main(String[] args) {
new ReflectionCalls();
}
public ReflectionCalls() {
callMethod(true);
callMethod(false);
}
private void callMethod(boolean isInstanceMethod) {
String className = "DiscoveredClass";
String staticMethodName = "methodStatic";
String instanceMethodName = "methodInstance";
Class<?>[] formalParameters = { int.class, String.class };
Object[] effectiveParameters = new Object[] { 5, "hello" };
String packageName = getClass().getPackage().getName();
try {
Class<?> clazz = Class.forName(packageName + "." + className);
if (!isInstanceMethod) {
Method method = clazz.getMethod(staticMethodName, formalParameters);
method.invoke(null, effectiveParameters);
}
else {
Method method = clazz.getMethod(instanceMethodName, formalParameters);
Object newInstance = clazz.newInstance();
method.invoke(newInstance, effectiveParameters);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
DiscoveredClass (the class we manipulate in the example)
package reflectionexp;
public class DiscoveredClass {
public static void methodStatic(int x, String string) {
System.out.println("static method with " + x + " and " + string);
}
public void methodInstance(int x, String string) {
System.out.println("instance method with " + x + " and " + string);
}
}
Output :
instance method with 5 and hello
static method with 5 and hello
Yes, this can be done. I've created a Test class in the same Package as the current class.
import java.lang.reflect.Method;
public class Sample {
public static void main(String[] args) {
Class<?> clazz = null;
try {
clazz = Class.forName("Test");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (clazz == null) {
System.out.println("class not found. Go eat some waffles and correct the name");
return;
}
Method m = null;
try {
m = clazz.getMethod("foo", null);
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (m == null) {
System.out.println("method not found. Go eat some waffles and correct the name");
return;
}
Test t;
try {
t = (Test) clazz.newInstance();
m.invoke(t, null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Test {
static {
System.out.println("test...");
}
public void foo() {
System.out.println("foo");
}
}
O/P :
test...
foo
You can use Class.forName:
try {
Class yourClass = Class.forName( "classname" );
Object o = yourClass.newInstance();
} catch( ClassNotFoundException e ) {
//Throw error or whatever
}
To check if a method exists you could use the NoSuchMethodError e in a try/catch
You can do this using reflection, however it isnt really practical unless you are trying to access classes that potentially will not be present at runtime or if you are trying to access private or hidden fields. Example below.
public static void reflectionDemo(){
//Here we attempt to get the common URI class
//If it is found, we attempt to get the create method
//We then invoke the create method and print the class name of the result.
try {
Class<?> uriClass = Class.forName("java.net.URI");
//getMethod(String name, Class<?>... args);
java.lang.reflect.Method create = uriClass.getMethod("create", String.class);
//The first parameter is null because this is a static method.
//invoke(Object target, Object... args);
System.out.println(create.invoke(null, "some/uri").getClass());
//Will print class java.net.URI
} catch (ClassNotFoundException e) {
// If class doesnt exist
e.printStackTrace();
} catch (NoSuchMethodException e) {
// If method doesnt exist
e.printStackTrace();
} catch (SecurityException e) {
// See Javadoc
e.printStackTrace();
} catch (IllegalAccessException e) {
// From invoke
e.printStackTrace();
} catch (IllegalArgumentException e) {
// From invoke
e.printStackTrace();
} catch (java.lang.reflect.InvocationTargetException e) {
// From invoke
e.printStackTrace();
}
}
To find whether a class exists, you can use the forName() method on Class.
To find whether a method exists, you can use the getMethod() method on Class.
Documentation here:
https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String)
https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getMethod(java.lang.String,%20java.lang.Class...)
For your class problem, you'd want to use code like:
try {
Class.forName("Y");
}
catch (ClassNotFoundException e) {
}
For your method problem, you'd want to use code like:
try {
Class.getMethod(a);
}
catch (NoSuchMethodException e) {
}
You can check if the Class exists with Class.forName("classname");
See this SO question: Check if class exists somewhere in package
If a method exists can be catched with NoSuchMethodError in your try/catch.
See this SO question: Check if method exists at Runtime in Java
try {
Object object = Class.forName("Y").newInstance();
object.a(String, String);
} catch( ClassNotFoundException | NoSuchMethodError ex) {
//do Something else
}

Java - Design Pattern for repeating sql tasks

I have different methods, which queries different data from a database, but the main structure of every method is the same. To reduce the code, I want to shrink that but I don't know how. I have tried interfaces but the return statement cannot called from an inner class. (It should be typesafe!)
Structure:
public <special type> getXYdata(some parameters) {
try (Connection connection = mDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(... special query ...)
) {
// Handle ResultsSet and return object of a special type.
} catch (SQLTimeoutException e) {
throw new ContentManagerException("Query took to long or connection timed out", e);
} catch (SQLException e) {
throw new ContentManagerException("Query or parsing its results failed", e);
}
}
Idea:
private interface QHandler<T> {
String getQuery();
T handleResultSet(ResultSet set) throws SQLException;
}
And then:
private void executeQuery(QHandler handler) throws ContentManagerException {
try (Connection connection = mDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(handler.getQuery())
) {
handler.handleResultSet(results);
} catch (SQLTimeoutException e) {
throw new ContentManagerException("Query took to long or connection timed out", e);
} catch (SQLException e) {
throw new ContentManagerException("Query or parsing its results failed", e);
}
}
But if I call this private method in one of my data mathods, I cannot return an object from the handleResultSet() methods, because the return statement will affect this interface method. Is there an option, to tell the execiteQuery() method which return type the handler has?
Attention: It has to be type safe, no casting if possible!
Your method should not use a raw QHandler type, and should be generic:
private <T> T executeQuery(QHandler<T> handler) throws ContentManagerException {
try (Connection connection = mDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(handler.getQuery())
) {
return handler.handleResultSet(results);
} catch (SQLTimeoutException e) {
throw new ContentManagerException("Query took to long or connection timed out", e);
} catch (SQLException e) {
throw new ContentManagerException("Query or parsing its results failed", e);
}
}
Note that you're trying to reinvent Spring's JdbcTemplate. You might consider using it instead of reinventing it.
Maybe you are open for alternative solutions. If you are using Java 8, you can do somehting like this:
Interface MyHandler {
<T> T handle(Connection c);
}
class MyHelperClass {
public <T> T withConnection(MyHandler handler) {
try {
Connection connection = mDataSource.getConnection();
return handler.handle(connection);
} catch (...) {
...
} finally {
...
}
}
}
Usage:
Result r = myHelperObject.withConnection(con -> {
ResultSet results = connection.createStatement().executeQuery(query)
return new Result(..)
});
This way you can use lambda expressions so you do not need to implement various new classes for your handler interface.

I cannot extend the class in java

This is may one class.
Now i want to create a new class registrationvalidator extending LoginValidator.
i tried by
public class registrationvalidator extends LoginValidator {
}
But its show error in netbeans...What is the soluation?
public LoginValidator() throws SQLException{
try {
connect = new Dbconnect();
st = connect.Statement();
} catch (SQLException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int validator(String mobileNo,String pass){
int ret = 0;
try{
String query="select * from login where mobileNo='"+mobileNo+"'";
res= st.executeQuery(query);
while(res.next()){
String dbMobileNo=res.getString("mobileNo");
String dbPass=res.getString("password");
if(mobileNo.equals(dbMobileNo) && pass.equals(dbPass)){
ret=1;
}
else if(mobileNo.equals(dbMobileNo)){
ret=2;
}
}
}catch(SQLException ex){
System.out.println("Sql Execption: "+ex);
System.out.println("3");
}
return ret;
}
}
A few things here.
You can only define one public class per java file. So your RegistrationValidator class should be in its own java file, separate from the LoginValidator class.
Since you are catching the SQLException and logging some info, you don't need the "throws SQLException" for the constructor signature LoginValidator()

Categories