Pokročilé programování na platformě Java, letní semestr 2012
Transkript
JAVA
JDBC
Java, letní semestr 2012
11.4.2012
Přehled
●
●
rozhraní pro přístup k relační databázi
jednotné
–
nezávislé na databázi
●
●
umožňuje
–
–
vykonávání SQL dotazů
přístup k výsledkům dotazů
●
●
podobné reflection API
balíky
–
–
●
výrobce databáze musí dodat JDBC driver
java.sql
javax.sql
verze
– JDK 1.1
– JDK 1.2
– JDK 1.4
Java, letní–semestr
2012
JDK
6
11.4.2012
– JDBC 1.0
– JDBC 2.0
– JDBC 3.0
– JDBC 4.0
JDBC Driver
●
JDBC API
–
–
●
driver
–
–
●
v podstatě jen rozhraní
implementace dodána přes driver
explicitně natáhnout a zaregistrovat
Class.forName("com.driver.Name");
po natažení driveru, vytvořit připojení na DB
–
–
Connection con = DriverManager.getConnection(url,
"myLogin", "myPassword");
url
●
●
jdbc:mysql://localhost/test
jdbc:odbc:source
Java, letní semestr 2012
11.4.2012
JDBC Driver
●
4 typy driveru
–
–
–
–
JDBC-ODBC bridge plus ODBC driver
Native-API partly-Java driver
JDBC-Net pure Java driver
Native-protocol pure Java driver
Java, letní semestr 2012
11.4.2012
Základní třídy a rozhraní
●
DriverManager – třída
–
–
všechny metody jsou statické
getConnection()
●
–
getDrivers()
●
–
–
všechny natažené drivery
getLogWriter(), setLogWriter()
println()
●
–
několik variant
zapis do logu
getLoginTimeout(), setLoginTimeout()
Java, letní semestr 2012
11.4.2012
Základní třídy a rozhraní
●
Connection – interface
–
●
vytváření a vykonávání dotazů
ResultSet – interface
–
výsledky dotazu
Java, letní semestr 2012
11.4.2012
Základní příklad
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost/test", "","");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM
test");
while (rs.next()) {
// zpracování výsledků po řádcích
}
stmt.close();
con.close();
Java, letní semestr 2012
11.4.2012
Přístup k výsledkům
●
podbné reflection API
–
–
–
getString(), getInt(),...
pracuje se nad aktuálním řádkem
identifikace sloupce pomocí
●
●
jména
pořadí
ResultSet rs = stmt.executeQuery("SELECT ID,
NAME FROM TEST");
while (rs.next()) {
int id = rs.getInt("ID");
String s = rs.getString("STRING");
System.out.println(id + " " + s);
}
Java, letní semestr 2012
11.4.2012
Přístup k výsledkům
●
ResultSet.next()
–
●
musí být zavoláno i na první řádek
getString()
–
lze volat na všechny typy
●
–
nelze na nové SQL3 typy
automatická konverze na String
Java, letní semestr 2012
11.4.2012
Dotazy
●
Connection.createStatement()
–
●
Statement.executeQuery("....")
–
–
●
vytvoření dotazu ("prázdného")
pro dotazy vracející vysledky (SELECT)
výsledky přes ResultSet
Statement.executeUpdate("...")
–
pro dotazy nevracející výsledky
●
●
●
UPDATE
CREATE TABLE
…
Java, letní semestr 2012
11.4.2012
PreparedStatement
●
PreparedStatement
–
–
–
interface
dědí od Statement
předpřipravený dotaz s parametry
●
–
vyplní se před použitím
metody
●
●
setType(int index, type v)
clearParameters()
PreparedStatement pstmt =
con.prepareStatement("UPDATE EMPLOYEES SET
SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)
Java, letní semestr 2012
11.4.2012
Transakce
●
implicitně – auto-commit mód
–
●
commit se provede po každé změně
auto-commit lze zrušit
con.setAutoCommit(false);
//
// posloupnost změn
//
con.commit();
// nebo con.rollBack()
con.setAutoCommit(true);
Java, letní semestr 2012
11.4.2012
Callable Statements
●
●
pro přístup k uloženým procedurám
dědí od PreparedStatement
–
nastavení parametrů
●
–
návratový typ nutno zaregistrovat
●
–
setType(int index, type v)
registerOutParameter(int index, int sqlType)
formát
a)
b)
{?= call <procedure-name>[<arg1>,<arg2>, …]}
{call <procedure-name>[<arg1>,<arg2>, …]}
CallableStatement cs = con.prepareCall("{call
SHOW_SUPPLIERS}");
ResultSet rs = cs.executeQuery();
Java, letní semestr 2012
11.4.2012
Ošetření chyb
●
SQLException
–
–
a její potomci
String getSQLState()
●
–
int getErrorCode()
●
●
definováno X/Open
specifický pro konkrétní databázi
varování (warnings)
–
–
–
SQLWarning
není to výjimka
nutno explicitně testovat
●
●
Statement.getWarnings()
SQLWarning.getNextWarning()
Java, letní semestr 2012
11.4.2012
Batch update
●
●
zpracování více dotazů najednou
Statement.addBatch(String sql)
–
●
přidá dotaz do dávky
int[] Statement.executeBatch();
–
–
provede dávku
vrací počet ovlivněných řádků pro každý dotaz v dávce
Java, letní semestr 2012
11.4.2012
Updatable ResultSet
●
implicitní ResultSet nelze měnit, lze se pohybovat
pouze vpřed
–
lze změnit při vytváření Statementu
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT ...");
–
výsledný ResultSet lze měnit, lze se v něm volně
pohybovat, nejsou v něm vidět změny od ostatních
uživatelů
Java, letní semestr 2012
11.4.2012
Java DB
●
●
http://www.oracle.com/technetwork/java/javadb/
Oraclem podporovaná distribuce databáze Apache
Derby
–
●
●
http://db.apache.org/derby/
kompletně v Javě
lze používat
–
–
samostatně jako server
uvnitř jiné aplikace
●
snaha o malou spotřebu paměti (~ 2MB)
●
existují i jiné databáze napsané v Javě
Java, letní semestr 2012
11.4.2012
Objektové databáze
●
●
●
●
●
●
●
ne-relační databáze
ukládaní a vyhledávání objektů
vlastní přístup bez JDBC
NeoDatis
db4o
…
příklad pro NeoDatis
Sport sport = new Sport("volley-ball");
ODB odb = ODBFactory.open("test.neodatis");
odb.store(sport);
Objects<Player> players = odb.getObjects(Player.class);
odb.close();
Java, letní semestr 2012
11.4.2012
ORM
●
problém s OO databázemi
–
–
●
jednoduché na použití
nepříliš výkonné, nepříliš podporované,...
řešení – ORM
–
–
–
(object-relational mapping)
vrstva mapující relační databázi na objekty
zjednodušeně
●
●
–
JDBC se typicky používá uvnitř
●
–
třída ~ schéma tabulku
objekt ~ řádek v tabulce
automaticky
Hibernate
●
●
http://hibernate.org/
nejpoužívanější ORM pro Javu
–
Java, letní semestr 2012
11.4.2012
implementace i pro další technologie
JAVA
Práce s XML
Java, letní semestr 2012
11.4.2012
Přehled
●
JAXP – Java API for XML Processing
–
–
čtení, zápis a transformaci XML
SAX, DOM, XSLT
●
–
podle W3C
podporuje různé implementace
●
referenční implementace součástí JDK
–
●
JDOM
–
–
●
http://www.jdom.org/
„zjednodušený“ DOM pro Javu
JAXB – Java Architecture for XML Binding
–
●
lze použít jiné
mapování XML <=> Java objekty
Elliotte Rusty Harold: Processing XML with Java
– http://www.cafeconleche.org/books/xmljava/
kniha
Java, letní–semestr
2012 – volně ke stažení
11.4.2012
JAXP – přehled
●
balíky
–
–
–
–
●
SAX (Simple API for XML)
–
–
–
–
●
javax.xml.parsers
org.w3c.dom
org.xml.sax
javax.xml.transform
průchod přes XML dokument element po elementu
na každém elementu něco provést
rychlé, nenáročné na paměť
složitější na použití
DOM
–
–
–
postaví z dokumentu strom v paměti
jednoduché na použití
pomalé, náročné na paměť
Java, letní semestr 2012
11.4.2012
22
SAX
Java, letní semestr 2012
11.4.2012
23
DOM
Java, letní semestr 2012
11.4.2012
24
DOM: použití
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
// vytvoří celý strom v paměti
Document document = builder.parse("file.xml");
Element root = document.getDocumentElement();
NodeList nl = root.getChildNodes();
for (int i=0; i<nl.length(); i++) {
Node n = nl.item(i);
...
}
Java, letní semestr 2012
11.4.2012
25
SAX: použití
class MyHandler extends DefaultHandler {
void startDocument() {
...
}
void endDocument() {
...
}
void startElement(....) {
...
}
...
}
SAXParserFactory factory =
SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
saxParser.parse("file.xml", new MyHandler() );
Java, letní semestr 2012
11.4.2012
26
Implementace
●
●
existují různé implementace JAXP
DocumentBuilderFactory.newInstance() i
SAXParserFactory.newInstance()
–
–
uvnitř používají ServiceLoader
varianta
newInstance(String factoryClassName,
ClassLoader classLoader)
●
hledá danou třídu
Java, letní semestr 2012
11.4.2012
27
JDOM – Přehled
●
●
●
http://www.jdom.org/
API pro XML
přímo pro Javu
–
●
●
●
používá std. API z Javy (kolekce,...)
jednoduché na používání
rychlé
"light-weight"
Java, letní semestr 2012
11.4.2012
28
Použití
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(filename);
Element root = doc.getRootElement();
List children = current.getChildren();
Iterator iterator = children.iterator();
while (iterator.hasNext()) {
Element child = (Element) iterator.next();
...
}
Java, letní semestr 2012
11.4.2012
29
JAXB – přehled
●
●
automatické mapovaní mezi XML dokumenty a Java
objekty
princip
–
Java třídy a odpovídající XML schema
●
–
lze vygenerovat třídy ze schematu i obraceně
použití
●
●
●
vytvoření Java objektů z XML (unmarshaling)
práce s Java objekty
uložení Java objektů do XML (marshaling)
Java, letní semestr 2012
11.4.2012
30
JAXB – příklad
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="2.0">
<xsd:element name="Greetings" type="GreetingListType"/>
<xsd:complexType name="GreetingListType">
<xsd:sequence>
<xsd:element name="Greeting" type="GreetingType"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="GreetingType">
<xsd:sequence>
<xsd:element name="Text" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="language" type="xsd:language"/>
</xsd:complexType>
Java,
letní semestr 2012
</xsd:schema>
11.4.2012
31
JAXB – příklad
●
vygenerování tříd
–
xjc -p hello hello.xsd
Java, letní semestr 2012
11.4.2012
32
JAXB – příklad
public class Hello {
private ObjectFactory of;
private GreetingListType grList;
public Hello(){
of = new ObjectFactory();
grList = of.createGreetingListType();
}
public void make( String t, String l ){
GreetingType g = of.createGreetingType();
g.setText( t );
g.setLanguage( l );
grList.getGreeting().add( g );
}
public void marshal() {
try {
JAXBElement gl = of.createGreetings( grList );
JAXBContext jc = JAXBContext.newInstance( "hello" );
Marshaller m = jc.createMarshaller();
m.marshal( gl, System.out );
} catch( JAXBException jbe ){ … }
}
} letní semestr 2012
Java,
11.4.2012
33
JAXB – příklad
Hello h = new Hello();
h.make( "Bonjour, madame", "fr" );
h.make( "Hey, you", "en" );
h.marshal();
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Greetings>
<Greeting language="fr">
<Text>Bonjour, madame</Text>
</Greeting>
<Greeting language="en">
<Text>Hey, you</Text>
</Greeting>
</Greetings>
Java, letní semestr 2012
11.4.2012
34
JAVA
Scripting API
Java, letní semestr 2012
11.4.2012
Přehled
●
podpora skriptovacích jazyku přímo z Javy
–
–
–
integrace skriptů do Java programu
volání skriptů
používání Java objektů ze skriptu
●
–
●
…
JSR 223
–
●
a obraceně
Scripting for the JavaTM Platform
od Java 6 přímo součástí JDK
–
součástí JDK je i Mozilla Rhino engine
●
●
–
implementace JavaScript jazyka v Javě
implementuje rozhraní JSR 223
existuje mnoho implementací pro další jazyky
●
stačí dát JAR balík na CLASSPATH
Java, letní semestr 2012
11.4.2012
Proč
●
jednotné rozhraní pro všechny skriptovací jazyky
–
●
dříve si každá implementace řešila rozhraní po svém
snadné požívání skr. jazyků
–
–
–
–
proměnné „bez“ typů
automatické konverze
…
programy není nutno kompilovat
●
●
existence „shelů“
použití
–
–
–
–
složitější konfigurační soubory
rozhraní pro „administrátora“ aplikace
rozšiřování aplikace (pluginy)
skriptování v aplikaci
●
obdoba jako JS v prohlížeči, VBScript v office,...
Java, letní semestr 2012
11.4.2012
Použití
●
●
balíček javax.scripting
ScriptEngineManager
–
–
●
základní třída
nalezení a získání instance skript. enginu
základní použití
–
–
–
instance ScriptEngineManegeru
nalezení požadovaného enginu
spuštění skriptu pomocí metody eval()
Java, letní semestr 2012
11.4.2012
Hello world
public class Hello {
public static void main(String[] args) {
ScriptEngineManager manager =
new ScriptEngineManager();
ScriptEngine engine =
manager.getEngineByName("JavaScript");
//ScriptEngine engine =
manager.getEngineByExtension("js");
//ScriptEngine engine =
manager.getEngineByMimeType("application/javascript");
try {
engine.eval("println( \"Hello World!\");" );
System.out.println(
engine.eval( " 'Hello World again!' "));
} catch(ScriptException e) { ... }
}
}
Java, letní semestr 2012
11.4.2012
Přehled funkčnosti
●
skript
–
–
●
řetězec nebo znakový stream (reader)
vyhodnocení přes ScriptEngine.eval()
interface Compilable
–
jeho implementace volitelná
●
–
●
kompilace skriptu do byte-code
interface Invocable
–
jeho implementace volitelná
●
–
●
otestovat – instanceof Compilable
otestovat – instanceof Invocable
volání metod a funkcí ze skriptů
Bindings, ScriptContext
–
prostředí pro vykonávání skriptů
●
mapování proměnných sdílených mezi Javou a skriptem
Java, letní semestr 2012
11.4.2012
Získání enginu
●
(1)
ScriptEngineManager.getEngineFactories()
–
seznam všech ScriptEngineFactory
for (ScriptEngineFactory factory :
engineManager.getEngineFactories()) {
System.out.println("Engine name: " + factory.getEngineName());
System.out.println("Engine version: " +
factory.getEngineVersion());
System.out.println("Language name: " +
factory.getLanguageName());
System.out.println("Language version: " +
factory.getLanguageVersion());
System.out.println("Engine names:");
for (String name : factory.getNames()) {
System.out.println(" " + name);
}
System.out.println("Engine MIME-types:");
for (String mime : factory.getMimeTypes()) {
System.out.println(" " + mime);
}
}
Java, letní semestr 2012
11.4.2012
Získání enginu
●
ScriptEngineFactory.getEngine()
●
nebo přímo
●
●
●
ScriptEngineManager.getEngineByName()
ScriptEngineManager.getEngineByExtension()
ScriptEngineManager.getEngineByMimeType()
Java, letní semestr 2012
11.4.2012
(2)
Skripty
●
vykonání skriptu
–
–
●
Object ScriptEngine.eval( String s, ...
Object ScriptEngine.eval( Reader r, …
předávání proměnných (základní varianta)
–
–
–
void ScriptEngine.put(String name, Object value)
Object ScriptEngine.get(String name)
POZOR na konverze typů!
Java, letní semestr 2012
11.4.2012
Předávání proměnných
●
interface Bindings
–
–
●
extends Map<String,Object>
základní implementace – SimpleBindings
interface ScriptContext
–
–
–
prostředí, ve kterém se skripty vykonávají
základní implementace – SimpleScriptContext
obsahuje scopes
●
–
speciální scopes
●
●
–
–
scope = Binding
ENGINE_SCOPE – lokální pro ScriptEngine
GLOBAL_SCOPE – globální pro EngineManager
getAttribute(..) / setAttribute(..) odpovídají
getBindings(..).get / put
lze nastavit standardní Reader a Writery (vstup a
výstup) pro skript
Java, letní semestr 2012
11.4.2012
Předávání proměnných
zdroj obrázku: http://www.javaworld.com/javaworld/jw-04-2006/jw-0424-scripting.html
Java, letní semestr 2012
11.4.2012
Volání funkcí/metod
●
interface Invocable
–
–
volitelná funkčnost, je třeba testovat (instanceof)
poskytuje
●
●
●
volání funkcí skriptu z Java kódu
volání metod objektů skriptu z Java kódu, pokud je
skriptovací jazyk objektový
implementace Java interface funkcemi (metodami)
skriptu
ScriptEngine engine = manager.getEngineByName("javascript");
Invocable inv = (Invocable) engine;
engine.eval("function run() { println( 'funkce run'); };");
Runnable r = inv.getInterface(Runnable.class);
(new Thread(r)).start();
engine.eval("var runobj = { run: function()
{ println('metoda run'); } };");
o = engine.get("runobj");
r = inv.getInterface(o, Runnable.class);
(new Thread(r)).start();
Java, letní semestr 2012
11.4.2012
JavaScript engine v JDK
●
●
Mozilla Rhino engine
některé funkce odstraněny (nebo nahrazeny)
–
●
(1)
převážně z důvodů bezpečnosti
vestavěné funkce pro import Java balíčků
–
importPackage(), importClass()
●
●
–
balíčky přístupné přes Packages.JmenoBalíčku, pro
nejpoužívanější balíčky jsou definované zkratky
(proměnné): java (ekvivalentní Packages.java), org,
com, ..
java.lang není importován automaticky (možné konflikty
objektů Object, Math, ..)
objekt JavaImporter
●
pro ukrytí importovaných prvků do proměnné (předchází
konfliktům)
var imp = new JavaImporter( java.lang, java.io);
Java, letní semestr 2012
11.4.2012
JavaScript engine v JDK
●
Java objekty v js
–
–
●
(2)
vytváří se stejně jako v Javě
var obj = new Trida( ...)
Javovské pole v js
–
–
–
vytvoříme přes Java Reflection
var pole = java.lang.reflect.Array.newInstance( ..)
dále pracujeme běžně: pole[i], pole.length, …
var a = java.lang.reflect.Array.newInstance( java.lang.String, 5);
a[0] = "Hello"
●
anonymní třídy
–
anonymní implementace Java rozhraní
var r = new java.lang.Runnable() {
run: function()
{
println( "running...");
}
};
var th = null;
th = new java.lang.Thread( r);
Java, letní semestr th.start();
2012
11.4.2012
JavaScript engine v JDK
●
anonymní třídy (pokrač.)
–
(3)
autokonverze funkce na rozhraní s jednou metodou
function func() {
println("I am func!");
};
th = new java.lang.Thread( func);
th.start();
Java, letní semestr 2012
11.4.2012
JavaScript engine v JDK
●
(4)
přetížené Java metody
–
–
–
připomenutí
overoading se děje při překladu (javac)
při předání JavaScriptových proměnných Java
metodám vybere script engine správnou variantu
výběr můžeme ale ovlivnit
●
●
objekt[“název_metody(typy parametrů)”](parametry)
pozor! řetězec bez mezer!
Java, letní semestr 2012
11.4.2012
Další enginy
●
existuje velké množství hotových enginů
–
–
awk, Haskell, Python, Scheme, XPath, XSLT, PHP,...
použití
●
●
●
stáhnout JAR
dát JAR na CLASSPATH
vytvoření vlastního enginu
–
implementace API
●
nutno implementovat alespoň
–
–
–
ScriptEngineFactory
ScriptEngine
zabalení do JAR
●
přidat soubor
META-INF/services/javax.script.ScriptEngineFactory
–
Java, letní semestr 2012
11.4.2012
ScriptEngineManager používá ServiceLoader
Podobné dokumenty
Embedded SQL v C/C++ úvod
Prekompilátor Pro*C/C++ (proc) tyto
dotazy nahradí voláním funkcí
standardní run-time knihovny
(SQLLIB) a převede soubor.ps do
čistého C/C++.
soubor.c
Dále se už kód překládá jako
„obyčejný“ céčkov...
Data mining
dbf.setNamespaceAware(false);
dbf.setValidating(false);
dbf.setFeature("http://xml.org/sax/features/namespaces", false);
dbf.setFeature("http://xml.org/sax/features/validation", false);
dbf.setFeat...
Rozhraní SAX, SAX vs. SAX2
Při volání metody parse nejprve XMLFilterImpl
zaregistruje u parseru sebe (implementuje všechny handler
rozhraní). Poté deleguje na parser volání parse.
Metody startElement,... definované třídou
XM...
Seminár Java VIII
Hlavní typy rozhraní pro zpracování XML dat:
Stromově orientovaná rozhraní (Tree-based API)
Rozhraní založená na událostech (Event-based API)
Rozhraní založená na "vytahování" událostí/prvků z do...
Práce s databází
b) Typ 2 - připojení prostřednictvím kódu nativního klienta pro přístup k síti ......................2
c) Typ 3 připojení prostřednictvím vrstvy aplikačního serveru ...................................
sql včera a dnes
ISO/IEC 9075-13:2008 Part 13: SQL Routines and Types Using the
Java Programming Language (SQL/JRT) – 210 stránek
– Definice použití jazyka java přímo v databázích