I am trying to fetching album details and all images associated with that album to Set piSet but it is not fetching all images to set piSet
I want like
albumname in al object
ABC
images in piSet
image1
image2
image3
....
Data fetching code is
con = ConnectionFactory.getConnection();
List<Album> aList = new ArrayList<Album>();
try {
ps = con.prepareStatement("select distinct album.*,pi.* from "
+ "atom as a "
+ "left join album as album "
+ "on "
+ "a.id=album.aid "
+ "left join post_images as pi "
+ "on "
+ "album.id=pi.album_id "
+ "where "
+ "a.id=? "
+ "and a.status=? ");
ps.setLong(1, aid);
ps.setString(2, "Active");
rs = ps.executeQuery();
while (rs.next()) {
Set<PostImages> piSet = new HashSet<PostImages>();
Album al = new Album();
al.setId(rs.getLong("album.id"));
al.setName(rs.getString("album.name"));
PostImages pi = new PostImages();
pi.setImageId(rs.getLong("pi.image_id"));
pi.setLargePicPath(rs.getString("pi.large_pic_path"));
piSet.add(pi);
al.setPostImageses(piSet);
aList.add(al);
}
} catch (SQLException e) {}
How to modify above code to fetch all images to 'PiSet'.
Assume id is unique in album table, above code can satisfy your requirement:
rs = ps.executeQuery();
HashMap<Long, Album> AlbumMap = new HashMap<Long, Album>();
while (rs.next()) {
Long albumId = rs.getLong("album.id");//assume album.id is unique.
Album al = AlbumMap.get(albumId);
if (al == null) {
al = new Album();
al.setId(albumId);
al.setName(rs.getString("album.name"));
Set<PostImages> piSet = new HashSet<PostImages>();
al.setPostImageses(piSet);
aList.add(al);
AlbumMap.put(albumId, al);
}
PostImages pi = new PostImages();
pi.setImageId(rs.getLong("pi.image_id"));
pi.setLargePicPath(rs.getString("pi.large_pic_path"));
al.getPostImageses().add(pi);
}
You need to keep a map from id to Album instances, and only create a new Album when there is no instance yet for the given id.
I'd also advise you to let Album handle the Set internally, and just add images to album, instead of setting the set to album.
Map<Long, Album> albumMap = new HashMapMap<>();
while (rs.next()) {
long albumId = rs.getLong("album.id");
Album album = albumMap.get(albumId);
if (albumId = null) {
album = new Album();
album.setId(albumId);
album.setName(rs.getString("album.name"));
albumMap.put(albumId, album);
)
PostImages pi = new PostImages();
pi.setImageId(rs.getLong("pi.image_id"));
pi.setLargePicPath(rs.getString("pi.large_pic_path"));
// Don't handle the set yourself, let Album handle it.
album.addPostImage(pi);
}
aList.addAll(albumMap.values());
As an aside: the use of table prefixes in ResultSet.getXXX is not JDBC standard and is - as far as I know - MySQL specific; it will make your code less portable between different databases.
Related
I'm trying to make an API that will response all the data from the database in a json format. I already succeeded in creating this API and manage to fetch some data from it. What my concern is that the data returns only the last row from the database when i'm calling the API.
when i'm logging the plancode before adding it inside the listobj, the plancode returns all the data from the database. But whenever i return the listobj it only returns the last row from the db. Thank you for your help!
Here's the code i used.
public ArrayList<HashMap<String, Object>> PlanCodesdb(String dbip,int dbport, String dbname, String dbuser,String dbpwd) throws SQLException, JSONException{
PreparedStatement ps = null;
ResultSet rs = null;
Connection conn = null;
StringBuilder str = new StringBuilder();
String procname = "PlanCodes";
String loggerLabel = procname + "-" + dbip + "-" + dbname;
str.append("SELECT brand, product_type, load_package, keyword, denomination, list_price AS wallet_cost, validity FROM plan_code_tbl");
com.mysql.jdbc.jdbc2.optional.MysqlDataSource ds = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
ds.setServerName(dbip);
ds.setPortNumber(dbport);
ds.setDatabaseName(dbname);
ds.setUser(dbuser);
ds.setPassword(dbpwd);
conn = ds.getConnection();
ps = conn.prepareStatement(str.toString());
rs = ps.executeQuery();
ArrayList<HashMap<String, Object>> listobj = new ArrayList<HashMap<String, Object>>();
rs = ps.getResultSet();
ResultSetMetaData metadata = rs.getMetaData();
ArrayList<String> key = new ArrayList<String>();
// System.out.println("column counts: "+metadata.getColumnCount());
logger.info("COlumn counts: " + metadata.getColumnCount());
for (int i=1; i <= metadata.getColumnCount(); i ++){
String columname = metadata.getColumnLabel(i);
// logger.info(loggerLabel + "plancode columnname = " + columname);
// System.out.println("key:"+columname);
key.add(columname);
}
HashMap<String,Object> plancodes = new HashMap<String,Object>();
while(rs.next()){
for (String columname : key){
try{
String colVal = rs.getString(columname);
// logger.info("columname: "+columname+" colVal:"+colVal);
plancodes.put(columname, colVal);
}catch(Exception e){
e.printStackTrace();
logger.info(loggerLabel + "Error Exception: "+e);
}
}
listobj.add(plancodes);
// logger.info("plan code response...");
// logger.info("brand: "+bean.getBrand()+ "\n product_type: "+ bean.getProductType() + "\n load_package: "+ bean.getLoadPackage() +"\n keyword: "+bean.getKeyword()+"\n denomination: "+bean.getDenomination()+"\n list_price: "+bean.getListPrice()+"\n retailer discount: "+bean.getRetailerDiscount()+"\n validity: "+bean.getValidity());
}
return listobj;
}
HashMap<String,Object> plancodes = new HashMap<String,Object>();
while(rs.next()){
for (String columname : key){
try{
String colVal = rs.getString(columname);
// logger.info("columname: "+columname+" colVal:"+colVal);
plancodes.put(columname, colVal);
}catch(Exception e){
e.printStackTrace();
logger.info(loggerLabel + "Error Exception: "+e);
}
}
listobj.add(plancodes);
// logger.info("plan code response...");
// logger.info("brand: "+bean.getBrand()+ "\n product_type: "+ bean.getProductType() + "\n load_package: "+ bean.getLoadPackage() +"\n keyword: "+bean.getKeyword()+"\n denomination: "+bean.getDenomination()+"\n list_price: "+bean.getListPrice()+"\n retailer discount: "+bean.getRetailerDiscount()+"\n validity: "+bean.getValidity());
}
The problem is that you keep updating the same Map and adding it to the list. You need to create the Map inside the while loop:
while(rs.next()){
HashMap<String,Object> plancodes = new HashMap<String,Object>();
so that every element of the list is a new Map.
You are using Map Key as a 'String' and in your map, key is 'columname'. Column names will be same for all the rows. So on each iteration your map will replace existing key with the next key i.e columnname and value. Thats why you are getting only one row in the list.
So don't use string as map key. Use some UNIQUE VALUE TO AVOID SUCH ISSUES.
Example:
Map<String,String> map = new HashMap<String,String>();
map.put("abc","1");`enter code here`
map.put("cde","2");
map.put("abc","3")
In map result you will find only two records i.e cde 2 and abc 3. Because when you add same string key abc twice. It will get replaced by the latest one.
Hope it answers your question. Good luck!
It is possible to create a table that contains other subtables in javafx like in the picture?
The program in the photo is written in javafx only that it is closed source.
Is there any other external or internal component in java that allows me to create a similar interface?
My problem is the same as this: JavaFX TableView: open detail information between rows on click
However, i need to load different value in the sub tables for every row. How can i do this?
This is the creation of my sub-tabs.
private Node createDetailsPane(ObjectProperty<Model> item) {
VBox vBox = new VBox();
ObservableList<Model> dv = FXCollections.observableArrayList();
ObservableList<Model> dl = FXCollections.observableArrayList();
ObservableList<Model> dp = FXCollections.observableArrayList();
TableView visite = new TableView();
TableView latte = new TableView();
TableView parti = new TableView();
visite.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
latte.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
parti.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
visite.setTableMenuButtonVisible(true);
latte.setTableMenuButtonVisible(true);
parti.setTableMenuButtonVisible(true);
visite.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
latte.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
parti.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
visite.getColumns().addAll(idVisita, dataVisita, azioniTerapeutiche, descrizioneVisita, incinta, dataPrevistaParto, veterinario);
latte.getColumns().addAll(idLatte, litri, dataProduzione);
parti.getColumns().addAll(idParto, dataParto, azioniParticolari);
visite.setFixedCellSize(25);
visite.prefHeightProperty().bind(visite.fixedCellSizeProperty().multiply(Bindings.size(visite.getItems()).add(2)));
visite.minHeightProperty().bind(visite.prefHeightProperty());
visite.maxHeightProperty().bind(visite.prefHeightProperty());
latte.setFixedCellSize(25);
latte.prefHeightProperty().bind(latte.fixedCellSizeProperty().multiply(Bindings.size(latte.getItems()).add(2)));
latte.minHeightProperty().bind(latte.prefHeightProperty());
latte.maxHeightProperty().bind(latte.prefHeightProperty());
parti.setFixedCellSize(25);
parti.prefHeightProperty().bind(parti.fixedCellSizeProperty().multiply(Bindings.size(parti.getItems()).add(2)));
parti.minHeightProperty().bind(parti.prefHeightProperty());
parti.maxHeightProperty().bind(parti.prefHeightProperty());
parti.setItems(dp);
latte.setItems(dl);
String id;
if(treeView.getSelectionModel().getSelectedIndices().get(treeView.getSelectionModel().getSelectedItems().size()-1) != -1) {
id = treeView.getSelectionModel().getSelectedItems().get(treeView.getSelectionModel().getSelectedItems().size()-1).getIdProv();
try {
Connection conn = Driver.connection();
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/animali?autoReconnect=true&useSSL=false", "admin", "admincs97");
Statement stmt = conn.createStatement();
sql = "SELECT DISTINCT `ID_VISITA`,`DATA_VISITA`,`AZIONI_TERAPEUTICHE`,`DESCRIZIONE_VISITA`,`STATO_VISITA`,`GRAVIDA_DA_GG`,`DATA_PREVISTA_PARTO`,`VETERINARIO` FROM `visite` "
+ "LEFT JOIN `anagrafe` USING(`ID_PROVVISORIO`, `BOLO`) "
+ "LEFT JOIN `parti` USING(`ID_PROVVISORIO`, `BOLO`) "
+ "LEFT JOIN `latte` USING(`ID_PROVVISORIO`, `BOLO`) "
+where;
String temp = "";
if(where.trim().length() > 0)
temp += " AND visite.`ID_PROVVISORIO` = '"+id+"'";
else
temp = "WHERE visite.`ID_PROVVISORIO` = '"+id+"'";
sql += temp;
ResultSet rs = stmt.executeQuery(sql);
if(rs.next())
do {
dv.add(new Model( rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7), rs.getString(8)));
/*rs.getString(13), rs.getString(14), rs.getString(15), rs.getString(16), rs.getString(17), rs.getString(18),
rs.getString(19), rs.getString(20), rs.getString(21), rs.getString(22), rs.getString(23), rs.getString(24),
rs.getString(25), rs.getString(26) */
} while(rs.next());
} catch(SQLException e) {
new FxDialogs().showException("Errore", "Errore nel caricamento dei dati", e);
}
}
visite.setItems(dv);
vBox.getChildren().addAll(visite, latte, parti);
return vBox ;
}
Everything works until I select multiple rows in the main table.
If for example I have two main lines, if I select first the second and then the first the subtables give me back the same value.
I know StackOver flow is not a place where you can post your homework up and ask people to do it for you
but i am at my wit's end I tried simple debugging method like printing line where I can see the result, just some how the arraylist doesn't save the item when i add in
lets just say the array adds two item
first item(name1,job1,event1,date1,location1)
second item(name2,job2,event2,date2,location2)
The end results
name1 test234
name2 test234
name2 outloop
name2 outloop
Here is the code
public class Homework {
// ...
private int cin;
private String[] jobarray;
private String[] eventarray;
private Timetable tb;
private String[] namesarray;
//...
public ArrayList retrievebyname(String name, String date) {
ResultSet rs = null;
DBController db = new DBController();
ArrayList<Timetable> list = new ArrayList();
// start of for loop**
for (int k = 0; k < cin; k++) {
// step 1 - establish connection to database
db.getConnection();
// step 2 - declare the SQL statement
String dbQuery = "select event.eventName,Timetable.location,Timetable.date "
+ "From Timetable " + "inner join event "
+ "on event.eventId=Timetable.eventId " + "inner join VolunteerJob "
+ "on VolunteerJob.ID= Timetable.jobId " + "Where JobName='"
+ jobarray[k] + "'" + "and Timetable.date ='" + date + "'"
+ "and eventName='" + eventarray[k] + "'";
// step 3 - to retrieve data using readRequest method
rs = db.readRequest(dbQuery);
try {
if (rs.next()) {
tb.setName(namesarray[k]);
tb.setJobName(jobarray[k]);
tb.setEventName(rs.getString("eventName"));
tb.setDate(rs.getString("date"));
tb.setLocation(rs.getString("location"));
// **Adding the item retrieve into ArrayList called List**
list.add(k, tb);
System.out.println(list.get(k).getName() + " test234");
}
} catch (Exception e) {
e.printStackTrace(); // fail to retrieve, print error message
}
// step 4 - close connection
db.terminate();
} // end of for loop**
System.out.println(list.get(0).getName() + " outloop");
System.out.println(list.get(1).getName() + " outloop");
return list;
}
}
After your edit, I see that you created one instance of Timetable at the start of the method. That's not enough.
It means you are adding the same object to the list over and over again, and you are overwriting its properties in each iteration.
You must create a new instance of Timetable for each object you add to the list.
tb = new Timetable ();
tb.setName(namesarray[k]);
tb.setJobName(jobarray[k]);
tb.setEventName(rs.getString("eventName"));
tb.setDate(rs.getString("date"));
tb.setLocation(rs.getString("location"));
list.add(k, tb)
I'm trying to store rows from a table into an array. I can get the first result and store that but I cannot seem to be able to store any of the other data.
This is the code I've written
try
{
test = "select * from Arsenal order by 'MatchNumber' ASC";
rs = st.executeQuery(test);
while (rs.next())
{
//This retrieves each row of Arsenal table and adds it to an array in the Team Results class.
matchno = rs.getString("MatchNumber");
hometeam = rs.getString("HomeTeam");
awayteam = rs.getString("AwayTeam");
homegoals = rs.getString("HomeGoals");
awaygoals = rs.getString("AwayGoals");
result = rs.getString("Result");
teams = (matchno + "," + hometeam + "," + awayteam + "," + homegoals + "," + awaygoals + "," + result); // Takes all the variables containging a single customers information and puts it into a string, seperated by commas.
TeamResults.add(matchno,hometeam,awayteam,homegoals,awaygoals,result);
}
}
Any idea where I'm going wrong?
Change the while-condition to hasNext() and use next() inside of the loop to move the database cursor forward.
Try to use this method bellow :
public void SelectData(String sqlcounter ,String sql){
try {
RsCounter=stmt.executeQuery(sqlcounter);
System.out.println(sqlcounter);
while(RsCounter.next()){
countrow=RsCounter.getInt("COUNTR");
System.out.println(countrow+"\n");
}
System.out.println(sql);
RsSelecting = stmt.executeQuery(sql);
data=new String[countrow][RsSelecting.getMetaData().getColumnCount()];
header= new String[RsSelecting.getMetaData().getColumnCount()];
i=0;
while(RsSelecting.next()){
for(j=0;j<RsSelecting.getMetaData().getColumnCount();j++){
data[i][j]=(RsSelecting.getString(j+1));
header[j]=RsSelecting.getMetaData().getColumnName(j+1);
System.out.print(data[i][j]+"\n");
}
i++;
}
i=j=0;
} catch (SQLException ex) {
ex.printStackTrace();
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
}
}
where
sqlcounter ="select COUNT(*) as COUNTR from Arsenal order by 'MatchNumber' ASC";
and
sql ="select * from Arsenal order by 'MatchNumber' ASC";
Verify the column names once. Sometimes ALIAS doesn't work out, I am not sure why.
Get the meta data from the result set:
ResultSetMetaData metaData = resultSet.getMetaData();
int size = metaData.getColumnCount();
for (int i = 0; i < size; i ++)
System.out.println(metaData.getColumnName(i);
Also just for performance, list out the column names instead of using * in the SELECT query. Also, you can take a look at com.sun.rowset.CachedRowSetImpl. It's used like:
CachedRowSetImpl crs = new CachedRowSetImpl();
crs.populate(resultSet);
I think it also implements CachedRowSet, but I am not entirely sure.
I am trying to implement FK relation from MySQL into JAVA using JDBC. I have a list of Garaz objects and each Garaz has a list of Auto (cars) objects. I have very mixed data.
My MySQl DB is ok and I try to do it like this:
public static ArrayList <Garaz> selectRecords() throws SQLException {
Connection dbConnection = null;
Statement statement = null;
String selectTableSQL = "SELECT Garaz.G_ID, Garaz.Nazwa, Garaz.Adres, Garaz.LiczbaMiejsc, Garaz.LiczbaPoziomow, " +
"Garaz.Czynny, Auta.A_Id, Auta.Model, Auta.Kolor, Auta.IloscDrzwi, Auta.Rejestracja\n" +
"FROM Garaz\n" +
"LEFT JOIN Auta\n" +
"ON Garaz.G_Id=Auta.G_Id\n" +
"ORDER BY Garaz.G_Id; ";
// ArrayList lista = new ArrayList <Garaz>();
try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(selectTableSQL);
// execute select SQL stetement
ResultSet rs = statement.executeQuery(selectTableSQL);
while (rs.next()) {
int g_id = rs.getInt("G_ID");
String nazwa = rs.getString("NAZWA");
String adres = rs.getString("ADRES");
int lmiejsc = rs.getInt("LICZBAMIEJSC");
int lpoz = rs.getInt("LICZBAPOZIOMOW");
boolean czynny = rs.getBoolean("CZYNNY");
ArrayList lista2 = new ArrayList <Auto>();
int a_id = rs.getInt("A_Id");
String model = rs.getString("Model");
String kolor = rs.getString("Kolor");
int ildrzwi = rs.getInt("IloscDrzwi");
String rejestracja = rs.getString("Rejestracja");
Auto d = new Auto(a_id, model, kolor, ildrzwi, rejestracja);
if (a_id !=0){
lista2.add(d);
}
Garaz f = new Garaz(g_id, nazwa, lista2, adres, lmiejsc, lpoz, czynny);
lista.add(f);
//System.out.println("nazwa : " + nazwa);
//System.out.println("adres : " + adres);
// return lista;
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
return lista;
}
I don't understand how to read from ResultSet rs in the way that: ArrayList Garaz contains objects (Garaz) and each Garaz object contains ArrayList Auto. So I have big problem with creating 2 lists (one is part of another) by reading data from rs (ResultSet). I have all Garaz and all Auto from DB tables, but the relation is mixed. Like Garaz1 contains random Auto (cars).
How do I create 2 lists (one is part of another) to keep the relation Auto is part of Garaz based on G_ID?
your result set will provide one result (aka line) for each Garaz and Auto, since thats what the select statement does. So you can...
either parse the resultset as it is, and manually create each Garaz & Auto record you want, but you will have to deal with the duplicate Garaz data.
OR
You can either use a framework like MyBatis to get the get the objects back, or.
OR
Perform a SELECT statement for the list of Garaz, then perform another SELECT statement to get the list of AUTO's back for each Garaz.
Sudo code.....
#Repository
public class StoreDbDAO
{
#Autowired
public void init(#Qualifier("dataSourceCDB") DataSource dataSource) {
this.dataSource = dataSource;
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
private static final String GET_USABLE_RECORDS = "SELECT d.ID, d.HARDWARE_ID " +
" FROM DEVICE d " +
" LEFT JOIN TABLEB o on o.X_ID = d.X_ID " +
" WHERE " +
" d.DEVC_HARDWARE_ID IS NOT NULL " +
" AND o.CODE = ? "";
public List<Map<String, Object>> getStores(String cCode)
{
return simpleJdbcTemplate.queryForList(GET_USABLE_RECORDS, code);
}
}
#Autowired
StoreDbDAO storeDbDAO;
public void caller() {
List> stores = storeDbDAO.getStores();
List<Stores> storeRecords = new ArrayList[stores.size()];
for (Map<String, Object> store: stores)
{
final String storeId = (String) store.get("HARDWARE_ID");
StoreRecord x = new StoreRecord(storeId)
storeRecords.add(x);
List<Map<String, Object>> devicesInTheStore = storeDbDAO.getDevicesForStore(storeId);
// convert these into something useful.
x.setDevicesInStore(convertToList(devicesInTheStore));
}
}
You need to iterate over the result, check if you already created the Garaz object for the G_ID of the row and either use that or create a new one. This can be simplified by sorting on the G_ID field and just create a new Garaz object when the G_ID changes.
As you comment that you don't know how to do this, here is a full example:
public List<Garaz> getAllGaraz() throws SQLException {
List<Garaz> garazList = new ArrayList<Garaz>();
try (
Connection con = getDBConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT Garaz.G_ID, /* other garaz columns */ " +
"Auta.A_Id /*other auta columns */\n" +
"FROM Garaz\n" +
"LEFT JOIN Auta\n" +
"ON Garaz.G_Id=Auta.G_Id\n" +
"ORDER BY Garaz.G_Id");
) {
Garaz currentGaraz = null;
while (rs.next()) {
int garazId = rs.getInt("G_ID");
// Create Garaz only if it is different
if (currentGaraz == null || currentGaraz.getId() != garazId) {
// retrieve other columns
currentGaraz = new Garaz(g_id /* + other garaz columns */);
garazList.add(currentGaraz);
}
int a_id = rs.getInt("A_Id");
// replacement of your condition of a_id != 0
// 0 could be a valid value, check for null instead
if (!rs.wasNull()) {
// retrieve other columns
Auto auta = new Auta(a_id /* + other auta columns */);
// The list of Auta is part of the garaz
currentGaraz.addAuta(auta);
}
}
return garazList;
}
}
public class Garaz {
private final List<Auta> autaList = new ArrayList<Auta>();
private final int id;
public Garaz(int g_id /* + other fields*/) {
id = g_id;
}
public int getId() {
return id;
}
public void addAuta(Auta auta) {
autaList.add(auta);
}
public List<Auta> getAutaList() {
return new ArrayList<Auta>(autaList);
}
}