filling combobox from database - java

I'm using flex, Java and sql server for webmapping application and i'm trying to fill my combobox from database, but i just get results like this [Object Object] [Object Object] [Object Object] [Object Object] instead of getting the correct values of the fields, this is the code, i think all is right but it doesn't work !!! can you help be to find what i'm messing !!
so first this is the code of my class, it selects a column (Intitule Chapitre) from database
public class RapportDao {
public Connection conectar(){
Connection cn = null;
String connectionUrl = "jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=mabase;user=sa;password=sa;";
try
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
cn = DriverManager.getConnection(connectionUrl);
}
catch(Exception ex)
{
System.out.println("Error : " + ex.getMessage());
}
return cn;
}
public ArrayList<Rapport> Selection() {
Connection conn = conectar();
ArrayList<Rapport> list = null;
if (conn!=null){
try{
Rapport pr = null;
String a;
list = new ArrayList<Rapport>();
String sql = "select IntituleChap from Rapport";
Statement st = conn.createStatement();
ResultSet rs=st.executeQuery(sql);
while (rs.next())
{
a=rs.getString("IntituleChap");
pr = new Rapport();
pr.setIntituleChap(a);
list.add(pr);
}
}
catch(SQLException e ) {
// System.out.print(e.getMessage());
System.out.println("Error = " + e.getMessage());
}
}else
{
}
return list;
}
}
and this is my actionscript code for combobox
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:esri="http://www.esri.com/2008/ags"
minWidth="1000" minHeight="700" applicationComplete="application1_applicationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import spark.components.ComboBox;
private function getTypeprojetResult(event : ResultEvent):void
{
//Alert.show(""+event.result);
}
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
RemoteRapportDao.Selection()
}
]]>
<fx:Declarations>
<s:RemoteObject id="RemoteRapportDao"
destination="RapportDaoDest"
fault="onFault(event)">
<s:method name="Selection" result="getTypeprojetResult(event);"/>
</s:RemoteObject>
</fx:Declarations>
<s:ComboBox id="cmb" x="10" y="13" width="162" labelField="IntituleChap" dataProvider="{RemoteRapportDao.Selection.lastResult}" />
RemoteRapportDao : is the id RemoteObject
Selection() : my method on the service
any one could help me ?

It's very likely to having issue with representing the results from the query correctly, and therefore the labelField is not trigered correctly with the combo box object.
I would suggest to create a data model representing the results, which would not only great improve readability of the code, but will help you aswell with such no-go issues.
possible example of a data model ( just for a testing purposes ).
package myTopLevelPackage.myPackage
{
public class ComboBoxItemDataModel
{
public var intituleChap: String;
public function ComboBoxItemDataModel( o : Object )
{
super();
this.intituleChap = o[ 'IntituleChap' ];
trace( JSON.encode( o ) );
// use this or other suitable method to see actually how Your object looks like, in order to set the object property correctly in the assignment above.
}
}
}
Please note that I have switched using capital character for a variable IntituleChap to intituleChap.

it works, thank you all for your help, i just should use ArrayCollection instead of arraylist.
public ArrayCollection Selection() {
Connection conn = conectar();
ArrayCollection list = new ArrayCollection();
if (conn!=null){
try{
Rapport pr = null;
String a;
list = new ArrayList<Rapport>();
String sql = "select IntituleChap from Rapport";
Statement st = conn.createStatement();
ResultSet rs=st.executeQuery(sql);
while (rs.next())
{
a=rs.getString("IntituleChap");
pr = new Rapport();
pr.setIntituleChap(a);
list.add(pr);
}
}
catch(SQLException e ) {
// System.out.print(e.getMessage());
System.out.println("Error = " + e.getMessage());
}
}else
{
}
return list;
}
thank you all :)

Related

How do I build a multilevel TreeView in JavaFX using a JDBC datasource?

