AMIS - 5th April 2012 JAVA AIN’T SCARY INTRODUCING JAVA TO PL/SQL PROGRAMMERS OVERVIEW • • • • • • • • • Hello World! Running Java on the JVM Language basics: Methods, Variables & simple Types Debugging Quiz Dinner Introduction to Java Objects A little inheritance Scratching the surface of – Java to Database communication (JDBC) – Http to Java communication (Servlet) HELLO WORLD • Create a PL/SQL program unit that writes Hello World! to the system output procedure hello_world is begin dbms_output.put_line('Hello World!'); end; • Create a Java program unit that writes Hello World! to the system output void hello_world() { System.out.println("Hello World!"); } THE CONTEXT FOR THE HELLO_WORLD PROGRAM UNIT • Create the PL/SQL Package that contains the hello_world program unit create or replace package welcome • Create the Java Class that contains the helloWorld program unit package nl.amis; public class Welcome { procedure hello_world; end welcome; -- end specification create or replace package body welcome public void helloWorld() { System.out.println("Hello World!"); } } procedure hello_world is begin dbms_output.put_line('Hello World!'); end; end welcome; -- end body HOW TO RUN THE HELLO_WORLD PROGRAM UNIT (PL/SQL) • In the context of a database connection, invoke the procedure through the package specification begin welcome.hello_world; end; PL/SQL VM (Oracle7, 1993) PL/SQL VM PL/SQL VIRTUAL MACHINE • Ever since Oracle7, the Oracle RDBMS contains a PL/SQL Virtual Machine • That means: write [PL/SQL] once, run anywhere (as long as the RDBMS is running) • This portability of PL/SQL across platforms is pretty extraordinary! PL/SQL JAVA VIRTUAL MACHINE (JVM) • Java is executed by the JVM (Java Virtual Machine) • On almost any platform, a platform specific JVM is available • Java is written once, then executed unchanged on the JVM on the target platform • ‘write once, run anywhere’ was the tagline for Java Java HOW TO RUN THE HELLOWORLD PROGRAM UNIT (JAVA) • Start JVM and instruct it to run a Java Class – More specifically: to invoke the main method of the designated Java Class: java nl.amis.Welcome package nl.amis; public class Welcome { public static void helloWorld() { System.out.println("Hello World!"); } public static void main(String[] args) { Welcome.helloWorld(); } } • In JDeveloper: CTRL + F11 RUNNING HELLO_WORLD • Connect to PLSQL VM (i.e. the database) and execute anonymous PL/SQL block • Start JVM and execute main method ... begin welcome.hello_world; end; public static void main(String[] args) { Welcome.helloWorld(); } ... ABOUT THE JVM • Java is compiled at design time into byte code – held in .class files (one .class per .java file) • The platform specific JVM loads class files (from .class or from JAR • Note: byte code (classes) can be created in other ways too besides from Java code – For example from Groovy, JRuby, BeanShell, Jython and various other languages – The JVM is not correctly named! ABOUT THE JVM (2) • Byte code is not machine language: the platform independent byte code is interpreted in the target JVM and turned into platform specific actions • Note: Byte code (‘class files’) can be decompiled • Note: there is no ‘dynamic Java’ such as execute immediate ‘Java fragment’ HABITAT OF THE JVM CLASS • Program Unit for Java – Similar to PL/SQL package • Class with Main method can be executed – Other classes and methods only invoked from within Java code • Execute means: having JVM load, instantiate & invoke • In JDeveloper, run means – Compile Java code (.java) into byte code (.class) – Call Java run time (JVM) with instruction to execute class • Which in turn means: invoke main method of the class METHODS • Functions are called methods • A method that does not return a value (a procedure in PL/SQL terms) is defined with void as return type: public void helloWorld() { System.out.println("Hello World!"); } • Methods can be public, protected, default or private – Determining accessibility from outside class and from outside package (similar to PL/SQL’s package specification and body) SOME LINGO AND OTHER JAVA TID BITS • Java is case sensitive • It is common practice to use ‘camel case’ for naming classes, methods and variables (and not underscores) public void helloWorld() { System.out.println("Hello World!"); { } } • { and } are used to indicate the start and end of code segments (where PL/SQL uses begin and end) – Such as methods, nested blocks in if, else, loops etc. – {} can be empty (similar to PL/SQL: begin null; end;) • Note: the indentation is not meaningful to the Java compiler – only to the human eye SOME STRIKING – AND UNIMPORTANT – DISTINCTIONS BETWEEN JAVA AND PL/SQL PL/SQL Assignment := Java • Java = Equality = == String concatenation || + String quoting ' " IF construct if then [else ] end if if () {} [else {}] Logical operators AND , OR, NOT &&, ||, ! Comment -- and /* … */ // and /* … */ l_name varchar2(20):= 'John'; -- nice name is it not? begin if l_name = 'Hank' then l_name:= l_name || 'B.'; end if; end; { // what wonderful name this is String name = "John"; if (name == "Hank") { name = name + "B."; } } VARIABLES • Global – defined (anywhere) at class level – accessible from any method – class level variables can be public – meaning they are accessible from outside the class • Local – defined (anywhere) inside a method – only accessible within the method package nl.amis; public class Welcome { private String lastName = "Doe"; public String greeting = "Hello"; public static void helloWorld() { String firstName = "John"; System.out.println(greeting + firstName + lastName); } } VARIABLES • Definition of a variable is reversed compared to PL/SQL: – first the type then the name • variables are not constrained through their definition (such as VARCHAR2(250) in PL/SQL) • some native types have built-in limitations: byte, short, integer, long, float, double, boolean package nl.amis; public class Welcome { byte short int long smallNumber = 127; notThatShort = 32767; // 16 bits substantialNumber = 2147483647; // 32 bits potentiallyLargeNumber = 0; // 64 bits, 9,2 trillion // floating point values: float fractured = 0.1f; // single-precision 32-bit, e+38 double verySmallAndVeryLarge = -0.1; // 64 bits, e+308 boolean itsNotALie = false; } PRINT THE FACTORIALS FOR 1..10 PL/SQL begin factorials.main(10); end; create or replace package factorials as procedure main (p_upper in number); end factorials; create or replace package body factorials as function factorial(p_i in number) return number is begin if (p_i<2) then return 1; else return p_i * factorial(p_i-1); end if; end factorial; procedure printFactorials(p_upper in number) is begin for i in 0..p_upper loop dbms_output.put_line(i || '! = ' || factorial(i)); end loop; end printFactorials; procedure main(p_upper in number) is begin Factorials.printFactorials(10); end main; end factorials; PRINT THE FACTORIALS FOR 1..10 Java java.exe -classpath C:\JavaAintScary\classes nl.amis.Factorials public class Factorials { private static int factorial(int i) { if (i<2) return 1; else return i * factorial(i-1); } private static void printFactorials( int upper) { for (int i=0; i<upper; i++) { System.out.println ( i + "! = " + factorial(i)); } } public static void main(String[] args) { Factorials.printFactorials(10); } } PRINT THE FACTORIALS FOR 1..10 PL/SQL create package body factorials as Java public class Factorials { function factorial(p_i in number) return number is begin if (p_i<2) then return 1; else return p_i * factorial(p_i-1); end if; end factorial; private static int factorial(int i) { if (i<2) return 1; else return i * factorial(i-1); } procedure printFactorials (p_upper in number) is begin for i in 0..p_upper loop dbms_output.put_line(i || '! = ' || factorial(i)); end loop; end printFactorials; private static void printFactorials ( int upper) { for (int i=0; i<upper; i++) { System.out.println ( i + "! = " + factorial(i)); } } procedure main(p_upper in number) is begin Factorials.printFactorials(10); end main; end factorials; public static void main(String[] args) { Factorials.printFactorials(10); } } DEBUGGING JAVA IN JDEVELOPER • Java code running in a JVM can be remote debugged • That means for example that JDeveloper can listen in to the execution of Java classes and methods – Pausing at breakpoints – Inspecting objects and variables – Inspecting the call stack – Manipulating values – Changing code ‘on the fly’ DEBUGGING IN ACTION SOME LOOPING CONSTRUCTS PL/SQL declare i number := 0; f number := 1; begin loop -- alternative: -- while i < 10 loop dbms_output.put_line (i || '! = '|| f); exit when i = 9; -- not needed -- when using the while loop i:= i+ 1; if i=1 then continue; -- 11g command end if; f:= f * i; end loop; end; Java { int i = 0; int f = 1; for (; ; ) { // alternative // while (i<10) do { System.out.println(i + "! = " + f); if (i == 9) break; // not needed // when using the while loop i++; if (i == 1) continue; f = f * i; } //for } SOME LOOPING CONSTRUCTS PL/SQL declare step number := 2; begin -- print numbers 10, 8, 6, 4, 2 for i in reverse 1..5 loop -- STEP does not exist in PL/SQL -- for i in reverse 1..5 step 2 loop dbms_output.put_line(i*step ); end loop; end; Java { for (int i = 10; i>1 ; i=i-2) { System.out.println(i); } } OTHER LANGUAGE CONSTRUCTS PL/SQL function divide( p_a in number , p_b in number) return number is BEGIN return p_a / p_b; EXCEPTION WHEN ZERO_DIVIDE THEN dbms_output.put_line ('Trying to divide by zero'); raise; END; DECLARE l_a NUMBER := 6; l_b NUMBER := 0; begin dbms_output.put_line(' result of division: ' || divide(l_a, l_b)); exception when others then dbms_output.put_line (' Some exception was returned!'); end; Java private static float divide( int a,int b) { try { return a/b; } catch (ArithmeticException ae) { System.out.println(ae.getMessage()); throw ae; } } public static void division() { int a = 6, b = 0; try { System.out.println("result of division: " + divide(a, b)); } catch (Exception e) { System.out.println("Some exception was returned!"); } } DECODE… • PL/SQL declare l_gender varchar2(1):= 'F'; begin dbms_output.put_line ( decode( l_gender , 'F','FEMALE' ,'MALE' ) ); end; declare l_gender varchar2(1):= 'F'; begin dbms_output.put_line ( case l_gender when 'F' then 'FEMALE' else 'MALE' end ); end; • Java // using a ternary expression ... { String gender ="F"; System.out.println ( gender=="F" ? "FEMALE" : "MALE" ); } ... THAT BIG THING ABOUT JAVA… Objects…. THE PERSON CLASS: “MOTHER OF MANY OBJECTS” public class Person { private private private private String String int String firstName; lastName; salary; gender; public String displayLabel() { return (gender=="M" ? "Mr." : "Mrs.") + firstName + " " + lastName; } } QUIZ TIME • What is the meaning of the acronym ‘JVM’ • What is meant by ‘write once, run anywhere’? • In which environments can you run Java? • How do you get from a .java file to a running program doing things? QUIZ TIME • What is wrong with this Java statement? string label_value = 'John' + 'Doe ' ; -- assign name QUIZ TIME • What is the PL/SQL equivalent of this Java snippet? { int i = 0; for (; ; ) { System.out.println(i++); if (i == 9) break; } } declare i integer := 0; begin loop dbms_output.put_line(i); i:= i+ 1; exit when i = 9; end loop; end; declare i number := 0; begin loop dbms_output.put_line(i); i:= i+ 1; declare exit when i == 9; i number := 0; end loop; begin end; loop dbms_output.put_line(i); i:= i+ 1; if i = 9 then break; end loop; end; QUIZ TIME • What is wrong with this Java statement? { for (int i = 10; i>1 ; i=i--) { System.Out.println(i); } } QUIZ TIME • What is the output from running this Java statement? package nl.amis; public class DoIt { private String lastName = "Obama"; public String greeting = "Hello"; public static void main( String[] args) { String firstName = "Michelle"; System.out.println(greeting + "Mrs." + firstName); } } java.exe -classpath C:\JavaAintScary\classes nl.amis.DoIt DINNER JAVA OBJECTS create or replace package thing as procedure set_value (p_value in varchar2); begin dbms_output.put_line ('value = '||thing.get_value); end; function get_value return varchar2; end thing; create or replace package body thing as g_value varchar2(100):= 'VALUE'; procedure set_value (p_value in varchar2) is begin g_value := p_value; end set_value; function get_value return varchar2 is begin return g_value; end get_value; begin g_value:= 'initialized value'; end thing; begin thing.set_value('hello world'); dbms_output.put_line ('value = '||thing.get_value); end; begin dbms_output.put_line ('value = '||thing.get_value); end; Package THING get_value set_value Database Session 1 Database Session 2 SEPARATION OF (SHARED) CODE AND INSTANCE DATA SHARED MEMORY Package THING get_value set_value PER SESSION MEMORY UGA UGA UGA Session 1 Session 2 Session 3 THING.g_value [Hello World] THING.g_value [Goodbye World] THING.g_value [initialized value] Database Session 1 Database Session 2 Database Session 3 PACKAGE AND MULTIPLE USER SESSIONS • • • • Package state is kept in UGA – Different sessions have different state for package globals – Note: with dbms_session.reset_package, all packages in the sessions are ‘de-instantiated’ Global variable is not really global – it means ‘retained across multiple calls in the same user session’ – not across sessions – Note: true global values can be achieved using Globally Accessible Application Context When a package is first called in a session, its initialization section is executed – And global variables assume default values – The package is ‘instantiated within the session’: the UGA starts to hold values for the globals Question: what is global about a GLOBAL TEMPORARY TABLE? THING IN JAVA create or replace package thing as procedure set_value (p_value in varchar2); public class Thing { public void setValue(String value) { this.value = value; } function get_value return varchar2; public String getValue() { return value; } end thing; create or replace package body thing as g_value varchar2(100):= 'VALUE'; String value = "VALUE"; procedure set_value (p_value in varchar2) is begin g_value := p_value; end set_value; function get_value return varchar2 is begin return g_value; end get_value; begin g_value:= 'initialized value'; end thing; public Thing() { value = "initialized value"; } } public class Thing { public void setValue(String value) { this.value = value; } create or replace package thing as procedure set_value (p_value in varchar2); function get_value return varchar2; public String getValue() { return value; } end thing; String value = "VALUE"; public Thing() { value = "initialized value"; } begin dbms_output.put_line ('value = '||thing.get_value); thing.set_value('hello world'); dbms_output.put_line ('value = '||thing.get_value); end; public static void main(String[] args) { Thing thing = new Thing(); System.out.println ("value = "+ thing.getValue()); thing.setValue("Hello World"); System.out.println ("value = "+ thing.getValue()); } } MULTIPLE THING INSTANCES WITH EACH ITS INSTANCE DATA public class Thing { public class ThingRunner { public void setValue(String value) {public static void main(String[] args) { this.value = value; Thing thing = new Thing(); } System.out.println ("value = "+ thing.getValue()); public String getValue() { thing.setValue("Hello World"); return value; System.out.println } ("value = "+ thing.getValue()); Thing thing2 = new Thing(); String value = "VALUE"; System.out.println ("value (2) = "+ thing2.getValue()); public Thing() { thing2.setValue("Goodbye World"); value = "initialized value"; System.out.println } ("value (2) = "+ thing2.getValue()); System.out.println } ("value = "+ thing.getValue()); } } SEPARATION OF (SHARED) CODE AND INSTANCE DATA SHARED Class THING getValue setValue INSTANCES thing thing 2 value [Hello World] value [Goodbye World] CLASS AND OBJECTS • A class is like a PL/SQL package: the template for an instance – At run time, the class is instantiated before its methods can be executed • An instantiated class is called:…. an object – During instantiation: members (global variables) are instantiated and initialization code can be executed • The Constructor method Class THING getValue setValue Object thing3 value Object thing value Object thing2 value Object thing4 value • Note: this also applies to objects in the Oracle Database: – Create type as object …. TRUE GLOBAL IN JAVA • Truly Global means: shared between all instances of a class in a JVM • Anything in Java designated ‘static’ is truly global or shared between all objects based on the same class SHARED Class THING static value INSTANCES thing thing 2 value value TRUE GLOBAL IN JAVA public class Thing { static String value = "VALUE"; public void setValue(String value) { this.value = value; } public String getValue() { return value; } public Thing() { value = "initialized value"; } } Class THING static value Object thing value Object thing2 value INSTANTIATING A PERSON (OBJECT) public class Person { private private private private String String int String firstName; lastName; salary; gender; public String displayLabel() { return (gender=="M" ? "Mr." : "Mrs." ) + firstName + " " + lastName; } } public static void main(String[] args) { Person p = new Person(); System.out.println(p.displayLabel()); } INSTANTIATING A PERSON AND SETTING PERSONAL PROPERTIES public class Person { private private private private String String int String firstName; lastName; salary; gender; public static void main(String[] args) { public void setFirstName (String firstName) { this.firstName = firstName; } public String getFirstName() { return firstName; } Person p = new Person(); p.setFirstName("John"); p.setLastName("Doe"); p.setGender("M"); System.out.println(p.displayLabel()); } public void setLastName(String lastName) ...// getters and setters for all properties public String displayLabel() { return (gender=="M" ? "Mr." : "Mrs." ) + firstName + " " + lastName; } } PASSING A PERSON TO A METHOD package nl.amis; public class PersonalAssistant { public static void printPersonalLabel ( Person person) { System.out.println ( (person.getGender()=="M" ? "Mr." : "Mrs.") + person.getFirstName() + " " + person.getLastName() ); } } public static void main(String[] args) { Person p = new Person(); p.setFirstName("John"); p.setLastName("Doe"); p.setGender("M"); PersonalAssistant.printPersonalLabel(p); } NOTES ON STATIC METHODS • Methods can be designated static too • Static methods can only access static class members (that means: variables that are also static in the Class) • A static method can be invoked on the Class – you do not first need to instantiate an object public static void main(String[] args) { ... PersonalAssistant.printPersonalLabel(p); } vs. public static void main(String[] args) { ... PersonalAssistant pa = new PersonalAssistant(); pa.printPersonalLabel(p); } MULTIPLE PEOPLE public static void main(String[] args) { Person p = new Person(); p.setFirstName("John"); p.setLastName("Doe"); p.setGender("M"); Person p2 = new Person(); p2.setFirstName("Jane"); p2.setLastName("Doe"); p2.setGender("F"); System.out.println(p.displayLabel()); System.out.println(p2.displayLabel()); } Class Person … displayLabel Person p firstName John lastName Doe Gender M Person p2 firstName Jane lastName Doe Gender F TWO TYPES OF VARIABLES • Variables can contain a value such as a number or boolean – Primitive types: byte, short, integer, long, float, double, boolean • Variables can also contain a reference to an object – Built-in Classes such as Byte, Short, Integer, Long, Float, Double, Boolean, Date – Custom classes such as Person and Thing • String is a special beast: it is an object reference but has also some primitive behavior – For example: create String with simple assignment, without new to instantiate a new String ... String value = "VALUE"; public Thing() { value = "initialized value"; } METHODS ON THE BUILT-IN STRING CLASS • Methods on a String METHOD CHAINING • Using various methods on String String someString = "Hello"; someString = someString.concat(" World "); someString = someString.replaceAll("Hello", " someString = someString.toUpperCase(); someString = someString.trim(); System.out.println(someString); Goodbye"); • When a method returns an object, a method can be invoked on that object – and when that method also returns an object .. String someString = "Hello"; someString = someString.concat(" World "). replaceAll("Hello", " Goodbye").toUpperCase().trim(); System.out.println(someString); PRIMITIVE VARIABLES AND PARAMETERS • Primitives are just a value 1.2312 FALSE 255 – Assigning one variable to another leads to copying the value 255 • Passing a primitive variable as parameter to a method means passing a copy of the value 59182 – Primitive parameters are read-only – there is no equivalent to in out or out parameters 255 OBJECT VARIABLES AND PARAMETERS • Object variables are references to objects <pointer> Person <pointer> Person – Multiple references to the <pointer> same object can exist – When no references exist any longer, the object will be garbage collected (eventually) • Passing an object variable as parameter means passing a read-only copy of the object reference – The object itself is editable! <pointer> PERSONAL DETAILS • There is more to a Person than a few simple properties Social Profile Person Email Address[es] • Person properties can be – References to other objects (such as a social profile) – Collections of values or object references (such as email addresses) INTRODUCING CLASS SOCIALPROFILE Social Profile Person Email Address[es] INTRODUCING CLASS EMAILADDRESS Social Profile Person Email Address[es] PERSON WITH HIS DETAILS Social Profile Person Email Address[es] CREATING A COMPLEX PERSON Person p = new Person("John", "Doe", 4500, "M"); p.getSocialProfile().setBlog("http://johndoe.blogspot.com"); p.getSocialProfile().setMsn("JohnnyDoe_234"); p.getEmailAddresses().add(new EmailAddress("johnny.doe@gmail.com","P")); p.getEmailAddresses().add(new EmailAddress("john.p.doe@acmecorp.com","W")); Social Profile Person Email Address[es] QUICK COLLECTION OVERVIEW AND COMPARISON declare type string_tbl_t is table of varchar2(200); l_names string_tbl_t:= string_tbl_t(); l_index number; begin l_names.extend(); l_names(1):= 'Tobias'; l_names.extend(); l_names(l_names.last):= 'Lex'; l_index:= l_names.first; loop exit when l_index is null; dbms_output.put_line (' Name '||l_index||' : ' ||l_names(l_index) ); l_index := l_names.next(l_index); end loop; end; ... List<String> names = new ArrayList<String>(); names.add("Tobias"); names.add("Lex"); int index = 1; for (String name:names) { System.out.println ("Name "+index+++" : "+name); }//for } PERSONAL DETAILS Social Profile Person Employee Email Address[es] Customer ENTITY RELATIONSHIP MODELING PERSON SOCIAL_PROFILE EMPLOYEE EMAIL_ADDRESS CUSTOMER OBJECT ORIENTED DESIGN PERSON EMPLOYEE 1 0..1 1 0..* CUSTOMER SOCIAL_PROFILE EMAIL_ADDRESS CODE FOR SUB CLASSES public class Employee extends Person { private String job; private int departmentId; private Date hiredate; // getters and setters } public class Customer extends Person { private String companyName; private String telephoneNumber; // getters and setters } PERSONAL ASSISTANT: CAN IT DEAL WITH EMPLOYEES AND CUSTOMERS? package nl.amis; public class PersonalAssistant { } public static void printPersonalLabel ( Person person) { System.out.println ( (person.getGender()=="M" ? "Mr." : "Mrs.") + person.getFirstName() ? + " " + person.getLastName() ); } public static void main(String[] args) { Employee e = new Employee(); e.setFirstName("John"); e.setLastName("Doe"); e.setGender("M"); e.setJob("Manager"); PersonalAssistant.printPersonalLabel(e); } AN INSTANCE OF A SUB CLASS IS ALSO AN INSTANCE OF ITS SUPERCLASS(ES) • Of course each Employee and every Customer is also a Person! • A method that accepts the superclass as input, will be able to process instances of the subclass just fine – Ask for Person, and get Customer or Employee is OK • Note: the reverse is not true: when the required input is a specialized sub type, then a supertype instance is not good enough – Ask for Customer and get a Person is NOT OK public static void printEmployeeLabel ( Employee employee) { System.out.println ( employee.getJob() + " in department " Person p = new Person(); + employee.getDepartmentId() p.setFirstName("John"); ); p.setLastName("Doe"); } p.setGender("M"); PersonalAssistant.printEmployeeLabel(p); ANY METHOD & PROPERTY DEFINED ON THE SUPERCLASS ALSO EXISTS FOR A SUBCLASS • Properties and methods on Person class are inherited by the subclasses Employee and Customer public class Person { private private private private ... String String int String firstName; lastName; salary; gender; public class Employee extends Person { private String job; private int departmentId; private Date hiredate; // getters and setters } Employee e = new Employee(); e.setFirstName("John"); e.setLastName("Doe"); e.setGender("M"); e.setJob("Manager"); e.setDepartmentId(10); OVERRIDING METHODS IN THE SUBCLASS – PROVIDING A SPECIALIZED IMPLEMENTATION • Methods can be overridden in a sub class – the sub class has its own version of the method with the exact same signature – invoking the method on an instance of the sub class results in execution of the specialized implementation – note: the sub class implementation can invoke the super class method too Person displayLabel() Employee displayLabel() public class Employee extends Person { ... public String displayLabel() { return super.displayLabel() + " (" + this.job+")"; } public class Person { ... public String displayLabel() { return (gender=="M" ? "Mr." : "Mrs." ) + firstName + " " + lastName; } } PRINTING THE EMPLOYEE DISPLAYLABEL • The Employee displayLabel method is both – the Employee’s special (overridden) implementation – as well as the super’s (Person’s) original version Person displayLabel() Employee displayLabel() Employee e = new Employee(); e.setFirstName("John"); e.setLastName("Doe"); e.setGender("M"); e.setJob("Manager"); e.setDepartmentId(10); System.out.println( e.displayLabel()); IMPERSONATING AN EMPLOYEE? • When a method accepts a handle to a Person object public String personalLabel(Person p) { return p.displayLabel(); } • and it receives a handle to a specialized type of Person – an Employee (no less) Employee e = new Employee(); e.setFirstName("John"); e.setLastName("Doe"); e.setGender("M"); e.setJob("Manager"); e.setDepartmentId(10); System.out.println( personalLabel()); • it will invoke the specialized, overridden method EMPLOYING A PERSON? • When a method accepts a handle to a Person object public String inspectPerson(Person p) { } • it can determine if the Person is just a Person or someone more special… public String inspectPerson(Person p) { if (p instanceof Employee) { return "Employee"; } else if (p instanceof Customer) { return "Customer"; } else { return "Person"; } } CASTING A PERSON IN THE ROLE OF EMPLOYEE • When a method accepts a handle to a Person object public String inspectPerson(Person p) { } • and it has determined that the Person is someone more special – an Employee – it can also address the Employee capabilities of the Person object public static void printSpecialPersonalLabel ( Person person) { String label = (person.getGender()=="M" ? "Mr." : "Mrs.") + person.getFirstName() + " " + person.getLastName(); if (person instanceof Employee) { label = label + " ("+ ((Employee)person).getJob()+")"; } if (person instanceof Customer) { label = label + " ("+ ((Customer)person).getCompanyName()+")"; } System.out.println(label); } CASTING IS SIMILAR TO CONVERSION IN PL/SQL • PL/SQL has explicit (to_number, to_char) and implicit conversion – similar to casting in Java declare i varchar2(10) := '21'; function add( p1 in number, p2 in varchar2) return number is begin return p1 + p2; end add; begin dbms_output.put_line(add(i,21)); end; • The keyword cast is also explicitly used in PL/SQL declare l_timestamp TIMESTAMP := cast ('05-Apr-2012 09.00.00.00 PM ' as TIMESTAMP ); l_number number(2) := cast ('21' as number); l_names string_table; begin select cast ( multiset(select ename from emp) as string_table) into l_names from dual; TECHNICAL OBJECT HIERARCHY • For example: RichTable class from ADF Faces: DESIGN BY CONTRACT • A contract is specification of the functionality that is (or will be) provided by some implementation – Without stipulating details about how the implementation is done – And sometimes well before the implementation is done • For consumers the contract is enough to create the software that relies on the functionality create or replace package calculator as function add( p1 in number, p2 in number) return number; function multiply( p1 in number, p2 in number) return number; end calculator; DESIGN BY CONTRACT IN JAVA INTRODUCING THE JAVA INTERFACE • The contract dictating functionality in Java is called an Interface – It defines methods – without providing implementations for those methods package nl.amis public interface Calculator { public int add( int p1, int p2); public int multiply(int p1, int p2); } • Classes can implement no, one or multiple Interfaces – And extend from only one super-class • Any interface can be implemented by multiple classes CODING TO THE INTERFACE – INVOKING THE INTERFACE WITHOUT IMPLEMENTATION • Classes can invoke the ‘interface’ without knowledge about the actual classes that implement the contract public class Worker { private Calculator calculator; // instance of the interface public void tableOfMultiplication( int table) { for (int i=1;i<=10;i++) { System.out.println( i +" * "+ table + " = " + calculator.multiply(i, table)); } } Calculator public void setCalculator(Calculator calculator) { this.calculator = calculator; } public static void main(String[] args) { Worker worker = new Worker(); worker.setCalculator(new SpecialCalculator()); worker.tableOfMultiplication(5); } } IMPLEMENTING THE INTERFACE • Any class can implement an interface (or more than one) if it publishes the required methods package nl.amis; public class SpecialCalculator extends Object implements Calculator , SecondContract { public int add(int p1, int p2) { return p1 + p2; } public int multiply(int p1, int p2) { return p1 * p2; } // defined in interface SecondContract public String remove(String s1, String s2) { return s1.replaceAll(s2, ""); } } } LEVERAGE METHODS FROM OTHER INTERFACES AS WELL • Testing if an object implements an interface is done using instanceof • Invoking methods from an interface on an object can be done by casting the object to the interface public class Worker { public static void main(String[] args) { Calculator calculator = new SpecialCalculator(); if (worker.calculator instanceof SecondContract) { System.out.println(((SecondContract)calculator).remove ("HELLO WORLD", "O")); }//if } } OVERVIEW • • • • • • • • • Hello World! Running Java on the JVM Language basics: Methods, Variables & simple Types Debugging Quiz Dinner Introduction to Java Objects A little inheritance Scratching the surface of – Java to Database communication (JDBC) – Http to Java communication (Servlet) JAVA APPLICATIONS & DATABASE Cache “NO SQL” Plain JDBC Ibatis, Spring JPA (Hibernate) JDBC RDBMS EJB (CMP) WS* Data Grid JDBC – JAVA DATABASE CONNECTIVITY • Using a JDBC Driver… • Any Java program can create a connection to almost any relational database – Connecting to a schema using a password, just like Forms, SQL*Plus or an APEX browser session – Note: most databases have their own, special JDBC drivers • Through that connection, the Java program can query, do DML and invoke Stored Procedures and Functions • Java programs can handle long running transactions and sessions QUERY EMPLOYEE DETAILS • Execute SQL Query via JDBC – process ResultSet: public static void main(String[] args) throws SQLException { Connection connection = ConnectionManager.getConnection(); // Get a statement from the connection Statement stmt = connection.createStatement(); // Execute the query ResultSet rs = stmt.executeQuery("SELECT empno,ename, sal FROM emp"); // Loop through the result set while (rs.next()) { System.out.println(rs.getInt(1) + " : " + rs.getString(2) + " (salary = " + rs.getFloat(3) + ")“ ); }//while // Close the result set, statement // and the connection rs.close(); stmt.close(); connection.close(); } PL/SQL PACKAGE PROCESSING AN HTTP REQUEST: THE EMBEDDED PL/SQL GATEWAY • The Database (the PL/SQL VM) can handle HTTP requests via the Embedded PL/SQL Gateway • HTTP requests are routed to a custom PL/SQL Package that writes the (usually HTML response) • The EPG infrastructure handles the actual HTTP response to the invoker E P G htp Custom PL/SQL package JAVA CLASS PROCESSING AN HTTP REQUEST: THE SERVLET • The JVM can handle HTTP requests via the Servlet Container • HTTP requests are routed to a custom Java Class that writes the (usually HTML response) • The Servlet infrastructure handles the actual HTTP response to the invoker JVM Greeter WebLogic Server HELLO WORLD SERVLET public class HelloWorldServlet extends HttpServlet { private static final String CONTENT_TYPE = "text/html; charset=utf8"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head><title>Hello World</title></head>"); out.println("<body>"); out.println("<h1>Hello World!</h1>"); out.println("</body></html>"); out.close(); } } SERVLET WITH PARAMETERS public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name =null; Object nameParam = request.getParameter("name"); if (nameParam!=null) { name = (String)nameParam; } response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head><title>Hello World</title></head>"); out.println("<body>"); if (name!=null) { out.println("<h1>Hello "+name+"!</h1>"); } else { out.println("<h1>Hello World!</h1>"); } out.println("</body></html>"); out.close(); } DEMO OF SERVLET THAT WRITES EMPLOYEES TO THE BROWSER PAGE public void doGet(HttpServletRequest request, • HTTP request with department HttpServletResponse response)idthrows ServletException, IOException { • Response is HTML page with a list of employees in the Integer departmentIdentifier = null; department if (request.getParameter("departmentId") != null) { departmentIdentifier = Integer.parseInt(request.getParameter("departmentId")); } List<String> employeeDetails = new EmployeesCoordinator(). getEmployeeDetails(departmentIdentifier); response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head><title>Employees</title></head>"); out.println("<body>"); out.println("<h1>Employees</h1>"); out.println("<ul>"); for (String employee : employeeDetails) { out.println("<li>" + employee + "</li>"); } out.println("</ul>"); out.println("</body></html>"); out.close(); } DEMO OF SERVLET THAT WRITES EMPLOYEES TO THE BROWSER PAGE public class EmployeesCoordinator { HTTP request with department id departmentId) { public• List<String> getEmployeeDetails(Integer List<String> employees = new ArrayList<String>(); • Response is HTML page with a list of employees in Connection connection; try { department connection = ConnectionManager.getConnection(); PreparedStatement stmt = connection.prepareStatement ("SELECT empno,ename, sal FROM emp WHERE deptno = nvl(?, deptno)"); if (departmentId != null) { stmt.setInt(1, departmentId); // set bind parameter value } ResultSet rs = stmt.executeQuery(); // Loop through the result set while (rs.next()) { employees.add( rs.getInt(1) + " : " + rs.getString(2) + " (salary = " + rs.getFloat(3) + ")"); } // while rs.close(); stmt.close(); connection.close(); } catch (SQLException e) {} // when others then null; return employees; } } the SUMMARY • Java is a 3GL programming language – Similar to PL/SQL in many respects • Java runs on a JVM - available on almost any platform – PL/SQL runs on database (PL/SQL VM) • JDeveloper is an IDE (one of many) – Support for edit/refactor/compile/run/debug/… • Java Class contains properties and methods – Just like PL/SQL package • Instances of a Class are called Objects – Each Object has ‘state’ (like PL/SQL package in each database session) • Class can have Sub Classes: more specialized – Sub Classes inherit methods and properties and add (or override) – Similar to Sub Types in ERD SUMMARY (2) • In Java the contract that specifies the functionality provided by a Class is called Interface – Similar to the PL/SQL Package Specification • An object can be cast in a specific role (to a Class or Interface) if it is an instanceof that Class or Interface – Similar to conversion or casting in PL/SQL • Through JDBC – Java programs can access relational databases and execute SQL & call PL/SQL • Servlets are Java Classes that process HTTP Requests and return HTTP Responses – for example to browser – Similar to PL/SQL packages accessed through EPG (database embedded PL/SQL gateway) NEXT STEPS • ‘get your hands dirty’ • Internet • Head First Java • Download & Install JDeveloper from OTN • AMIS Training “Java for PL/SQL Developers” (5 day) BUT FIRST…