Java ain't Scary - introducing Java to PL/SQL programmers

advertisement
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…
Download