Lecture 5 - Wojciech Bieniecki
Download
Report
Transcript Lecture 5 - Wojciech Bieniecki
Advanced Java
Programming
Lecture 9
Databases in Java
•JDBC
•Hibernate
•JPA
dr inż. Wojciech Bieniecki
mgr inż. Michał Paluch
[email protected]
http://wbieniec.kis.p.lodz.pl
Introduction to JDBC
Used for accessing databases from JAVA applications
Information is transferred in two ways: from application to the database and vice versa
Four types of JDBC driver implementation
Type 1 drivers are translating JDBC on ODBC and are using ODBC driver to connect with
database.
JDK provides only one type of this driver: JDBC/ODBC bridge
Type 2 drivers has been written partly in JAVA and partly in their platform source code. In
communication process they are using client programming interface of their database
system.
Type 3 drivers has been written absolutely in JAVA.
In communication process they are using protocol independent from database system,
Type 4 drivers has been written absolutely in JAVA.
In communication process they are using protocol specific for database system.
JDBC usage
Traditional client – server model
Dataframe
Protocol
CLIENT
JDBC
Database
Server
JDBC usage
Three layered architecture
Database
Protocol
HTTP, RMI
CLIENT
(data presentation)
Intermediate layer
(business logic)
JDBC
Database
Server
Standard Query Language
SQL is a standard way to get access to all existing relational databases. Consists of:
●Data Manipulation Language (DML)
●Data Definition Language (DDL)
DML instructions
INSERT – instruction use to adds rows to a table.
INSERT into students values ('Smith', 'Anna', '21');
SELECT – select data from table
SELECT * from students WHERE age > 20
DELETE - removes a specified row
DELETE * from students WHERE
UPDATE - modifies an existing row
UPDATE students set grade = 5 where age < 22
DDL instructions
CREATE TABLE – allows to create a new table in database
TRUNCATE – cleans whole table
DROP TABLE – removes table from database
ALTER TABLE – modifies existing table
JDBC installation process
Download and install:
- Eclipse
- MySQL or PostgreSQL, Oracle, DB2
Add location of your database to system classpath
Create database and tables:
CREATE DATABASE ife;
use ife;
CREATE TABLE students (P_ID int, LastName varchar(15), FirstName
varchar(15), age int);
Download a driver into your Eclipse plugins location
Starting JDBC
You will need a proper connector (database dependent)
For MySQL use: mysql-connector-java-5.0.4-bin.jar
You may copy the file to jre\lib\ext directory
7
JDBC installation process
Set up driver in your project Build Path
(Build Path – Add library – Connectivity Driver
Definition - <your driver>
Register database driver class in your application code
(optional):
Class.forName( "com.mysql.jdbc.Driver" ).newInstance();
Setting up connection
import java.sql.*;
import java.io.*;
import java.util.*;
class MyJDBC{
public static void main (String args[]){
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/";
String u = "dbuser";
String p = "dbpass";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn =DriverManager.getConnection(url + "ife", u, p);
//
// Operations on a database
//
conn.close();//disconnected
} catch (Exception e){
e.printStackTrace();
}
}
}
Performing operations on the database
To be able to work on database we have to create Statement object
Statement stat = conn.createStatement();
Now we can create new database
stat.execute("CREATE TABLE country (count varchar(15))");
Insert data
stat.execute("INSERT INTO country VALUES ('Germany')")
Managing connections
Connection conn = //...
try{
statement stat =
conn.createStatement();
stat.executeUpdate("...");
}
finally
{
conn.close();
}
catch (SQLException e)
{
//...
}
ExecuteUpdate method
Can execute SQL operations such as:
●
INSERT
●
UPDATE
●
DELETE
●
CREATE TABLE
●
DROP TABLE
Example use of executeUpdate method
Statement stat = conn.createStatement();
String command = "update data SET age= age+1"
+ "Where name NOT LIKE '%Smith%'";
stat.executeUpdate(command);
Useful methods
ResultSet getResultSet()
Return ResultSet object which contains result of a
previous query
int getUpdateCount()
Returns the number of records which has been modified
by a previous command
ResultSet executeQuery(String sqlQuery)
Executes sql query given in string and returns ResultSet
object allowing to watch query result
Parameterized query
public static int addPerson(Connection con, Person p) throws
SQLException {
PreparedStatement ps = null;
try{
ps = con.prepareStatement("INSERT INTO PERSONS (PESEL,
IMIE, NAZWISKO, WIEK, DATA_ZAPISU) VALUES (?,?,?,?,?)");
ps.setString(1, p.getPesel());
ps.setString(2, p.getImie());
ps.setString(3, p.getNazwisko());
ps.setInt(4, p.getWiek());
ps.setDate(5, p.getDataZapisu());
return ps.executeUpdate();
} finally
{
if (ps != null)
ps.close();
}
15
}
Transactions in JDBC
The transaction consists of one or more commands that have been
invoked executed and confirmed (Commit) or rejected (rollback).
The transaction therefore constitutes an atom operation.
Transaction management is especially important,
when you want to perform several operations at once treating them
as one logical operation.
16
Transactions in JDBC
By default, the „auto commit” mode is set up for the connection.
Disabling „auto commit” requires ending the transactionusing methods
Connection.commit() or rollback()
Connection conn = DriverManager.getConnection(…);
conn.setAutoCommit(false);
…
…
conn.commit();
…
…
conn.rollback();
In JDBC there is no explicit method for starting the transaction.
The first SQL instruction executed after disabling auto commit or finishing the
previous transaction starts a new transaction.
17
Multiple queries processing
// Here create a JDBC connection „connection”
// . . . .
Statement stmt = connection.createStatement();
// Create statement object
try{
connection.setAutoCommit(false); // Start a new transaction
stmt.addBatch("Delete from user where user_id=3");
stmt.addBatch("UPDATE EMP SET JOB = 1");
stmt.executeBatch();
connection.commit(); // commit a transaction
}
catch (SQLException s){
System.out.println("SQL Exception " + s);
}
}
catch (Exception e){
e.printStackTrace();
}
SQL exceptions
BatchUpdateException
You’ll get it when you call the method executeBatch if:
•one of the SQL statements you added to the batch produces a result set (usually a query)
or
•one of the SQL statements in the batch does not execute successfully for some other
reason
●
SQLTransientException
●
SQLRecoverableException
●
SQLNonTransientException
●
SyncFactoryException
●
SQLWarning
●
RowSetWarning
Hibernate
●
●
●
●
Object-relational mapping tool (ORM) which
allows for persisting Java objects in a relational
database
Uses XML configuration files to configure
connectivity and map classes to database
tables
Uses Plain Old Java Objects (POJOs) classes
to map to the database table.
There is no need for implementing interfaces
Advanteges of using Hibernate
●
Open source framework
●
Convenient and intuitive mapping files
●
Simple operation rules
●
Work with classes and objects instead of queries
and result sets
●
Eliminate need for repetitive SQL
●
Generates DDL scripts to create DB schema
Hibernate Architecture
HIBERNATE ARCHITECTURE
Application
Persistence Object
Hibernate
Hibernate.properties
Database
XML Mapping
Hibernate Architecture
There are three main components:
●
●
●
●
●
●
Connection Management
Hibernate Connection management service provide
efficient management of the database connections.
Transaction management:
Provide the ability to the user, to execute more than
one database statements at a time.
Object relational mapping
A technique of mapping the data representation
from an object model to a relational data model.
Entity Java class
Includes get and set methods for class attributes – fields in table
class Entity
{
int id;
private void setId(int id)
{
this.id = id;
}
public int getId()
{
return id;
}
}
Mapping file (Work.hbm.xml)
<hibernate-mapping package="org.hibernate.tutorial.hbm">
<class table="EVENTS" name="Event">
<id name="id" column="EVENT_ID">
<generator class="increment"/>
</id>
<property name="date" column="EVENT_DATE" type="timestamp"/>
<property name="title"/> </class>
</hibernate-mapping>
Hibernate configuration file
(hibernate.cfg.xml)
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name="connection.url">
jdbc:hsqldb:data/tutorial
</property>
<property name="connection.username"> sa </property>
<property name="connection.password"> </property>
<property name="dialect">
org.hibernate.dialect.HSQLDialect
</property>
<property name="show_sql"> true </property>
<mapping resource="Class.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hibernate.cfg.xml
Fields names are intuitive. Most important is to set up the information about:
JDBC connector
Database URL
Username and password
SQL dialect
Mapping classes (*.hbm.xml files)
show_sql – allows printing SQL commands in the screen
Additional options:
<property name="hbm2ddl.auto">create</property>
- At the startup the database is created (destroyes previous content)
- update – updates database
27
Obtaining the
org.hibernate.SessionFactory
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sf = cfg.buildSessionFactory();
Usage pattern
Session s = sessionFactory.openSession();
Transaction tx = s.beginTransaction();
Entity ent = new Entity();
//example operations
ent.setTitle(title);
ent.setDate(Date);
//saving and commiting changes
s.save(Event);
tx.commit();
//closing session
s.close();
session.set(null);
Exemplary program
Persistence class "Student"
package org.hibernate.Student;
public class Student {
private String name;
private String lastName;
private long id;
public String getName(){return name;}
public String getLastName(){return lastName;}
public long getId() {return id;}
public void setName(String first) {name = first;}
public void setLastName(String last) {lastName = last;}
public void setId(long number){id = number;}
}
Mapping the Student object to
database (file Student.hbm.xml)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.hibernate.Student" table="STUDENT">
<id name="id" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="Name">
<column name="FIRSTNAME" />
</property>
<property name="lastName">
<column name="LASTNAME"/>
</property>
</class>
</hibernate-mapping>
Configuring Hibernate
(hibernate.cfg.xml)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- We will use database ife -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost/ife
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">dbPass</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
Configuring Hibernate
(hibernate.cfg.xml)
<!-- org.hibernate.dialect.MySQLDialect tells Hibernate that we
are using MySQL Database -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Mapping files -->
<mapping resource="Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Exemplary program
package org.hibernate.Student;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Example {
public static void main(String[] args) {
Session session = null;
try{
// application is reading from hibernate.cfg.xml
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
session = sessionFactory.openSession();
//Creating new instance of Student and setting values
Student student = new Student();
student.setId(1);
student.setName("John");
student.setLastName("Smith");
session.save(student);
}catch(Exception e){ System.out.println(e.getMessage()); }
finally { session.flush(); session.close(); }
}
}
Hibernate Query Language (HQL)
●
Syntax is similar to database SQL language.
The language is objective, possible usage of
inheritance and polymorphism.
●
●
HQL uses class name instead of table name
HQL uses property names instead of column
names
Examples of HQL use
SELECT query example will retrieve an age where age equals 24
Query query =
session.createQuery("select * from Student where age = :age ");
query.setParameter("age", "24");
List list = query.list();
Update query (updates students age to 25 if students last name is
Smith)
Query query = session.createQuery("update Student set age = :age" +
" where lastName = :lastName");
query.setParameter("age", 25);
query.setParameter("lastName", "Smith");
int result = query.executeUpdate();
Delete query (deletes student which name is Smith)
Query query =
session.createQuery("delete Student where lastName =:lastName");
query.setParameter("lastName", "Smith");
int result = query.executeUpdate();
Hibernate – Criteria
Criteria allow simple and intuitive way to reduce the number of records
returned.
You do not need to know the exact structure of the query language.
Query result is returned as a list. You have to attach the criteria for the
Persistence class name.
Criteria crit = sess.createCriteria(User.class);
crit.setMaxResults(50);
List users = crit.list();
Criteria can be added in cascade
List users = sess.createCriteria(User.class)
.add( Restrictions.like("name", "Now%") )
.add( Restrictions.between("age", minAge, maxAge)
).list();
37
Hibernate and SQL
Hibernate allows using of pure SQL if needed.
List users = sess.createSQLQuery(
"SELECT {us.*} FROM user us WHERE us.age = 17").list();
38
Hibernate – an advanced example
You may need to obtain the Hibernate librarties:
antlr-2.7.6rc1.jar
cglib-2.1.3.jar
commons-collections-2.1.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
ehcache-1.1.jar
hibernate3.jar
hsqldb.jar
jta.jar
c3p0-0.9.0.jar
Of course you have to get the JDBC driver
39
Hibernate – an advanced example
We will use HSQL DB engine
In the project directory you have to make a direcory data (at the
package directory level) and run a command line.
Run the database engine using
java -classpath lib/hsqldb.jar org.hsqldb.Server
After you run the application for the first time, please comment the
entry in hibernate.cfg.xml
<property name="hbm2ddl.auto">create</property>
.. Or change the value for „update”
After any change in the database structure restore the entry
40
HibernateUtil.java
A file for session management, opens and closes the factory.
package pl.lodz.p;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public final class HibernateUtil {
private HibernateUtil() {}
private static final SessionFactory SESSION_FACTORY;
static {
try {
SESSION_FACTORY = new
Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {/* init error*/ }
}
public static final ThreadLocal SESSION = new ThreadLocal();
41
HibernateUtil.java cont’d
public static Session currentSession() throws
HibernateException {
Session s = (Session)SESSION.get();
if (s == null) {
s = SESSION_FACTORY.openSession();
SESSION.set(s);
}
return s;
}
public static void closeSession() throws
HibernateException {
Session s = (Session)SESSION.get();
SESSION.set(null);
if (s != null) s.close();
}
}
42
EventManager.java
Creating connections with sql
package pl.lodz.p;
import java.io.Serializable;
import java.util.*;
import org.hibernate.*;
import pl.lodz.p.User;
public class EventManager {
43
EventManager.java
public long insertRecord(Object obj) throws Exception {
long id = -1;
Transaction tx = null;
try {
Session session = HibernateUtil.currentSession();
tx = session.beginTransaction();
session.save( obj );
Serializable ser = session.getIdentifier(obj);
if (ser != null) id = Long.parseLong( ser.toString()
);
tx.commit();
System.out.println("-> end insertRecord");
} catch (Exception ex) {
if (tx != null) tx.rollback();
id = -1;
throw ex;
} finally HibernateUtil.closeSession();
return id;
}
44
EventManager.java
public Object selectRecord(Class c, String id, boolean useTx)
throws Exception {
Object obj = null;
Transaction tx = null;
try {
System.out.println("- Start selectRecord");
Session session = HibernateUtil.currentSession();
if (useTx) tx = session.beginTransaction();
obj = session.get(c, new String(id));
if (useTx) tx.commit();
System.out.println("- end selectRecord");
} catch (Exception ex) {
if (tx != null) tx.rollback();
throw ex;
} finally {
HibernateUtil.closeSession(); }
return obj;
}
45
EventManager.java
public List selectRecords(String query, boolean useTx) throws
Exception {
List list = new ArrayList();
Transaction tx = null;
String methodName = "selectRecords";
try {
Session session = HibernateUtil.currentSession();
if (useTx) { tx = session.beginTransaction(); }
Query q = session.createQuery( query );
list = q.list();
if (useTx) { tx.commit(); }
System.out.println("- end selectRecords
list.size="+list.size());
} catch (Exception ex) {
if (tx != null) { tx.rollback(); }
throw ex;
} finally { HibernateUtil.closeSession(); }
return list;
46
}
}
User.java
Mapped class
Has accessors
private Long id;
private String imie;
private String nazwisko;
47
User.hbm.xml – mapping class
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate
Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping3.0.dtd">
<hibernate-mapping>
<class name="pl.lodz.p.User" table="USER">
<id name="id" column="USER_ID">
<generator class="native"/>
</id>
<property name="imie"/>
<property name="nazwisko"/>
</class>
</hibernate-mapping>
48
hibernate.cfg.xml – config file
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD
3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource="pl/lodz/p/User.hbm.xml"/>
</session-factory>
49
</hibernate-configuration>
ORM in depth - JPA
Java Persistence API (JPA) is another example of object-to-relation mapping (ORM). JPA is a
generalization of Hibernate. Here EclipseLink implementation will be used
In this tutorial, presented EclipseLink.
JPA allows to map a class to the relation and therefore place, update, and retrieve objects to
and from the database.
We call this process as persisting of objects
The implementation of JPA is called as persistence provider
JPA may be used both in Java-EE i Java-SE apps.
The process of mapping may be achieved with use of metadata.
The Metadata may be defined as an XML file (last example of Hibernate) or wit help
of annotations (or using both techniques).
In JPA we define a special query language HQL – similar to SQL.
JPA allows automatically create a database schema
Entity
The class being persisted must be annotated by javax.persistence.Entity.
Such a class is called an ENTITY
The instances of this class will be the records in the database table
Defining the entity requires:
- declaration of the member field which will be the primary key
- definitionon of the default constructor
- the class must not be final
JPA allows creation of the primary key using the annotation
@GeneratedValue
By default the name of the entity is the name of the table. We may change it using the
annotation
@Table(name="NEWTABLENAME").
Entity – persisting the fields
All or some fields of the entity may be persisted in the database.
JPA uses or the values of the fields or their accesors. We must not mix these two
solutions.
Using accessors requires the application of JavaBeans name conventions.
By default, JPA persists all members of the entity, unless they are annotated by:
@Transient
By default each field is mapped to a column of the same name. We may change it using
the annotation
@Column(name="newColumnName")
@Id
The primary key of the table
@GeneratedValue
Together with the key it it means that the value
will be generated (autonumber)
@Transient
The field will not be stored in the database
Mapping of the relation
JPA allows defining relations between the classes (class composition). There may be
the following types of the relations:
-one-to-one – annotated by @OneToOne
-one-to-many – annotated by @OneToMany
-many-to-one – annotated by @ManyToOne
-many-to-many – annotated by @ManyToMany.
A relation can be unidirectional or multidirectional.
In a bidirectional relation, both dependent classes hold references each to other.
In unidirectional relation one class stores a reference to the other.
In case of bidirectional relation the owner of the relation must be defined
@ManyToMany(mappedBy="attributeOfTheOwningClass").
Interfaces used by JPA
PersistenceManagerFactory: main object used to get access to the persistence
manager
– the initialization at the level of application
– the initialization using parameters in the file of properties
PersistenceManager: main object used for storing, reading and deletion of the
objects.
States of the object
Managing the object
EntityManagerFactory factory =
Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
Persisting of the object
Employee e = new Employee(...);
pm.makePersistent(e)
Deletion of the object
Employee e = pm.getObjectById(id);
pm.deletePersistent(e);
Detach of the object
Employee ee = pm.detachCopy(e);
Attach of the object
Employee eee = pm.makePersistent(ee);
Example of mapping classes to a table
Project setup
Get the JDBC connectior, for instance mysql-connector-java-5.1.22-bin.jar
From eclipse.org get EclipseLink.
We’ll need the files
- eclipselink.jar
- javax.persistence_*.jar
Create a new project and add the libraries to it
In the src directory create a directory META-INF.
Create a package for the entity (required)
Example of mapping classes to a table
Entity creation – inside the package
package test;
import javax.persistence.*;
@Entity
public class Notatka {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String tytul;
private String opis;
public String getTytul()
{ return tytul;
}
public void setTytul(String tytul) { this.tytul = tytul;}
public String getOpis()
{ return opis;
}
public void setOpis(String opis)
{ this.opis = opis; }
@Override
public String toString() {
}
return "Notatka " + tytul + ": " + opis;
}
Example of mapping classes to a table
Creation of Persistence Unit – w the directory META-INF create the file
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="Notatki" transaction-type="RESOURCE_LOCAL">
<class>test.Notatka</class>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/test" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>
</persistence-unit>
</persistence>
Example of mapping classes to a table
A test class
import java.util.List;
import javax.persistence.*;
import test.Notatka;
public class Main {
public static void main(String[] args) {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("Notatki");
EntityManager em = factory.createEntityManager();
// read the content of the table
Query q = em.createQuery("select t from Notatka t");
List<Notatka> todoList = q.getResultList();
for (Notatka todo : todoList) {
System.out.println(todo);
}
System.out.println("Size: " + todoList.size());
// create a new note
em.getTransaction().begin();
Notatka todo = new Notatka();
todo.setTytul("Zakupy");
todo.setOpis("Kupić kartofle w Carfour");
em.persist(todo);
em.getTransaction().commit();
em.close();
}
}
Using relations – Family entity
package test;
import java.util.*;
import javax.persistence.*;
@Entity
public class Family {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private int id;
private String description;
@OneToMany(mappedBy = "family")
private final List<Person> members = new ArrayList<Person>();
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getDescription() { return description; }
public void setDescription(String description)
{
this.description = description;
}
public List<Person> getMembers() { return members; }
}
61
An example of relations – the entityPerson
package test;
import java.util*;
import javax.persistence.*;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private String id;
private String firstName;
private String lastName;
private Family family;
private String nonsenseField = "";
private List<Job> jobList = new ArrayList<Job>();
public String getId() {
return id; }
public void setId(String Id) {
this.id = Id; }
public String getFirstName() {
return firstName; }
public void setFirstName(String firstName) {
this.firstName = firstName;
}
// Leave the standard column name of the table
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName;
}
62
An example of relations – the entityPerson (cont’d)
@ManyToOne
public Family getFamily() { return family; }
public void setFamily(Family family) { this.family = family; }
@Transient
public String getNonsenseField() { return nonsenseField;
public void setNonsenseField(String nonsenseField) {
this.nonsenseField = nonsenseField;
}
}
@OneToMany
public List<Job> getJobList() {
return this.jobList;
}
public void setJobList(List<Job> nickName) {
this.jobList = nickName;
}
}
63
An example of relations – the entity Job
package test;
import javax.persistence.*;
@Entity
public class Job
{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private int id;
private double salary;
private String jobDescr;
public int getId()
{
return id; }
public void setId(int id)
{ this.id = id; }
public double getSalary()
{ return salary; }
public void setSalary(double salary)
{ this.salery = salary; }
public String getJobDescr()
{ return jobDescr; }
public void setJobDescr(String jobDescr){this.jobDescr = jobDescr;}
}
64
An example of relations – persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="people" transaction-type="RESOURCE_LOCAL">
<class>test.Person</class>
<class>test.Family</class>
<class>test.Job</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/test" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="update-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
</persistence>
65
An example of relations – test class
import javax.persistence.*;
import test. Family;
import test.Person;
public class Main {
private EntityManagerFactory factory;
public void setUp() throws Exception {
factory = Persistence.createEntityManagerFactory("people");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin(); //nowa transakcja
Query q = em.createQuery("select m from Person m"); //lista rekordów
boolean createNewEntries = (q.getResultList().size() == 0);
if (createNewEntries) {// No, so lets create new entries
Family family = new Family();
family.setDescription("Family for the Knopfs");
em.persist(family);
for (int i = 0; i < 40; i++) {
Person person = new Person();
person.setFirstName("Jim_" + i);
person.setLastName("Knopf_" + i);
em.persist(person);
family.getMembers().add(person);
em.persist(person);
em.persist(family);
}
}
em.getTransaction().commit();
em.close();
}
66
An example of relations – test class cont’d
public void checkAvailablePeople()
{
EntityManager em = factory.createEntityManager();
Query q = em.createQuery("select m from Person m");
// We should have 40 Persons in the database
System.out.println(q.getResultList().size());
em.close();
}
public void checkFamily()
{
EntityManager em = factory.createEntityManager();
Query q = em.createQuery("select f from Family f");
// We should have one family with 40 persons
System.out.println(q.getResultList().size());
System.out.println(((Family)q.getSingleResult()).getMembers().size());
em.close();
}
67
An example of relations – test class cont’d
public void deletePerson()
{
EntityManager em = factory.createEntityManager();
// Begin a new local transaction so that we can persist a new entity
em.getTransaction().begin();
Query q = em
.createQuery("SELECT p FROM Person p WHERE p.firstName = :firstName AND
p.lastName = :lastName");
q.setParameter("firstName", "Jim_1");
q.setParameter("lastName", "Knopf_!");
Person user = (Person) q.getSingleResult();
em.remove(user);
em.getTransaction().commit();
Person person = (Person) q.getSingleResult();
// Begin a new local transaction so that we can persist a new entity
em.close();
}
}
68