Łukasz Piotrowski

Łukasz Piotrowski Urządnik Państwowy

Temat: Pobranie danych z bazy PSQL

Witam.
Chciałbym jeśli mogę, prosić Was o pomoc w utworzeniu funkcji która pobierze mi dane z bazy postgresql. Dane przechowywane są w jednej tabeli. Potrzebuję pobrać wszystkie dane, bez nagłówków. Trudność polega na tym że dane muszę pobrać do tablicy. Każdy wiersz z danej kolumny musi być przetrzymywany osobno w taki sposób abym już mając pobrane te dane, mógł się do nich odwołać ponieważ chciałbym na tych danych wykonać później pewne operacje których wynik będzie zapisany na końcu danego wiersza. Oczywiście całe połączenie z bazą itd mam już wykonane. Dane chcę wyświetlić w textArea. Czy mogę liczyć na Waszą pomoc? Nie koniecznie proszę o gotowca ale chociaż może o jakiś przykład bo ciężko taki znaleźć. Odczyt z pliku itd to wszystko jest ale z bazy przykładów brakuje.

Oczywiście próbuję też coś sam w tej kwestii napisać i udało mi się sklepać takie proste pobieranie ale obawiam się że to nie wystarczy bo tak jak mówię, ja potrzebuję to zapisać w tablicy żebym do każdego wiersza w danej kolumnie mógł się odwołać a w tym co napisałem to odczytuję wiersz po wierszu z bazy i tyle.

...
Statement s = null;
try {
s = conn.createStatement();
ResultSet r;
r=s.executeQuery("Select * from raport;");
r.next();

ResultSetMetaData rsmd = r.getMetaData();
int numcols = rsmd.getColumnCount();

for (int i = 1; i <= numcols; i++) {
System.out.print(rsmd.getColumnLabel(i)+" | ");
}
System.out.print("\n------------------------------------\n");

while (r.next()) {
for (int i = 1; i <= numcols; i++) {
Object obj = r.getObject(i);
if (obj != null)System.out.print(obj.toString()+ " | ");
else System.out.print(" ");
}
System.out.println();
}
} catch (SQLException e) {
System.out.println("Blad odczytu z bazy! " +e.toString());
System.exit(3);
}
...
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: Pobranie danych z bazy PSQL

Troche mało składnie opisałeś co chcesz zrobić...
"Każdy wiersz z danej kolumny..." - co autor miał na myśli?
"Odczyt z pliku itd..." - to dane brane z bazy danych czy z pliku?

Podaj może strukturę tabeli i info jakie operacje chcesz wykonywać na wierszach. Może można to wykonać zapytaniem do bazy danych i operacje wykonać po stronie bazy.

Chcesz bawić się na ResultSet z zapytania dodawać kolumny do wiersza i potem trzymać w JTextArea. Nie lepiej do prezentacji danych użyć JTable?
Łukasz Piotrowski

Łukasz Piotrowski Urządnik Państwowy

Temat: Pobranie danych z bazy PSQL

Wiesz co, obliczenia które chcę wykonać są niestety zbyt skomplikowane aby wykonać je na bazie. Oczywiście, pewnie że można ale to wymaga dość rozbudowanego zapytania co po stronie javy jestem w stanie wykonać jedną prostą pętlą.

Co chcę zrobić:
Mam tabelę gdzie przechowuję dane w postacie tekstowej. Tabela zawiera 10 kolumn i ok 3 tysięcy wierszy. Chcę pobrać z bazy z i-tego wiersza j-ej kolumny daną i zapisać ją do dwuwymiarowej tablicy tak aby w pętli wykonującej obliczenia, mógł się odwołać do tej danej. Każdą taką daną z tej tabeli chciałbym pobrać do osobnego rekordu w tablicy.
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: Pobranie danych z bazy PSQL

Jakoś cię nie mogę zrozumieć. Może dlatego, że nie wiem jaki ma być efekt. Wnioskuję, że operacje będziesz wykonywał dla każdego wiersza a wynik operacji na kolumnach z wiersza chcesz pamiętać w dodatkowej 11 kolumnie tak?

Najprościej w sumie zrobić wielowymiarową tablicę i się po niej iterować ale jeżeli w ramach wierszy to wykorzystałbym TableModel. Iterowałbym po ResultSet i wykonywał operację po czym dane z ResultSet i wynik operacji zapisałbym jako wiersz w TableModel.

Chciałem Ci przygotować przykład ale nie wiem czy dobrze rozumuję...
Łukasz Piotrowski

Łukasz Piotrowski Urządnik Państwowy

Temat: Pobranie danych z bazy PSQL

Jeszcze raz :). Mam w bazie tabelę która zawiera 10 kolumn z danymi i ok 3 tysięcy wierszy. Teraz chcę pobrać ją do javy w taki sposób aby każda dana z tabeli była pod osobnym adresem w tablicy. Dla przykładu mam tabelę:

Wartość_1 Wartość_2 Wartość_3 .....
123 45646 45654654
324 23455 34543656
345 22134 43534567
. . .
. . .
. . .

I teraz chcę każdą tą daną przechowywać w pod osobnym indeksem w tablicy po pobraniu tzn: wartość 123 pod indeksem [0][0], wartość 45646 pod [0][1] itd. W taki sposób abym mógł do każdej z tych wartości wykonując obliczenie mógł się odnieść. Do obliczeń brane będą co prawda tylko wartości z 3 kolumn albo pobrać muszę wszystko ponieważ po wyliczeniu wygeneruję z tego plik w którym muszą być te wszystkie dane. Wynik obliczenia będę przechowywał w 11 kolumnie obok tzn wynik obliczenia dla pierwszego wiersza będzie pod w tablicy pod adresem [0][10] dla drugiego wiersza pod adresem [1][10] dla trzeciego po [2][10] itd. Trochę zawile ale mam nadzieję że teraz troszeczkę jaśniej to opisałem :)

Dziękuję za zainteresowanie i pomoc :)Ten post został edytowany przez Autora dnia 22.10.14 o godzinie 22:13
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: Pobranie danych z bazy PSQL

Teraz właśnie jest konkretnie :) Wszystko rozumiem i zaraz podeślę Ci klasę generującą JFrame i obekty na których lepiej się pracuje niż na Object[][].
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: Pobranie danych z bazy PSQL

Tabela w bazie:
CREATE TABLE raport(
c1 INT,
c2 INT,
c3 INT,
);
insert into raport values (1,1,1);
insert into raport values (1,2,3);
insert into raport values (3,6,7);
Klasa:
package wsb;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import wsb.core.sql.pgDbParams;
import wsb.core.sql.pgQuery;
import wsb.core.sql.pgSQL;
import wsb.core.sql.pgSQLConnectionType;
import wsb.core.sql.pgSQLException;

/**
* @author Marcin Mackiewicz / mmackiew@wsb.poznan.pl
*/
public class Dane extends JFrame {

private JTable tbl;
private ResultSet result;

/**
* Konstruktor klasy
*/
public Dane() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

przygotujTabele();
pobierzDane();
wykonajObliczeniaIZapiszDane();

zapiszDoPliku("/home/mmackiew/Pulpit/result.csv");

pack();
setLocationRelativeTo(null);
}


/**
* Przygotowanie modelu danych oraz ich prezentacji dla użytkownika
*/
private void przygotujTabele() {
// Model danych - przykładowo 3 kolumny + wynik z operacji na nich
DefaultTableModel model = new DefaultTableModel(
new Object[] {"Kolumna 1", "Kolumna 2", "Kolumna 3", "Wynik"},
0
);

// Tworzymy obiekt widoku danych dla uzytkownika
tbl = new JTable(model);

// Dodajemy go do okna
JScrollPane scroll = new JScrollPane(tbl);
tbl.setFillsViewportHeight(true);
getContentPane().add(scroll);
}