In my JavaFX program I want to dynamically generate a tree using the live data set from my database (I'm using MariaDB, but it could be any SQL database).
I had searched a bunch and could not find a direct answer to my question, so I spent some time learning how JDBC ResultSet's work, how the next() method works, and how while loops work. A few trial-and-error attempts finally led me to the result I wanted, so I thought I would share it in case anyone else finds themselves in my position.
See my answer below.
edit It seems I’ve designed the overall program poorly in not using threading to isolate the GUI from the JDBC query. I think this can be fixed using JavaFX concurrency, but I’ve never used it so until I can update the code below, just ignore the stuff outside the while loop.
Firstly, I'm using following versions of MariaDB (10.4.12), Java (13.0.2.8), JavaFX (13.0.2), and MariaDB JDBC (2.6.0). I don't think any of this will make a difference, but just in case.. I'm using FXML, which is why you won't see any UI formatting in there anywhere.
This is the full method that generates the TreeView in my JavaFX program. It's then called from a separate class shortly after generating the Stage and Scene objects.
They key part is the while loop, which was a struggle for me to get right. I initially thought I needed a nested while(rs.next()) loop, but then I realised that this was causing rows to be skipped because each rs.next() call is related to the previous one, not to the while loop in which it is used.
Note also that the SQL statement is important. If the statement gives results out of order the method doesn't work correctly.
public void generateTree(DataSource dataSource) {
source = null;
this.source = dataSource;
Connection con = null;
Statement stmt = null;
TreeItem<String> rootTreeItem = new TreeItem<String>("EMT");
rootTreeItem.setExpanded(true);
emtTree.setRoot(rootTreeItem);
TreeItem<String> site = null;
TreeItem<String> plant = null;
try {
con = source.getConnection();
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT sites.siteid, sites.longname, plants.plantid, plants.siteplantid, plants.shortname FROM sites INNER JOIN plants ON plants.siteid=sites.siteid ORDER BY sites.longname ASC, plants.siteplantid ASC");
String site1 = ""; //It's not possible for the site name to be "" in the result set because the database design prevents it.
//Steps through the result set from first row item to last row item.
while(rs.next()) {
//This bit prevents repeating the same first level items multiple times.
//I only want each site to appear once, and under each site is a list
//of plants.
if (!site1.equals(rs.getString("sites.longname"))) {
site = new TreeItem<String>(rs.getString("sites.longname"));
rootTreeItem.getChildren().add(site);
site1 = rs.getString("sites.longname");
}
//This section is never skipped and will add all the plants to a given
//site until the next site is reached in the result set, then the if
//is triggered again and the process for the new site.
plant = new TreeItem<String>(rs.getInt("plants.siteplantid") + " " + rs.getString("plants.shortname"));
site.getChildren().add(plant);
}
} catch (SQLException e) {
System.out.println("Statement Error");
System.err.println("SQL State: " + ((SQLException)e).getSQLState());
System.err.println("Error Code: " + ((SQLException)e).getErrorCode());
System.err.println("Message: " + ((SQLException)e).getMessage());
System.err.println("Cause: " + ((SQLException)e).getCause());
return;
}
} catch (SQLException e) {
e.printStackTrace();
return;
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
I'll probably find ways to improve it in future, but for now I'm just happy to have it working. Ignore the messy exception handling - its a work in progress!
Here is my try how to do it with not blocking the UI Thread:
public class YourClassName {
ArrayList<ResultBean> fetchedData = null;
public void createTree() {
// run in other thread fetching the data
Task task = new Task<Void>() {
#Override
protected Void call() throws Exception {
// show loading pane -> you can use the one from import org.controlsfx.control.MaskerPane
// https://github.com/controlsfx/controlsfx/wiki/ControlsFX-Features
loadingPane.setVisible(true);
// get data
fetchedData = generateTreeData(yourDataSource);
return null;
}
#Override
protected void succeeded() {
// the data has been fetched, now is safe to build your tree
super.succeeded();
buildTreeFromTheData(fetchedData);
}
};
new Thread(task).start();
}
}
Fetch the data from your database:
public ArrayList<ResultBean> getTreeData(DataSource dataSource) {
ArrayList<ResultBean> resultBeans = new ArrayList<>();
source = null;
this.source = dataSource;
Connection con = null;
Statement stmt = null;
try {
con = source.getConnection();
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT " +
"sites.siteid, " +
"sites.longname, " +
"plants.plantid, " +
"plants.siteplantid, " +
"plants.shortname " +
"FROM sites " +
"INNER JOIN plants ON plants.siteid=sites.siteid " +
"ORDER BY sites.longname ASC, plants.siteplantid ASC");
while (rs.next()) {
ResultBean resBean = new ResultBean();
resBean.setSiteId(rs.getString("sites.siteid"));
//....
//....
// set all values and add it to the result array
resultBens.add(resBean);
}
} catch (SQLException e) {
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return resultBens;
}
ResultBean:
public class ResultBean {
private int siteid;
private String longname;
private int plantid;
private int siteplantid;
private String shortname;
// setters
....
// getters
....
}
And finally, build the tree with your logic:
public void buildTreeFromTheData(ArrayList<ResultBean> treeData) {
// do you logic here, loop over treeData ArrayList in while loop
TreeItem<String> rootTreeItem = new TreeItem<String>("EMT");
rootTreeItem.setExpanded(true);
emtTree.setRoot(rootTreeItem);
TreeItem<String> site = null;
TreeItem<String> plant = null;
//This bit prevents repeating the same first level items multiple times.
//I only want each site to appear once, and under each site is a list
//of plants.
//if (!site1.equals(rs.getString("sites.longname"))) {
// site = new TreeItem<String>(rs.getString("sites.longname"));
// rootTreeItem.getChildren().add(site);
// site1 = rs.getString("sites.longname");
// }
//This section is never skipped and will add all the plants to a given
//site until the next site is reached in the result set, then the if
//is triggered again and the process for the new site.
// plant = new TreeItem<String>(rs.getInt("plants.siteplantid") + " " + rs.getString("plants.shortname"));
// site.getChildren().add(plant);
// finally, hide the loading pane
maskerPane.setVisible(false);
}

java- how to retrieve resultset from database without using JDBC?

I am writing a program that acts as a service and picks up emails from the email queue table, processes them and sends them out. Here is something along how I did it, and it does work fine.
MySqlConnect con = new MySqlConnect();
public PreparedStatement preparedStatement = null;
public Connection con1 = con.connect();
//pick up queue and send email
public void email() throws Exception {
try {
while(true) {
String sql = "SELECT id,user,subject,recipient,content FROM emailqueue WHERE status='Pending' ";
PreparedStatement statement = con1.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
String subject = rs.getString("subject");
String recipient = rs.getString("recipient");
String content = rs.getString("content");
String id = rs.getString("id");
String username = rs.getString("user");
String emailStatus = "DONE";
String errormsg = sendEmail(recipient, subject, content, id,username);
if (!errormsg.equals("")) {
emailStatus = "FAILED";
}
TerminalLogger.printMsg("Status : " + emailStatus);
}
statement.close();
rs.close();
}
} catch(Exception e) {
e.printStackTrace();
TerminalLogger.printMsg("Exception: "+e.toString());
}
con1.close();
Thread.sleep(2000);
}
Now, I am clearly using JDBC to obtain the result set in the loop and process them as shown. Of course, I also need to specify my database connection in MySqlConnect.java properties. While all this works perfectly fine, I was wondering is there another way of achieving the same goal without using JDBC, i.e. specifying the connection properties?
I was thinking of Java Persistence. I am new to this.
Edit
I have been told to use JPA to achieve this and I have written it in this way:
public void email() throws Exception {
try {
while(true) {
String sql = "select p.id,p.user,p.subject,p.recipient,p.content from Emailqueue p where " +
"status='Pending'";
List<Object[]> list = em.createQuery(sql).getResultList();
for (Object[] obj : list) {
System.out.println(obj[0]);
System.out.println(obj[1]);
System.out.println(obj[2]);
System.out.println(obj[3]);
System.out.println(obj[4]);
}
}
} catch(Exception e) {
e.printStackTrace();
TerminalLogger.printMsg("Exception: " + e.toString());
}
From here, I would pass the parameters I want to the method. Is this way feasible?
Edit 2
Did it a bit different like below:
String id = ejbCon.getSettingsFacade().getid();
String username = ejbCon.getSettingsFacade().getUser();
String subject = ejbCon.getSettingsFacade().getSubject();
String recipient = ejbCon.getSettingsFacade().getRecipient();
String content = ejbCon.getSettingsFacade().getContent();
String errormsg = sendEmail(recipient, subject, content, id,username);
public String getContent() {
try {
String sql="Select content FROM emailqueue WHERE status='Pending'";
if (em == null) {
throw new Exception("could not found subject");
}
return (String) em.createNativeQuery(sql).getSingleResult();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Just a bit idea of how the method looks like, the other methods follow the same concept.
List<EmailQueue> emailList = em.createQuery(sql).getResultList();
for (EmailQueue obj : emailList) {
String emailStatus = "DONE";
String errormsg=sendEmail(obj.getRecipient(), obj.getSubject, obj.getContent(),obj.getId(),obj.getUsername());
if (!errormsg.equals("")) {
emailStatus = "FAILED"
}
TerminalLogger.printMsg("Status : " + emailStatus);
}
}
Before using JPA ,you must read about it WHY JPA
As discussed in the comments above, Spring Batch and Spring JPA is a good choice for your use-case,
you can follow and study about on the internet and follow the official document
Spring JPA tutorial link
Spring Batch tutorial link
Happy Learning, Hope more users would suggest other good options that you can choose from and apply to your use-case post evaluating their pros and cons

SQLException: ResultSet closed

I'm trying to execute method which should create a new object with fields from database, and everytime i run this code im getting SQLException: ResultSet closed.
public DatabasedClient getDatabaseClient(int clientDatabaseid){
if(DatabaseClientUtil.isInDatabase(clientDatabaseid)){
return DatabaseClientUtil.getDBClient(clientDatabaseid);
}else{
try{
System.out.println("Trying to find user in db");
ResultSet rs = fbot.getStorage().query("select * from database_name where clientDBId = " + clientDatabaseid);
System.out.println("deb " + rs.getString("nick"));
while (rs.next()) {
DatabasedClient databasedClient = new DatabasedClient(clientDatabaseid);
databasedClient.setUid(rs.getString("uid"));
databasedClient.setNick(rs.getString("nick"));
databasedClient.setLastConnect(rs.getLong("lastConnected"));
databasedClient.setLastDisconnect(rs.getLong("lastDisconnect"));
databasedClient.setTimeSpent(rs.getLong("timeSpent"));
databasedClient.setLongestConnection(rs.getLong("longestConnection"));
return databasedClient;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
}
Im using hikari, here are methods from AbstractStorage class
#Override
public void execute(String query) throws SQLException {
try (Connection connection = getConnection()){
connection.prepareStatement(query).executeUpdate();
}
}
#Override
public ResultSet query(String query) throws SQLException {
try (Connection connection = getConnection()) {
return connection.prepareStatement(query).executeQuery();
}
}
Screenshot from error
I hope someone will help me with this.
I think the exact error you are seeing is being caused by the following line of code:
System.out.println("deb " + rs.getString("nick"));
You are trying to access the result set before you advance the cursor to the first record. Also, your method getDatabaseClient is returning a single object which conceptually maps to a single expected record from the query. Hence, iterating once over the result set would seem to make sense. Taking all this into consideration, we can try the following:
try {
System.out.println("Trying to find user in db");
ResultSet rs = fbot.getStorage().query("select * from database_name where clientDBId = " + clientDatabaseid);
// do not access the result set here
if (rs.next()) {
DatabasedClient databasedClient = new DatabasedClient(clientDatabaseid);
databasedClient.setUid(rs.getString("uid"));
databasedClient.setNick(rs.getString("nick"));
databasedClient.setLastConnect(rs.getLong("lastConnected"));
databasedClient.setLastDisconnect(rs.getLong("lastDisconnect"));
databasedClient.setTimeSpent(rs.getLong("timeSpent"));
databasedClient.setLongestConnection(rs.getLong("longestConnection"));
return databasedClient;
}
} catch (SQLException e) {
e.printStackTrace();
}

use one jdbc connection class for all classes java

i have been using this JDBC conection in all of my class that had to run query but i created a new class which i dont want the constructor with a parameter of the DConnection from JDBC Class(main Database Class).
but i keep on getting NullPointExceptions. Can anyway figur out what that problem may be.
Thanks.
public class UsersDao {
// associating the Database Connection objekt
private DConnector connector;
private final Connection myConn;
// Constructor
public UsersDao() throws CZeitExceptionHand,SQLException {
myConn = connector.getConnenction();
}
public boolean updateUsers(String mitarb, int mid) throws SQLException{
// PreparedStatement myStmt = null;
Statement stmt = myConn.createStatement();
try {
String myStmt = "SELECT Bly "
+ "" + mid + ";";
return stmt.execute(myStmt);
} finally {
close(stmt);
}
}
Example like this Method which is working but in different class
String[][] getAllTheWorkers(DConnector connector) throws CZeitExceptionHand {
try {
Connection connect = connector.getConnenction();
Statement stmt = connect.createStatement();
ResultSet result = stmt.executeQuery("SELECT ");
result.last();
int nt = result.getRow();
result.beforeFirst();
}
return results;
} catch (SQLException e) {
throw new CZeitExceptionHand("Error: " + e);
}
}
The object does not seem to be initialized.
Can you please post which method is not working and from where it is invoked ?
P.S : Unable to add a comment - that is why have answered !

How do I call data from a table in a database into a java class in netbeans?

first time posting so sorry if my question is slightly strange.
So I have a project in school that requires us to create java classes using netbeans that open up a window with three options, check stock, purchase item and update stock.
We had a class called stockdata that held the details of 5 different items for us to use in our three classes to check, purchase and update items. The latest stage of our coursework requires us to create a derby database and enter the items into a table.
I have done this with no issues but I am having a problem getting the items from the table back into my classes to use. We were given the following code but I can't get it to work, even using the commented hints.
package stock;
// Skeleton version of StockData.java that links to a database.
// NOTE: You should not have to make any changes to the other
// Java GUI classes for this to work, if you complete it correctly.
// Indeed these classes shouldn't even need to be recompiled
import java.sql.*; // DB handling package
import java.io.*;
import org.apache.derby.drda.NetworkServerControl;
public class StockData {
private static Connection connection;
private static Statement stmt;
static {
// standard code to open a connection and statement to an Access database
try {
NetworkServerControl server = new NetworkServerControl();
server.start(null);
// Load JDBC driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//Establish a connection
String sourceURL = "jdbc:derby://localhost:1527/"
+ new File("UserDB").getAbsolutePath() + ";";
connection = DriverManager.getConnection(sourceURL, "use", "use");
stmt = connection.createStatement();
} // The following exceptions must be caught
catch (ClassNotFoundException cnfe) {
System.out.println(cnfe);
} catch (SQLException sqle) {
System.out.println(sqle);
} catch (Exception e) {
System.out.println(e);
}
}
// You could make methods getName, getPrice and getQuantity simpler by using an auxiliary
// private String method getField(String key, int fieldNo) to return the appropriate field as a String
public static String getName(String key) {
try {
// Need single quote marks ' around the key field in SQL. This is easy to get wrong!
// For instance if key was "11" the SELECT statement would be:
// SELECT * FROM Stock WHERE stockKey = '11'
ResultSet res = stmt.executeQuery("SELECT * FROM Stock WHERE stockKey = '" + key + "'");
if (res.next()) { // there is a result
// the name field is the second one in the ResultSet
// Note that with ResultSet we count the fields starting from 1
return res.getString(2);
} else {
return null;
}
} catch (SQLException e) {
System.out.println(e);
return null;
}
}
public static double getPrice(String key) {
// Similar to getName. If no result, return -1.0
return 0;
}
public static int getQuantity(String key) {
// Similar to getName. If no result, return -1
return 0;
}
// update stock levels
// extra is +ve if adding stock
// extra is -ve if selling stock
public static void update(String key, int extra) {
// SQL UPDATE statement required. For instance if extra is 5 and stockKey is "11" then updateStr is
// UPDATE Stock SET stockQuantity = stockQuantity + 5 WHERE stockKey = '11'
String updateStr = "UPDATE Stock SET stockQuantity = stockQuantity + " + extra + " WHERE stockKey = '" + key + "'";
System.out.println(updateStr);
try {
stmt.executeUpdate(updateStr);
} catch (SQLException e) {
System.out.println(e);
}
}
// close the database
public static void close() {
try {
connection.close();
} catch (SQLException e) {
// this shouldn't happen
System.out.println(e);
}
}
}
Sorry if this seems a stupid question but I am fairly new to Java and was making good progress until this roadblock.
Thanks in advance!
Alex
Searching for "java sql" on Google delivers this link: https://docs.oracle.com/javase/tutorial/jdbc/basics/processingsqlstatements.html
From a connection you can create a statement (you can find this in the link and in your code) , then fetch a result set and loop over that with rs.next(). That should get your started.
Of course you have to make sure that the driver and database are there/running, just saying...
Here netbeans has nothing to do with database. This is a Java-based integrated development environment(IDE) that will help you to reduce syntactic error.
public void dataAccess(){
try {
String connectionUrl = "suitable connection url as per your database";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
Class.forName("JDBC driver name as per your database");
con = DriverManager.getConnection(connectionUrl, userName, password);
String SQL = "SQL query as per your criteria";
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
// look into ResultSet api and use method as per your requirement
}
rs.close();
}
catch (Exception e) {
//log error message ;
}
}

Categories