Commit 7a3bba31 by Patryk Czarnik

Gotowe przykłady dot. baz danych

parent 0d8a5a7a
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",
"kurs",
"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();
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();
System.out.printf("%d %s %s %s %s %s%n", 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 podwyzka(int zmiana, int min, int max) {
String sql = "UPDATE employees SET salary = salary + ? "
+ "WHERE salary BETWEEN ? AND ?" ;
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, zmiana);
stmt.setInt(2, min);
stmt.setInt(3, max);
int ile = stmt.executeUpdate(); // uwaga, tego używamy także dla insert czy delete
// Dokładnie mówiąc: ilu wierszy dotyczyło zapytanie.
System.out.println("Zaktualizowano " + ile + " wierszy");
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
podwyzka(333, 10000, 20000);
}
}
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)
// 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;
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()) {
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.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class P09a_Procedura_BrakWyniku {
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");
// gdyby byl parametr INOUT albo OUT
// stmt.registerOutParameter(1, Types.VARCHAR);
// a jeśli funkcja zwraca wynik (wartość skalarną, a nie tabelę), to piszemy tak:
// "{?= call funkcja(?,?,?)}"
// i zarejestrować parametr wynikowy, aby Java odebrała ten wynik
// stmt.registerOutParameter(1, Types.VARCHAR);
// teraz jakaś wersja execute
stmt.executeUpdate();
// i po execute zrobic String zmiennaWJavie = stmt.getString(1);
// gdyby funkcja zwracała wyniuk typu tabela, to wtedy nie rejestrujemy tego wyniku jako parametru
// tylko stosujemy ResultSet rs = stmt.executeQuery();
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 P09b_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 P09c_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 P09d_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 P10_Skoki {
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 P11_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 P11_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.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.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class P13_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.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=kurs&password=abc123&tcpKeepAlive=true";
String name = "Steven";
String last = "King";
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 P16_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", "kurs");
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 P16a_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 P16b_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(P16b_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 = "kurs";
}
url=jdbc:postgresql://localhost/hr
user=kurs
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();
}
}
}
package zajecia.postgresql;
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 java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
/* W tej wersji program korzysta z bazy danych "w transakcji", co oznacza,
* że dopóki nie zatwierdzi zmian (commit), zmiany te nie są widoczne dla innych klientów,
* nie są zapisane w sposób trwały, można je wycofać.
*/
public class Podwyzka3 {
public static void main(String[] args) {
final String url = "jdbc:postgresql://localhost/hr";
try(Connection c = DriverManager.getConnection(url, "kurs", "abc123")) {
// wyłączam tryb auto-commit, wchodzę w tryb transakcji
c.setAutoCommit(false);
List<String> jobs = znajdzJoby(c);
String job = (String) JOptionPane.showInputDialog(null,
"Wybierz job", "Komu dać podwyżkę?", JOptionPane.QUESTION_MESSAGE, null, jobs.toArray(), null);
double avg1 = sredniaPensja(c, job);
JOptionPane.showMessageDialog(null, "Średnia pensja na stanowisku " + job + " wynosi teraz " + avg1);
BigDecimal zmiana = new BigDecimal(JOptionPane.showInputDialog("Podaj kwotę podwyżki"));
zmienPensje(c, job, zmiana);
double avg2 = sredniaPensja(c, job);
JOptionPane.showMessageDialog(null, "Średnia pensja na stanowisku " + job + " wynosi teraz " + avg2);
int wybor = JOptionPane.showConfirmDialog(null, "Czy zatwierdzić zmiany?");
switch(wybor) {
case JOptionPane.YES_OPTION:
c.commit();
break;
case JOptionPane.NO_OPTION:
c.rollback();
break;
default:
// pass
}
double avg3 = sredniaPensja(c, job);
JOptionPane.showMessageDialog(null, "Średnia pensja na stanowisku " + job + " wynosi teraz " + avg3);
JOptionPane.showMessageDialog(null, "Koniec programu, zaraz sie rozłączę...");
} catch (SQLException e) {
e.printStackTrace();
}
}
private static double sredniaPensja(Connection c, String job) throws SQLException {
String sql = "SELECT avg(salary) FROM employees WHERE job_id = ?";
try (PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setString(1, job);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return rs.getDouble(1);
}
}
}
return 0.0;
}
private static List<String> znajdzJoby(Connection c) throws SQLException {
List<String> jobs = new ArrayList<>();
try(PreparedStatement stmt = c.prepareStatement("SELECT DISTINCT job_id FROM employees ORDER BY 1");
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
jobs.add(rs.getString(1));
}
}
return jobs;
}
private static void zmienPensje(Connection c, String job, BigDecimal zmiana) throws SQLException {
final String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?";
try(PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setBigDecimal(1, zmiana);
stmt.setString(2, job);
int ile = stmt.executeUpdate();
JOptionPane.showMessageDialog(null, "UPDATE wykonany. Zmieniono " + ile + " rekordów.");
}
}
}
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