// Pobieranie danych z bazy
private void pobierzDane() {

// Nastawy do bazy danych/
pgDbParams param = new pgDbParams();
param.setHostname("localhost");
param.setPort(5432);
param.setDatabase("gl");
param.setEncoding("UTF-8");
param.setConnectionType(pgSQLConnectionType.PASSWORD);
param.setSchema("public");
param.setUsername("postgres");
param.setPassword("TWOJE TAJNE HASLO");

// Nawiazanie połączenia z bazą danych
pgSQL dbh = pgSQL.getInstance();
dbh.setParams(param);
try {
dbh.Connect();
} catch (pgSQLException ex) {
Logger.getLogger(Dane.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Błąd połączenia z bazą danych!");
}

// Zapytanie SQL
String sql = "SELECT c1, c2, c3 FROM raport";


// Wykonanie zapytania i przekazanie do resultset
try {
pgQuery sth = new pgQuery(sql);
sth.Execute();
result = sth.getResult();
} catch (SQLException ex) {
Logger.getLogger(Dane.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Błąd zapytania SQL\n\n" + ex.getMessage());
}
}


/**
* Wykonuje obliczenia na danych z resultset i zapisuje je w modelu danych
*/
private void wykonajObliczeniaIZapiszDane() {
try {
// Pobranie modelu z widoku dla użytkownika
DefaultTableModel model = (DefaultTableModel) tbl.getModel();

// Ustawiam kursor przed pierwszym wierszem
result.beforeFirst();

// Iteracja po wierszach
while (result.next()) {
/*
* Wykonywanie obliczeń na podstawie danych z kolumny (tu akurat dodawanie). Wynik zapisany
* do zmiennej
*/
int wynik = result.getInt("c1") + result.getInt("c2") + result.getInt("c3");

// Dodanie wiersza do modelu danych (kolumny z bazy + wynik operacji na nich
model.addRow(new Object[]{
result.getInt("c1"),
result.getInt("c2"),
result.getInt("c3"),
wynik
});
}

} catch (SQLException ex) {
Logger.getLogger(Dane.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Błąd przetwarzania danych SQL\n\n" + ex.getMessage());
}
}


/**
* Zapisanie danych do pliku. Każdy wiersz w modelu danych to oddzielna linia. Separatorem kolumy
* jest średnik. W pliku nie ma nagłówków kolumn.
* @param plik Ścieżka wraz z nazwą pliku do którego zapisać dane
*/
private void zapiszDoPliku(String plik) {
try {
// Tworzę uchwyt do pliku (ewentualnie nowy plik)
File f = new File(plik);

// Tworzę obiekt do zapisu danych
FileWriter fw = new FileWriter(f);

// Pobieram model z danymi z widoku dla użytkownika
DefaultTableModel model = (DefaultTableModel) tbl.getModel();

// Iteruję i tworzę linię w postaci string'a
for (int i = 0; i < model.getRowCount(); i++) {
String buffer = model.getValueAt(i, 0).toString() + ";" +
model.getValueAt(i, 1).toString() + ";" +
model.getValueAt(i, 2).toString() + ";" +
model.getValueAt(i, 3).toString() + "\n";

// Zapisuję danę
fw.write(buffer);
}

// Pamiętam aby rozłączyć się z plikiem po wykonaniu zapisu danych.
fw.close();
} catch (IOException ex) {
Logger.getLogger(Dane.class.getName()).log(Level.SEVERE, null, ex);
}
}

}
Tworzę JFrame dla potrzeb prezentacji danych - możesz pominąć.
JTable robi za warstę widoku danych - możesz pominąć.

Stworzyłem model danych odzwierciedlający tabelę rozszerzony o kolumnę wynik (DefaultTableModel model).
Pobrałem dane z bazy i przechowuję w ResultSet

Potem iteruję po ResultSet. W tej pętli wykonuję obliczenia i dodaję dane z bazy poszerzone o wynik.
Całość podzieliłem na metody wykonywane kolejno z konstrukora.
Dodałem też metodę zapisującą danę do pliku.

Klasy pgSQL, pgQuery itp to moje obiekty do łączenia się z PostgreSQL - nie znajdziesz ich nigdzie a ten kod musisz zastąpić własnym.

Następna dyskusja:

Problem z optimistic lockin...




Wyślij zaproszenie do