Commit d80d6a45 by Patryk Czarnik

Gotowe przykłady na bazy danych (JDBC)

parent 1e72a1d3
package gotowe.inne_bazy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/* Łączenie z bazą Oracle wymaga:
* - sterownika Oracle JDBC (OJDBC)
* - wpisania odpowiedniego URL-a, poniżej przykład, który zadziałał dla Oracle 11 eXpress Edition
*/
public class Oracle {
public static void main(String[] args) {
final String url = "jdbc:oracle:thin:@//10.0.15.13:1521/xe";
try(Connection con = DriverManager.getConnection(url, "HR", "abc123")) {
try(Statement st = con.createStatement()) {
final String sql = "SELECT * FROM countries";
try(ResultSet rs = st.executeQuery(sql)) {
while(rs.next()) {
System.out.print(rs.getString(1));
System.out.print(" ");
System.out.println(rs.getString("country_name"));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.inne_bazy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SQLServer {
public static void main(String[] args) {
try (Connection cn = DriverManager.getConnection(
"jdbc:sqlserver://localhost:1433;database=HR;user=KURS;password=abc123");
PreparedStatement stmt = cn.prepareStatement("SELECT * FROM employees");
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
int a = rs.getInt(1);
String b = rs.getString(2);
String c = rs.getString(3);
System.out.println(a + " " + b + " " + c);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class P00_TestPolaczenia {
public static void main(String[] args) {
try (Connection c = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/hr",
"alx",
"abc123")) {
System.out.println("Udało się połączyć: " + c);
System.out.println(c.getClientInfo());
System.out.println(c.getMetaData().getDatabaseProductName());
try (Statement stmt = c.createStatement()) {
final String sql = "SELECT * FROM employees";
try (ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
System.out.print(rs.getString("first_name"));
System.out.print(" ");
System.out.println(rs.getString("last_name"));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P01_Odczyt_Statement {
public static void main(String[] args) {
try {
// W tej wersji zamykam połączenie za pomocą jawnego close()
Connection c = DriverManager.getConnection(Ustawienia.URL,Ustawienia.USER,Ustawienia.PASSWD);
System.out.println("Udało się połączyć: " + c);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM employees");
while (rs.next()) {
// Wartości z kolumn można odczytywać wg numerów (numeracja od 1)
// Do różnych typów danych mamy odpowiednie metody getXXX()
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
// Wartości z kolumn można też odczytywać wg nazw (lub aliasów)
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
java.sql.Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
// również obiekty Statement oraz ResultSet należy zamykać
// ponieważ mogą się z nimi wiązać zasoby trzymane po stronie serwera bazy danych
rs.close();
System.out.println("\n----------------------\n");
// Ten sam Statement może być użyty do innego zapytania.
rs = stmt.executeQuery("SELECT city, country_id FROM locations ORDER BY 2, 1");
while (rs.next()) {
System.out.printf("%s (%s)%n", rs.getString(1), rs.getString(2));
}
rs.close();
stmt.close();
c.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P02_Odczyt_Try {
public static void main(String[] args) {
// W tej wersji zamykaniem połączenia i innych zasobów zajmuje się try-with-resources
try(Connection c = DriverManager.getConnection(Ustawienia.URL,Ustawienia.USER,Ustawienia.PASSWD);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM employees")) {
while (rs.next()) {
// Wartości z kolumn można odczytywać wg numerów (numeracja od 1)
// Do różnych typów danych mamy odpowiednie metody getXXX()
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
// Wartości z kolumn można też odczytywać wg nazw (lub aliasów)
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
// numer wiersza
int nr = rs.getRow();
System.out.printf("%3d. %d %s %s %s %s %s%n", nr, id, firstName, lastName, jobId, salary, date);
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Koniec programu");
}
}
package gotowe.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P03_Odczyt_PreparedStatement {
public static void main(String[] args) {
// W tej wersji zamykniem połączenia i innych zasobów zajmuje się try-with-resources
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// Dzięki rozdzielenieu do osobnych try mogę pomiędzy nimi wpisywać inne instrukcje
System.out.println("Otwarto połączenie " + c);
c.setAutoCommit(false);
c.setReadOnly(true);
final String sql = "SELECT * FROM employees ORDER BY employee_id";
try (PreparedStatement stmt = c.prepareStatement(sql)) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P04_Odczyt_Sparametryzowany {
public static void main(String[] args) {
String kogoSzukac = JOptionPane.showInputDialog("Podaj kod stanowiska, np. IT_PROG");
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
System.out.println("Otwarto połączenie " + c);
// również stosowanie traksancji oraz oznaczanie sesji jako readonly jeśli nie planujemy zmian są dodatkowymi zabezpieczeniami przed skutkami SQL injection
c.setAutoCommit(false);
c.setReadOnly(true);
final String sql = "SELECT * FROM employees WHERE job_id = ? ORDER BY employee_id";
try (PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setString(1, kogoSzukac);
System.out.println("Zapytanie do wykonania: " + stmt);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P05_ProstyUpdate {
public static void main(String[] args) {
String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?" ;
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, 333);
stmt.setString(2, "IT_PROG");
int ile = stmt.executeUpdate(); // uwaga, tego używamy także dla insert czy delete
// Dokładnie mówiąc: ilu wierszy dotyczyło zapytanie.
// W tym programie nie są używane transakcje (inaczej mówiąc: autoCommit == true)
// więc od razu zmiany są zapisywane trwale na serwerze.
System.out.println("Zaktualizowano " + ile + " wierszy");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
public class P06_Transakcja {
public static void main(String[] args) {
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
c.setAutoCommit(false);
c.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); // cudze zmiany widzimy dopiero wtedy, gdy zostaną zakomitowane
// c.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); // nie widzimy cudzych zmian w czasie traksakcji, kolejne selecty zwracają te same wartości (o ile sami nie edytujemy); operacja może się zawiesić w oczekiwaniu na to, co zrobi inny user
// c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); // nasze zmiany nie zamażą cudzych zmian - ale możemy dostać wyjątek gdy próbujemy zmeiniać rekordy
// c.setReadOnly(true); // tutaj nie ma sensu, ale może mieć sens:
JOptionPane.showMessageDialog(null, "Połączyliśmy się i ustawiliśmy transakcję...");
String kogoSzukac = JOptionPane.showInputDialog("Podaj kod stanowiska:");
double srednia1 = sredniaPensja(c, kogoSzukac);
JOptionPane.showMessageDialog(null, "Średnia przed zmianą: " + srednia1);
BigDecimal podwyzka = new BigDecimal(JOptionPane.showInputDialog("Podaj kwotę podwyżki:"));
int ile = podwyzka(c, podwyzka, kogoSzukac);
double srednia2 = sredniaPensja(c, kogoSzukac);
JOptionPane.showMessageDialog(null, ile + "rekordów zmienionych.\nŚrednia po zmianie: " + srednia2);
int wybor = JOptionPane.showConfirmDialog(null, "Czy zapisać zmiany?");
String coSieStalo;
switch (wybor) {
case JOptionPane.YES_OPTION:
c.commit();
coSieStalo = "commit";
break;
case JOptionPane.NO_OPTION:
c.rollback();
coSieStalo = "rollback";
break;
default:
coSieStalo = "cancel";
// Cancel - nie robimy nic
}
double srednia3 = sredniaPensja(c, kogoSzukac);
JOptionPane.showMessageDialog(null, "Średnia po " +coSieStalo +": " + srednia3);
JOptionPane.showMessageDialog(null, "Rozłączamy się...");
} catch (SQLException e) {
e.printStackTrace();
}
}
private static double sredniaPensja(Connection c, String jobId) {
final String sql2 = "SELECT avg(salary) FROM employees WHERE job_id = ?";
try(PreparedStatement stmt2 = c.prepareStatement(sql2)) {
stmt2.setString(1, jobId);
try(ResultSet rs = stmt2.executeQuery()) {
if(rs.next()) {
return rs.getDouble(1);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
private static int podwyzka(Connection c, BigDecimal zmiana, String jobId) {
String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?";
try(PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setBigDecimal(1, zmiana);
stmt.setString(2, jobId);
int ile = stmt.executeUpdate();
return ile;
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class P07_GenerowaneId {
/* W bazach danych często stosowane są automatycznie generowane klucze. Gdy wykonujemy polecenie INSERT nie wymieniając kolumny z kluczem,
* jego wartość jest generowana automatycznie (z sekwencji lub w oparciu o specjalny typ kolumny).
* Ale aplikacja zwykle potrzebuje poznać to ID, aby móc odwoływać się do tego rekordu w dalszej części programu.
* JDBC oferuje mechanizm, w którym przed wykonaniem operacji INSERT w obiekcie Statement rejestruje się automatycznie generowane kolumny,
* a po wykonaniu polecenia można pobrać ich wartości (jako ResultSet).
* W praktyce chodzi o takie kolumny, jak autoinkrementowane ID (przede wszystkim), czas utworzenia rekordu, czasami inne wartości domyślne.
* Tu dodatkowo używam state_province, co jest o tyle nieciekawe, że tam po prostu będzie null,
* ale po prostu pokazuję, że tych pól można podać więcej niż jedno.
*/
public static void main(String[] args) {
// Tablica nazw kolumn, których wartości są wstawiane automatycznie.
// Zamiast nazw mogą być też numery (wtedy tablica intów).
String[] polaGenerowane = {"location_id", "state_province"};
String sql = "INSERT INTO locations(street_address, postal_code, city, country_id) VALUES(?, ?, ?, ?)";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql, polaGenerowane)) {
stmt.setString(1, "Nowa z " + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:SS")));
stmt.setString(2, "01-321");
stmt.setString(3, "Warszawa");
stmt.setString(4, "US");
int ile = stmt.executeUpdate();
System.out.println("Wstawiono " + ile + " rekord"); // powinno być 1
// odcyt wartości wygenerowanych pól
try(ResultSet rsGen = stmt.getGeneratedKeys()) {
if(rsGen.next()) {
int id = rsGen.getInt(1);
String state = rsGen.getString(2);
System.out.println("wygenerowane wartości pól: " + id + ", " + state);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P08a_ModyfikacjaPoprzezWynik {
public static void main(String[] args) {
int limit = 100;
final String sql = "SELECT * FROM departments WHERE department_id < ? ORDER BY department_id";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
try(PreparedStatement stmt = c.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
stmt.setInt(1, limit);
try(ResultSet rs = stmt.executeQuery()) {
System.out.println("Nazwa kursora: " + rs.getCursorName());
while(rs.next()) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
int id = rs.getInt(1);
String staraNazwa = rs.getString(2);
String nowaNazwa = staraNazwa + " *";
System.out.printf("%3d %s → %s\n", id, staraNazwa, nowaNazwa);
rs.updateString(2, nowaNazwa);
//rs.updateString("department_name", nowaNazwa);
rs.updateRow();
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P08b_ModyfikacjaPoprzezWynik_WTransakcji {
public static void main(String[] args) {
final String sql = "SELECT * FROM departments WHERE department_id < ? ORDER BY department_id";
int limit = 100;
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
c.setAutoCommit(false); // przejście w tryb transakcji
try(PreparedStatement stmt = c.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
stmt.setInt(1, limit);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
int id = rs.getInt(1);
String staraNazwa = rs.getString(2);
String nowaNazwa = staraNazwa + " #";
System.out.printf("%3d %s → %s\n", id, staraNazwa, nowaNazwa);
rs.updateString(2, nowaNazwa);
rs.updateRow();
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
c.commit();
System.out.println("COMMIT");
//c.rollback();
//System.out.println("ROLLBACK");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P09_DowolnaKolejnoscResultSet {
public static void main(String[] args) {
final String sql = "SELECT employee_id, first_name, last_name FROM employees ORDER BY employee_id";
int[] pozycje = {1, 100, 3, 5, 500, 30, 1, 3};
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// Aby przewijanie wyników (takie operacje jak absolute() czy previous()) było możliwe,
// należy utworzyć zapytanie typu
// TYPE_SCROLL_INSENSITIVE - wyniki nie są już aktualizowane w trakcie przeglądania; dwa razy odwiedzając ten sam rekord zobaczymy te same dane
// TYPE_SCROLL_SENSITIVE - wyniki są wrażliwe na zmiany robione na tabelach, dane mogą zmienić się w trakcie
// TYPE_FORWARD_ONLY - domyślny, w ogóle nie umożliwia przewijania, tylko rs.next()
try(PreparedStatement stmt = c.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
// możemy sterować ilością rekordów pobieranych jednorazowo przez sieć
// stmt.setFetchSize(20);
try(ResultSet rs = stmt.executeQuery()) {
// Metody z "is" w nazwie tylko sprawdzają położenie, ale go nie zmieniają.
if(rs.isBeforeFirst()) {
System.out.println("before first");
}
if(rs.isFirst()) {
System.out.println("first");
}
if(rs.isAfterLast()) {
System.out.println("after last");
}
if(rs.isLast()) {
System.out.println("first");
}
// rs.beforeFirst(); // ustawia pozycję na taką, to jest domyślne ustawienie na samym początku, przed while(rs.next())
// rs.afterLast(); // ustawia pozycję na taką
// rs.first(); // ustawia na pierwszy rekord (zwraca false jeśli takiego nie ma)
// rs.last(); // ustawia na ostatni rekord (zwraca false jeśli takiego nie ma)
// rs.absolute(nr); // przechodzi do konkretnego numeru wiersza
// rs.relative(offset); // przesuwa się o tyle wględem pozycji bieżącej
// rs.next(); // przesuwa do następnego (jak relative(1))
// rs.previous(); // przesuwa do poprzedniego (jak relative(-1))
for(int poz : pozycje) {
if(rs.absolute(poz)) {
int id = rs.getInt(1);
String imie = rs.getString(2);
String nazwisko = rs.getString(3);
System.out.printf("\npoz %3d: %d %s %s\n", poz, id, imie, nazwisko);
if(rs.previous()) {
nazwisko = rs.getString(3);
System.out.printf(" ... a poprzedni ma na nazwisko %s\n", nazwisko);
}
if(rs.relative(2)) {
nazwisko = rs.getString(3);
System.out.printf(" ... a następny ma na nazwisko %s\n", nazwisko);
}
} else {
System.out.printf("\npoz %3d - nie ma takiej pozycji\n", poz);
}
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P10_Batch {
public static void main(String[] args) {
int ID = 5000;
int ILE = 1000;
final String sql = "INSERT INTO locations(location_id, street_address, postal_code, city, country_id)"
+ " VALUES(?,?,?,?,?)";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
c.setAutoCommit(false); // wyłączamy automatyczne commitowanie - przechodzimy w tryb traksakcji
System.out.println("start");
long poczatek = System.currentTimeMillis();
for(int i=0; i<ILE; i++) {
stmt.setInt(1, ID + i);
stmt.setString(2, "Jasna 23 " + i);
stmt.setString(3, "01-234");
stmt.setString(4, "Warszawa");
stmt.setString(5, "UK");
stmt.addBatch();
if(i % 50 == 0) {
System.out.println();
}
System.out.print(".");
System.out.flush();
}
System.out.print("\n***");
// Wykonanie wszystkich poleceń zapamiętanych w batchu
stmt.executeBatch();
//c.rollback();
c.commit();
long koniec = System.currentTimeMillis();
System.out.println("\n\nGotowe, czas = " + (koniec - poczatek) + " ms");
} catch (SQLException e) {
System.err.println("Błąd podczas łączenia albo wykonywania SQL");
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P10_Batch_wersja_bez_batch_do_porownania {
public static void main(String[] args) {
int ID = 4000;
int ILE = 1000;
final String sql = "INSERT INTO locations(location_id, street_address, postal_code, city, country_id)"
+ " VALUES(?,?,?,?,?)";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
c.setAutoCommit(false); // wyłączamy automatyczne commitowanie - przechodzimy w tryb traksakcji
System.out.println("start");
long poczatek = System.currentTimeMillis();
for(int i=0; i<ILE; i++) {
stmt.setInt(1, ID + i);
stmt.setString(2, "Jasna 14/16a lok. " + i);
stmt.setString(3, "01-234");
stmt.setString(4, "Warszawa");
stmt.setString(5, "UK");
stmt.executeUpdate();
if(i % 50 == 0) {
System.out.println();
}
System.out.print(".");
System.out.flush();
}
System.out.print("\n***");
//c.rollback();
c.commit();
long koniec = System.currentTimeMillis();
System.out.println("\n\nGotowe, czas = " + (koniec - poczatek) + " ms");
} catch (SQLException e) {
System.err.println("Błąd podczas łączenia albo wykonywania SQL");
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class P11_Metadane {
/* Nawet nie wiedząc jaka jest struktura bazy danych, można te informacje odczytać z połączenia */
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
System.out.println("Otwarto połączenie. c = " + c);
DatabaseMetaData dbMetaData = c.getMetaData();
System.out.println(dbMetaData.getDatabaseProductName());
System.out.println(dbMetaData.getDatabaseMajorVersion()
+ "." + dbMetaData.getDatabaseMinorVersion());
System.out.println();
try(ResultSet tables = dbMetaData.getTables(null, "public", null, null)) {
wypiszTabele(tables);
}
System.out.println("\n\nNormalna tabela:");
try(ResultSet rs = c.createStatement().executeQuery("SELECT * FROM jobs")) {
wypiszTabele(rs);
}
System.out.println();
try(ResultSet rs = c.createStatement().executeQuery("SELECT * FROM departments JOIN locations USING(location_id)")) {
wypiszTabele(rs);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void wypiszTabele(ResultSet rs) throws SQLException {
// Odczytanie "metadanych wyniku"
ResultSetMetaData rsMetaData = rs.getMetaData();
final int n = rsMetaData.getColumnCount();
System.out.println("Wynik ma " + n + " kolumn:");
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rsMetaData.getColumnName(i));
}
System.out.println();
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rsMetaData.getColumnType(i));
}
System.out.println();
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rsMetaData.getColumnTypeName(i));
}
System.out.println();
while(rs.next()) {
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rs.getString(i));
}
System.out.println();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class P12_MultiResult {
public static void main(String[] args) {
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
try (Statement stmt = c.createStatement()) {
// Kilka zapytań w jednym stringu
String sql = "SELECT * FROM countries;"
+ " SELECT * FROM jobs;"
+ " SELECT first_name, last_name FROM employees";
if(stmt.execute(sql)) // jeśli jest pierwszy ResultSet
do {
try (ResultSet rs = stmt.getResultSet()) {
System.out.println("\n###########################\nKolejne wyniki:");
while (rs.next()) {
System.out.print(rs.getString(1));
System.out.print(" ");
System.out.println(rs.getString(2));
}
}
// sprawdzam czy jest jeszcze jakiś kolejny ResultSet i jeśli tak, ponawiam wypisywanie
} while (stmt.getMoreResults());
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class P13a_Blob_Create {
// nazwa typu dla danych binarnych w wielu bazach danych, w tym Oracle, to BLOB
// w PostgreSQL ten typ nazywa się BYTEA
public static void main(String[] args) {
final String sql = """
DROP TABLE IF EXISTS photos;
CREATE TABLE photos(
photo_id SERIAL PRIMARY KEY,
file_name VARCHAR(60) NOT NULL,
bytes BYTEA NOT NULL
)
""";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
Statement stmt = c.createStatement()) {
stmt.execute(sql);
System.out.println("Gotowe");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
public class P13b_Blob_Insert {
public static void main(String[] args) {
String[] polaGenerowane = {"photo_id"};
String sql = "INSERT INTO photos(file_name, bytes) VALUES(?, ?)";
JFileChooser fileChooser = new JFileChooser(".");
fileChooser.setDialogTitle("Wybierz plik");
fileChooser.setFileFilter(new FileNameExtensionFilter("Pliki graficzne", "jpg", "jpeg", "png", "bmp"));
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode
c.setAutoCommit(false);
try(PreparedStatement stmt = c.prepareStatement(sql, polaGenerowane)) {
while(true) {
int wybor = fileChooser.showOpenDialog(null);
if(wybor == JFileChooser.CANCEL_OPTION) break;
if(wybor == JFileChooser.ERROR_OPTION) continue;
File selectedFile = fileChooser.getSelectedFile();
try(InputStream input = new FileInputStream(selectedFile)) {
stmt.setString(1, selectedFile.getName());
//stmt.setBlob(2, input);
stmt.setBinaryStream(2, input);
int ile = stmt.executeUpdate();
try(ResultSet generatedKeys = stmt.getGeneratedKeys()) {
if(ile == 1 && generatedKeys.next()) {
int id = generatedKeys.getInt(1);
JOptionPane.showMessageDialog(null, "Dodano zdjęcie " + selectedFile.getName() + " pod numerem " + id);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
int wybor = JOptionPane.showConfirmDialog(null, "Czy zatwierdzasz zmiany?");
switch(wybor) {
case JOptionPane.YES_OPTION -> c.commit();
case JOptionPane.NO_OPTION -> c.rollback();
}
JOptionPane.showMessageDialog(null, "Gotowe");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
public class P13c_Blob_Download {
public static void main(String[] args) {
String sql = "SELECT photo_id, file_name, bytes FROM photos ORDER BY 1";
JFileChooser fileChooser = new JFileChooser(".");
fileChooser.setFileFilter(new FileNameExtensionFilter("Pliki graficzne", "jpg", "jpeg", "png", "bmp"));
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode
c.setAutoCommit(false);
c.setReadOnly(true);
try(PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
int id = rs.getInt(1);
String fileName = rs.getString(2);
fileChooser.setDialogTitle("Zapisz plik nr " + id);
fileChooser.setSelectedFile(new File(fileName));
int wybor = fileChooser.showSaveDialog(null);
if(wybor != JFileChooser.APPROVE_OPTION) continue;
File selectedFile = fileChooser.getSelectedFile();
try(InputStream input = rs.getBinaryStream(3);
OutputStream output = new FileOutputStream(selectedFile)) {
input.transferTo(output);
} catch (IOException e) {
e.printStackTrace();
}
}
}
JOptionPane.showMessageDialog(null, "Gotowe");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
public class P13d_Blob_Download {
public static void main(String[] args) {
String sql = "SELECT photo_id, file_name, bytes FROM photos ORDER BY 1";
JFileChooser fileChooser = new JFileChooser(".");
fileChooser.setFileFilter(new FileNameExtensionFilter("Pliki graficzne", "jpg", "jpeg", "png", "bmp"));
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode
c.setAutoCommit(false);
c.setReadOnly(true);
try(PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
int id = rs.getInt(1);
String fileName = rs.getString(2);
Blob blob = rs.getBlob(3);
try {
fileChooser.setDialogTitle("Zapisz plik nr " + id);
fileChooser.setSelectedFile(new File(fileName));
int wybor = fileChooser.showSaveDialog(null);
if(wybor != JFileChooser.APPROVE_OPTION) continue;
File selectedFile = fileChooser.getSelectedFile();
try(InputStream input = blob.getBinaryStream();
OutputStream output = new FileOutputStream(selectedFile)) {
input.transferTo(output);
} catch (IOException e) {
e.printStackTrace();
}
} finally {
blob.free();
}
}
}
JOptionPane.showMessageDialog(null, "Gotowe");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
public class P13e_Blob_Show {
public static void main(String[] args) {
String sql = "SELECT photo_id, file_name, bytes FROM photos ORDER BY 1";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
c.setAutoCommit(false);
c.setReadOnly(true);
try(PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
int id = rs.getInt(1);
String fileName = rs.getString(2);
byte[] bytes = rs.getBytes(3);
ImageIcon img = new ImageIcon(bytes);
JOptionPane.showMessageDialog(null, img, "Zdjęcie nr " + id, JOptionPane.INFORMATION_MESSAGE);
}
}
JOptionPane.showMessageDialog(null, "Gotowe");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class P14a_Procedura_BrakWyniku {
// Przykład wywołania "procedury składowanej" - takie rzeczy można tworzyć w bazach Oracle (PL/SQL), PostgreSQL (odmiana PL/SQL, ale także C i Python), MS SQL Server (T-SQL)
// Ta procedura przyjmuje tylko parametry typu IN i nie zwraca wyniku. W kolejnych plikach przykłady innych sytuacji.
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("CALL przenies_pracownika(?,?,?)")) {
stmt.setInt(1, 112);
stmt.setInt(2, 60);
stmt.setString(3, "IT_PROG");
stmt.execute();
System.out.println("Wykonane");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.util.Scanner;
public class P14b_Procedura_ParametryOut {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
System.out.print("Podaj numer departamentu: ");
int nrDep = sc.nextInt();
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("{CALL statystyki_departamentu(?,?,?,?,?)}")) {
// parametrom IN ustawiamy wartości
stmt.setInt(1, nrDep);
// parametry OUT należy zarejestrować przed wykonaniem zapytania
stmt.registerOutParameter(2, Types.INTEGER);
stmt.registerOutParameter(3, Types.DECIMAL);
stmt.registerOutParameter(4, Types.DECIMAL);
stmt.registerOutParameter(5, Types.DECIMAL);
stmt.executeUpdate();
// odebranie wartości wynikowych
int count = stmt.getInt(2);
BigDecimal avg = stmt.getBigDecimal(3);
BigDecimal min = stmt.getBigDecimal(4);
BigDecimal max = stmt.getBigDecimal(5);
System.out.printf("Statystyki departamentu %d: cnt = %d, avg = %s, min = %s, max = %s%n",
nrDep, count, avg, min, max);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Scanner;
public class P14c_Procedura_OdczytWartosciSkalarnej {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
System.out.print("Podaj numer pracownika: ");
int nr = sc.nextInt();
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("{?= call nazwisko_szefa(?)}")) {
stmt.setInt(2, nr);
stmt.registerOutParameter(1, Types.VARCHAR);
System.out.println(stmt);
stmt.executeUpdate();
String nazwisko = stmt.getString(1);
if(nazwisko == null) {
System.out.println("Nie ma szefa");
} else {
System.out.println("Szef ma na nazwisko: " + nazwisko);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
import java.util.Scanner;
public class P14d_Procedura_OdczytTabeli {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
System.out.print("Podaj numer pracownika: ");
int nr = sc.nextInt();
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("{call zarabiajacy_wiecej_niz(?)}")) {
stmt.setInt(1, nr);
System.out.println(stmt);
try (ResultSet rs = stmt.executeQuery()) {
System.out.println("Pracownicy zarabiający więcej:");
while (rs.next()) {
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P15_Url {
public static void main(String[] args) throws SQLException {
// Parametry zapytania można przekazać też w URL-u.
// W tym także użytkownika i hasło.
// Parametr tcpKeepAlive niczemu konkretnemu tu nie służy - jest tylko przykładem,
// że sterowniki JDBC mogą posiadać dodatkowe parametry niestandardowe.
// W SQL Server parametry rozdziela się średnikami, np user=ala;password=kot
String url = "jdbc:postgresql://localhost/hr?user=alx&password=abc123&tcpKeepAlive=true";
String name = "Steven";
Connection c = DriverManager.getConnection(url);
c.setAutoCommit(false);
PreparedStatement stmt = c.prepareStatement("SELECT first_name,last_name FROM EMPLOYEES "
+ "WHERE first_name = ?");
stmt.setString(1, name);
stmt.setFetchSize(10);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.print("Wynik: ");
System.out.print(rs.getString(1) + " ");
System.out.println(rs.getString(2));
}
stmt.setFetchSize(0);
rs.close();
stmt.close();
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class P16a_Property {
// Parametr tcpKeepAlive niczemu konkretnemu tu nie służy - jest tylko przykładem,
// że sterowniki JDBC mogą posiadać dodatkowe parametry niestandardowe.
public static void main(String[] args) throws SQLException {
Properties props = new Properties();
props.setProperty("user", "alx");
props.setProperty("password", "abc123");
// props.setProperty("ssl", "true");
props.setProperty("tcpKeepAlive", "true");
String url = "jdbc:postgresql://localhost/hr";
Connection c = DriverManager.getConnection(url, props);
Statement stmt = c.createStatement();
// Statementy można trochę skonfigurować
stmt.setFetchSize(10);
ResultSet rs = stmt.executeQuery("SELECT SUM(salary) FROM employees");
while (rs.next()) {
System.out.print("Wynik: ");
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
c.close();
}
}
package gotowe.postgresql;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class P16b_Property_ZPliku {
public static void main(String[] args) {
try {
Properties props = new Properties();
// nazwa pliku jeśli jest w katalogu bieżącym, albo pełna ścieżka do pliku
props.load(new FileInputStream("postgres.properties"));
// props.load(new FileInputStream("C:/jakis_katalog/postgres.properties"));
String url = props.getProperty("url");
Connection c = DriverManager.getConnection(url, props);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT avg(salary) FROM employees");
if (rs.next()) {
System.out.print("Wynik: ");
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
c.close();
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class P16c_Property_Z_Classpath {
public static void main(String[] args) {
try {
Properties props = new Properties();
// Tutaj odczytany zostanie plik, który znajduje się (wraz z plikami .class) w katalogach / jar-ach
// będących częścią classpath.
// Jeśli podana jest tylko nazwa pliku (albo ścieżka względna), to jako katalog bieżący jest traktowany bieżący pakiet.
// Można też podać ścieżkę bezwzględną np. /gotowe/postgresql/ustawienia_bazy.properties
// to wtedy plik byłby szukany w pakiecie ustawienia
// W projekcie Mavenowym właściwą lokalizacją dla takich plików jest src/main/resources
props.load(P16c_Property_Z_Classpath.class.getResourceAsStream("ustawienia_bazy.properties"));
String url = props.getProperty("url");
Connection c = DriverManager.getConnection(url, props);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT avg(salary) FROM employees");
while (rs.next()) {
System.out.print("Wynik: ");
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
c.close();
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import javax.sql.RowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
public class P21_RowSet {
public static void main(String[] args) {
try {
//Class.forName("org.postgresql.Driver");
RowSetFactory rsf = RowSetProvider.newFactory();
RowSet rowSet = rsf.createJdbcRowSet();
//RowSet rowSet = rsf.createCachedRowSet(); // też działa
rowSet.setUrl(Ustawienia.URL);
rowSet.setUsername(Ustawienia.USER);
rowSet.setPassword(Ustawienia.PASSWD);
// Moim skromnym zdaniem to przykład złej praktyki "low cohesion" - namieszane za dużo rzeczy w jednej klasie...
String sql = "SELECT first_name, last_name, salary "
+ "FROM employees WHERE salary BETWEEN ? AND ?";
rowSet.setCommand(sql);
rowSet.setInt(1, 8000);
rowSet.setInt(2, 10000);
rowSet.execute();
while (rowSet.next()) {
System.out.printf("%s %s zarabia %s%n", rowSet.getString(1), rowSet.getString(2),
rowSet.getBigDecimal(3));
}
System.out.println();
rowSet.setCommand("SELECT * FROM countries");
rowSet.execute();
while (rowSet.next()) {
System.out.println(rowSet.getString(2));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.math.BigDecimal;
import java.sql.Connection;
import javax.sql.rowset.JdbcRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import javax.swing.JOptionPane;
/* JdbcRowSet jest "connected".
* 1) Zadawanie wielu zapytań w jednej sesji będzie bardziej wydajne przy użyciu JdbcRowSet niż CachedRowSet,
* bo Jdbc pozostaje połączony, a Cached musi się łączyć za każdym razem.
* 2) Posiada metody do zarządzania transakcjami (commit/rollback/savepoint).
* 3) Umożliwia aktualizację danych poprzez wynik.
*/
public class P22_JdbcRowSet {
public static void main(String[] args) {
// final String JOB = "IT_PROG";
// final BigDecimal ZMIANA = new BigDecimal("1.00");
final String JOB = JOptionPane.showInputDialog("Komu zmienić? (np. IT_PROG)");
final BigDecimal ZMIANA = new BigDecimal(JOptionPane.showInputDialog("O ile zmienić?"));
try {
RowSetFactory rsf = RowSetProvider.newFactory();
JdbcRowSet rowSet = rsf.createJdbcRowSet();
rowSet.setUrl(Ustawienia.URL);
rowSet.setUsername(Ustawienia.USER);
rowSet.setPassword(Ustawienia.PASSWD);
rowSet.setAutoCommit(false);
rowSet.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
String sql = "SELECT employee_id, first_name, last_name, salary FROM employees WHERE job_id = ?";
rowSet.setCommand(sql);
rowSet.setString(1, JOB);
rowSet.execute();
while (rowSet.next()) {
BigDecimal pensja = rowSet.getBigDecimal("salary");
System.out.printf("%s %s zarabia %s%n",
rowSet.getString("first_name"), rowSet.getString("last_name"), pensja);
pensja = pensja.add(ZMIANA);
System.out.println(" ale teraz zmieniam mu pensję na " + pensja);
rowSet.updateBigDecimal("salary", pensja);
rowSet.updateRow();
}
System.out.println();
int coRobic = JOptionPane.showConfirmDialog(null, "Czy zakomitować zmiany?");
switch(coRobic) {
case JOptionPane.YES_OPTION:
rowSet.commit();
break;
case JOptionPane.NO_OPTION:
rowSet.rollback();
break;
case JOptionPane.CANCEL_OPTION:
default:
// do nothing
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;
import javax.sql.RowSet;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.FilteredRowSet;
import javax.sql.rowset.Predicate;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
/* CachedRowSet i jego specjalizacje są disconnected.
* To może zmniejszyć wydajność, ale pozwala kopiować dane i pracować z nimi w oderwaniu od bazy.
*
* FilteredRowSet pozwala nakładać filtry na odczytywane dane.
*/
public class P23_CachedRowSet {
private Connection c;
private RowSetFactory rsf;
P23_CachedRowSet() throws SQLException {
rsf = RowSetProvider.newFactory();
c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
}
private void populujWynikiZapytania(String tabela, CachedRowSet cachedRowSet) throws SQLException {
final String sql = "SELECT * FROM " + tabela;
try(PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
cachedRowSet.populate(rs);
// rs można zamknąć
}
}
private void run() throws SQLException {
FilteredRowSet employees = rsf.createFilteredRowSet();
populujWynikiZapytania("employees", employees);
CachedRowSet jobs = rsf.createCachedRowSet();
populujWynikiZapytania("jobs", jobs);
while(jobs.next()) {
String jobId = jobs.getString("job_id");
String jobTitle = jobs.getString("job_title");
System.out.printf("\nPracownicy ze stanowiska %s (%s):\n", jobTitle, jobId);
employees.setFilter(new PredykatJobowy(jobId));
employees.beforeFirst();
while(employees.next()) {
String firstName = employees.getString("first_name");
String lastName = employees.getString("last_name");
System.out.printf(" * %s %s\n", firstName, lastName);
}
}
}
public static void main(String[] args) {
try {
P23_CachedRowSet p13 = new P23_CachedRowSet();
p13.run();
System.out.println("Koniec");
} catch (Exception e) {
e.printStackTrace();
}
}
private static class PredykatJobowy implements Predicate {
private String jobId;
public PredykatJobowy(String jobId) {
this.jobId = jobId;
}
public boolean evaluate(RowSet rs) {
try {
String actualJobId = rs.getString("job_id");
return Objects.equals(jobId, actualJobId);
} catch (SQLException e) {
return false;
}
}
public boolean evaluate(Object value, int column) throws SQLException {
return true;
}
public boolean evaluate(Object value, String columnName) throws SQLException {
return true;
}
}
}
package gotowe.postgresql;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import javax.sql.rowset.WebRowSet;
/* WebRowSet pozwala wyeksportować dane do formatu XML
*/
public class P24_WebRowSet {
public static void main(String[] args) {
try {
System.out.println("Start");
RowSetFactory rsf = RowSetProvider.newFactory();
WebRowSet rowSet = rsf.createWebRowSet();
rowSet.setUrl(Ustawienia.URL);
rowSet.setUsername(Ustawienia.USER);
rowSet.setPassword(Ustawienia.PASSWD);
String sql = "SELECT * FROM employees LEFT JOIN jobs USING(job_id) LEFT JOIN departments USING (department_id) LEFT JOIN locations USING (location_id) LEFT JOIN countries USING (country_id) ORDER BY employee_id";
rowSet.setCommand(sql);
System.out.println("Zadaję zapytanie");
rowSet.execute();
System.out.println("Eksportuję XML");
try(Writer out = new BufferedWriter(new FileWriter("employees.xml"))) {
rowSet.writeXml(out);
}
System.out.println("Gotowe");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.postgresql;
public class Ustawienia {
public static final String HOST = "localhost";
public static final String PASSWD = "abc123";
public static final String BAZA = "hr";
public static final String URL = "jdbc:postgresql://" + HOST + "/" + BAZA;
public static final String USER = "alx";
}
url=jdbc:postgresql://localhost/hr
user=alx
password=abc123
tcpKeepAlive=true
package gotowe.sqlite;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
public class P01_Polaczenie {
public static void main(String[] args) {
// JDBC
try {
Connection connection = DriverManager.getConnection(
"jdbc:sqlite:hr.db");
System.out.println("Nawiązano połączenie " + connection);
System.out.println("Klasa: " + connection.getClass().getName());
DatabaseMetaData metaData = connection.getMetaData();
System.out.println(metaData.getDatabaseProductName());
System.out.println(metaData.getDatabaseMajorVersion() + " " + metaData.getDatabaseMinorVersion());
// da się też odczytać listę wszystkich tabel, informacje o tabelach...
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.sqlite;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P02_Odczyt {
public static void main(String[] args) {
try {
Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement("SELECT * FROM employees");
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
// można odczytać kolumny wg numeru - numeracja od 1
String imie = rs.getString(2);
// można też używać nazwy kolumny
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
System.out.println(imie + " " + nazwisko + " zarabia " + pensja);
}
rs.close();
stmt.close();
c.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.sqlite;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P03_Odczyt {
public static void main(String[] args) {
final String sql = "SELECT * FROM employees ORDER BY employee_id";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
// można odczytać kolumny wg numeru - numeracja od 1
String imie = rs.getString(2);
// można też używać nazwy kolumny
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
String data = rs.getString("hire_date");
int id = rs.getInt("employee_id");
System.out.printf("%-15s %-15s (%3d) - zatr. %s, pensja %8s\n",
imie, nazwisko, id, data, pensja);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.sqlite;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JOptionPane;
public class P04_Parametry {
public static void main(String[] args) {
String szukani = JOptionPane.showInputDialog("Podaj kod stanowiska");
szukani = szukani.toUpperCase();
// Przykład SQL injection, które zadziałałoby w wersji ze sklejaniem stringów:
// a'; DROP TABLE job_history; SELECT 'ala
// final String sql = "SELECT * FROM employees WHERE job_id = '" + szukani + "'";
// Właściwe podejście: użyć znaków zapytania i metod PreparedStatement.setXXX aby ustawić wartość parametru.
final String sql = "SELECT * FROM employees WHERE job_id = ?";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setString(1, szukani);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
// można odczytać kolumny wg numeru - numeracja od 1
String imie = rs.getString(2);
// można też używać nazwy kolumny
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
String data = rs.getString("hire_date");
int id = rs.getInt("employee_id");
String job = rs.getString("job_id");
System.out.printf("%-15s %-15s (%3d) - zatr. %s, pensja %8s, %s\n",
imie, nazwisko, id, data, pensja, job);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.sqlite;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JOptionPane;
public class P05_DanePracownika {
public static void main(String[] args) {
String s = JOptionPane.showInputDialog("Podaj id pracownika");
int id = Integer.parseInt(s);
// program ma:
// połączyć się z bazą,
// zadać zapytanie (z JOIN i WHERE)
// i wypisać dane tego pracownika:
// first_name, last_name, department_name, street_address, city
// (z tabel employees, departments, locations)
final String sql = "SELECT first_name, last_name, department_name, street_address, city " +
"FROM employees" +
" LEFT JOIN departments USING(department_id)" +
" LEFT JOIN locations USING(location_id)" +
"WHERE employee_id = ?";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, id);
try(ResultSet rs = stmt.executeQuery()) {
if(rs.next()) {
System.out.printf("%s %s %s %s %s\n",
rs.getString(1),
rs.getString(2),
rs.getString(3),
rs.getString(4),
rs.getString(5));
} else {
System.out.println("Nie znaleziono takiego pracownika");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.sqlite;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P06_Podwyzka {
public static void main(String[] args) {
String job = "IT_PROG";
int zmiana = 250;
final String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, zmiana);
stmt.setString(2, job);
// Także dla poleceń jak INSERT, DELETE czy ALTER TABLE użylibyśmy executeUpdate
int ile = stmt.executeUpdate();
System.out.println("Zmodyfikowano " + ile + " rekordów.");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment