Warning
This page is located in archive.

JAVA – modely ve SWINGu, JDBC, příklad volání SELECT,INSERT

JAVA - Modely v SWINGu

  • Moderní návrh aplikace rozlišuje 3 úrovně (MVC)
    • Model - návrh datových struktur, jejich efektivní reprezentace/uložení, výpočty
    • View - návrh vizualizace výsledků, egronomie aplikace (menu, formuláře)
    • Controler - implementace ovládání, syrová funkcionalita
  • Pro složitější datové struktury SWING nabízí modely [ základní třída (abstraktní třída, třída s již implementovanými listenery)] :
    • pro seznam ListModel ( AbstractListModel,DefaultListModel )
    • pro tabulku TableModel (AbstractTableModel,DefaultTableModel )
      • DefaultTableModel(Vector data, Vector columnNames);
      • DefaultTableModel(Object[][] data, Object[] columnNames);
      • int getRowCount(); definováno v AbstractTableModel
      • int getColumnCount(); definováno v AbstractTableModel
      • Object getValueAt(int rowIndex, int columnIndex); definováno v AbstractTableModel
      • void setValueAt(Object aValue, int rowIndex, int columnIndex); definováno v TableModel
  • Při návrhu modelu - otázkou, co držet v paměti, co počítat (optimalizace na zvolenou platformu)
  • Kolik paměti potřebujete na uložení násobilky 10 ?
  • Ukázky použití modelů v praxi:
  • Bean and Table Demo 4 od Petra Pošíka

Připojení aplikace k DB systému

  • pro připojení a práci s databází se používá
    • nativních funkcí daného databázového systému
      • specializovaná komponenta, příp. třídy (například NPgSQL pro C# pro PostgreSQL)
    • speciálního ovladače (driveru / resp. connectoru) pro danou databázi
      • ODBC (Open Database Connectivity), JDBC (Java Database Connectivity)
      • poskytuje jednotné API pro všechny databáze (například JDBC pro Javu pro PostgreSQL)

Příklad - Ukázka zpracování SQL v Javě

package PisDemo;
import java.sql.*;
import javax.swing.*;
public class PrvniSQLPokus {
  private Connection connection;
  private Statement statement; 
  public PrvniSQLPokus() {
          try {
          // nejdříve zaregistujeme JDBC driver [[http://jdbc.postgresql.org//| org.postgresql.Driver ]]            
          Class.forName("org.postgresql.Driver");
          //vytvoříme connection - připojení k databázi
          connection = DriverManager.getConnection("jdbc:postgresql://screwdriver.felk.cvut.cz:5432/pisdemo","pisdemo","pisdemopass");
          //nyní už lze s databází pracovat přímo přes API JDBC
          pridej();
          //uzavřeme connection!!!
          connection.close();
      } catch(Exception e) {
          e.printStackTrace();
      }   
  }
  private log getPosledni() {
      try {
          // provedeme vyber max. hodnoty id_sez v tabulce seznam
          // pokud id_sez pro nas znamená identifikátor, tak tohle nam "může pomoci jako" obdoba automatického čísla
          // vytvoříme Statement - příkaz pro databázi
          Statement statement1 = connection.createStatement();
          // pomocí metody executeQuery  zašleme příkaz databázi a databáze nám vrátí výsledek, který uložíme do rSet
          ResultSet rSet = statement1.executeQuery("select max(id_sez) from seznam");
          // začneme zpracovávat výsledek - metoda standartně vrací true, pokud se skutečne posune na další prvek výsledku
          rSet.next();
          // načteme 1. sloupec z výsledku
          long id_sez_last = rSet.getLong(1);
          // a uzavřeme Statement
          statement1.close();
          return id_sez_last;
      }
      catch (SQLException e) {
          JOptionPane.showMessageDialog(null, "Nepodařilo se získat výsledek!","Error",JOptionPane.ERROR_MESSAGE);
          return 0;
      }
 }
  private void pridej() {
      try {
          // pro nacteni je minimalne potrebne pouzivat prepareStatement
          // znacne nam pomuze v odfiltrovani nekorektního zadávání
          // připravíme si "předpřipravený" příkaz jako "šablonu"
          PreparedStatement statement2 = connection.prepareStatement("insert into seznam (id_sez, jmeno, prijmeni, vek) values (?, ?, ?, ?)");
          // vyplníme data do šablony
          statement2.setLong(1, getPosledni()+1);
          statement2.setString(2, "Petra");
          statement2.setString(3, "Novakova");
          statement2.setInt(4, 20);
          // zašleme příkaz databázi (na tento typ dotazu neočkáváme výsledek)
          statement2.execute();
          // a uzavřeme
          statement2.close();
      }
      catch (SQLException e) {
          JOptionPane.showMessageDialog(null, "Nepodařilo se přidat záznam!","Error",JOptionPane.ERROR_MESSAGE);
          return;
      }
  }
  public static void main(String[] args) {
      new PrvniSQLPokus();
  } 
}

SQL Injection - a neb takto ne

Představme si, že máme systém, jehož funkcionalita je založena na autentifikaci uživatele - seznam uživatelů je v tabulce uzivatel

Fragment příslušného kódu může vypadat např takto:

  private void prihlaseni( String uzivatelskeJmeno,uzivatelskeHeslo) {
      try {
          Statement statement1 = connection.createStatement();
          // vytvoříme si dotaz
          String dotaz ="SELECT  * FROM uzivatel WHERE jmeno = '" + uzivatelskeJmemo+"' AND heslo = "' + uzivatelskeHeslo  + "'";
          //a pomocí metody executeQuery jej zašleme databázi
          ResultSet rSet = statement1.executeQuery(dotaz);
          // pokud databáze vrátí neprázdný výsledek, zvítězili jsme
          if (rSet.next())
             provedVseNutneProPrihlaseni(rSet);
          else
             JOptionPane.showMessageDialog(null, "Chybné přihlášení!","Error",JOptionPane.ERROR_MESSAGE);
          // a uzavřeme Statement
          statement1.close();
      }
      catch (SQLException e) {
          JOptionPane.showMessageDialog(null, "Chyba při přihlašování!","Error",JOptionPane.ERROR_MESSAGE);
          return ;
      }
 }

Co je špatně?

courses/x33mis/cviceni/02.txt · Last modified: 2013/10/04 13:02 (external edit)