pBeans2 Persistence Layer
Object Relational Mapping (ORM) for Java
(Now even easier)
Overview
pBeans is a Java persistence layer and an object/relational
database mapping (ORM) framework. It is designed to be simple to use and automated.
The idea is that you save time and effort by simply focusing on writing
Java classes, and not worrying about maintenance of matching SQL scripts,
schema evolution,
XML based schemas, or generating code. The pBeans framework takes care
of persisting JavaBeans with little assistance from the developer.
Major features
- Automatic Table Creation and Schema Evolution.- Tables corresponding to JavaBean classes
are created on demand. Field types are based, by default, on JavaBean compile-time
types. Field type changes and new fields are detected. Manually changing tables (user-managed mode)
is also supported.
- Based on Annotated JavaBeans.- You define a getter and setter for each bean
property. Persisent bean classes only need to be tagged with a @PersistentClass
annotation.
- Transitive Persistence.- If object A is persisted and it refers
to Persistent object B, then object B is automatically persisted. If Persistent
object C also refers to B, and C is also persisted, the record for object B in the database is not
duplicated.
- Instance Consistency.- If you retrieve an object from persistent
storage that is already known to exist in main memory, you get a reference
to the object in main memory. (Garbage collection is allowed to happen via weak references.)
- Near-Zero Configuration.- There is no need to define schemas or anything
of the sort in a language other than Java, and there are no code generation
steps of any kind. No XML or SQL need to be written, except the necessary to
create a database and grant user permissions. However, you can instruct pBeans to let you manage
database modifications manually.
- Database features.- Transactions and auto-increment IDs (MySQL only) are now supported.
- Flexibility.- Via annotations users are allowed to define their own table and field names,
the name of the primary key, whether fields are nullable, whether tables are user-managed (not automatically
modified), table indexes, unique or otherwise, whether unused fields should be deleted, whether
a field is nullable, whether it is renamed from another field (to prevent loss of data when
a property is renamed), etc.
- Servlet support.- A pBeans store may be easily configured
using servlet context parameters (see ServletAccess.)
Requirements
- J2EE/J2SE 5+.
- A JDBC Driver.
- A Relational Database.
pBeans supports MySQL, PostgreSQL, SQLServer and HSQLDB by default.
Support for additional databases may be "plugged in" by implementing
a class named net.sourceforge.pbeans.data.[database].DatabaseImpl
that extends AbstractDatabase.
Getting started
- Add
lib/pbeans.jar and your JDBC driver JAR to your CLASSPATH
variable. (MySQL, PostgreSQL and SQL Server JDBC driver JARs are redistributed in the
ext directory.)
- Create a blank database and a database user with read/write and table
creation/modification (DDL) privileges.
- For recommended servlet setup, see the pertinent section below.
For general usage, you need to obtain a
DataSource instance, which may be done by instantiating a class
provided with the JDBC driver you will use.
It is probably easiest to instantiate GenericDataSource as
follows:
import net.sourceforge.pbeans.data.*;
import net.sourceforge.pbeans.*;
import javax.sql.*;
...
DataSource dataSource = new GenericDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://datahost/dbname?user=yourusername&password=yourpassword");
In case you are using JTDS (SQL Server):
import net.sourceforge.pbeans.data.*;
import net.sourceforge.pbeans.*;
import javax.sql.*;
...
DataSource dataSource = new GenericDataSource();
dataSource.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
dataSource.setUrl("jdbc:jtds://datahost/dbname;user=yourusername;password=yourpassword");
- Create an instance of
Store
by passing the DataSource you obtained in the previous step.
It is preferable to have only one instance of Store per database in your
Java process.
- For each of your entities, create a JavaBean that is tagged by the @PersistentClass annotation.
Class properties (defined by getters and setters) are assumed to be persistent by default. Mark your transient properties with @TransientProperty.
- Finally, invoke methods on class
Store to
insert, save, delete, look up records, begin transactions, find the unique IDs of your objects, etc.
pBeans2: Now even easier
pBeans v1.x allowed definition of unique indexes, custom field names and so on by means
of a decoration class with a name such as User_StoreInfo ; a technique similar to the
way beans may be decorated with a BeanInfo class. pBeans2 uses annotations instead.
A persistent class may now look as follows:
@PersistentClass(
table="User",
indexes=@PropertyIndex(unique=true,propertyNames="userName")
}
public class User {
private String userName;
private String passwordHash;
public String getUserName() {
return this.userName;
}
public String setUserName(String un) {
this.userName = un;
}
public String getPasswordHash() {
return this.passwordHash;
}
public void setPasswordHash(String ph) {
this.passwordHash = ph;
}
@TransientProperty
public void setPassword(String pwd) {
this.passwordHash = Hash.getMD5Hash(pwd);
}
public void isPasswordMatch(String pwd) {
return Hash.getMD5Hash(pwd).equals(this.passwordHash);
}
}
pBeans2 introduces many annotation elements that provide additional
flexibility.
Servlet HOWTO
pBeans2 provides a facility named
ServletAccess
which helps the caller obtain a common Store
instance as defined in servlet context parameters.
A web.xml file set up to use pBeans may
look as follows.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<context-param>
<param-name>pbeans.stores</param-name>
<param-value>mystore1,mystore2,mystore3</param-value>
</context-param>
<context-param>
<param-name>mystore1.jdbc.url</param-name>
<!-- Note the & -->
<param-value>jdbc:mysql://localhost/mydatabase?user=javauser&password=javapassword</param-value>
</context-param>
<context-param>
<param-name>mystore1.jdbc.driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<context-param>
<param-name>mystore1.max.connections</param-name>
<param-value>99</param-value>
</context-param>
<context-param>
<param-name>mystore1.connection.timeout</param-name>
<param-value>3600000</param-value>
</context-param>
<!-- Other configuration here -->
</web-app>
|