EZPersistence

Thank you for choosing EZPersistence. The absolute easiest way to hook your code into a database without database coding! Has transactions, finder methods, no JDBC or SQL code needed, can auto-create your schema for you, and C.R.U.D. operations through one method call.
No BS here, just jump in;

Coding For EZPersistence

To make a persistent class just follow the three simple steps;

1) Make your class extend com.ezsoft.ezpersistence.BasePersistence
2) Create public variables. These variables will be the data stored in the database.
3) Make a constructor with parameter that you want to be your primary key or the main index of the object.

That's it! This is pretty much the way most Value Objects (or View Objects) work anyway. You dont have to know ANY SQL! You dont have to create ANY tables! It does it all for you! It is really ALL done for you! You write your bean and set up your database connection using the included GUI and its all handled.

This program was designed to perform C.R.U.D. operations seamlessly on java beans. C.R.U.D. operations stand for Create, Read, Update and Delete. The basic operations one would need to perform. I've also added another nifty one called find.

You can read the javadocs for BasePersistence to see a more detailed description of each of these operations. The three classes you should really look at are first Employee.java, then EmployeeGuiFrame.java to see how it uses Employee.java and then BasePersistence.java to see complete javadocs on the supported functionality for a persisted object.

The syntax for these operations are;

   Employee employee = new Employee(email.getText());
   employee.setFirstName(fname.getText());
   .....
   employee.setAge(new Integer(age.getText())));
   employee.create();

This code is from com.ezsoft.ezpersistence.gui.EmployeeGuiFrame.java. It shows how a java object is created using EZ Persistence. But you can then use the same object to perform the R.U.D. operations of C.R.U.D. by just calling;

   employee.create() // Creates a row in the database populated with the current object and it's populated fields.
   employee.read() // updates the object from database. Forced read, not from object cache. Wipes out all object data with database data.
   employee.update() // updates database with the values the object contains
   employee.delete() // deletes the current object from the database

In addition to these C.R.U.D. operations there are a couple of other convenience methods. These are;
   Employee.delete(new Employee(email.getText())); // static method to delete an object from the database
   Employee employee = (Employee)BasePersistence.getPersistenceObject(new Employee(email.getText()));    // reads the object from EZPersistence cache if it exists, otherwise, it pulls from the database

   employee.find(); // Looks at all the populated fields in your object and creates a vector of objects that match the given data.
     ie: If an Employee object is created with only the last name populated, a vector of Employee objects will be returned of all employees with the last name given.

     Employee employee = new Employee();
     employee.lastName("Lee");
     Vector employees = employee.find();
     ....
     Employee employeeFromVector = (Employee)employees.elementAt(2);  // gets the second employee from the list
If no fields are populated, find() returns a vector of all Employees.

There is a new feature that allows a developer to have a more feature rich find(). It was modeled after Apache's PersistenceBroker framework's Criteria object. You can now create a com.ezsoft.ezpersistence.Criteria object and populate it with criteria you wish each field to search on. If no criteria is set for a field, a literal match is done on a populated field. Criteria types can be BETWEEN, LESS_THAN, GREATER_THAN and can be applied to most data types (Dates, numbers, etc). Criteria take a list of CriteriaItem objects that each hold the field you wish to search on and the criteria type to search. The criteria types are noted above. The CriteriaItem object also has a value field that holds the second value for the BETWEEN criteria type. Here's a code example;

     Employee employee = new Employee();
     Criteria criteria = new Criteria();
     employee.setAge("21");
     criteria.addCriteria(new CriteriaItem("age", CriteriaItem.LESS_THAN));
     Vector employees = employee.find(criteria);
This example will get all employees under the age of 21.

Here are some rules to keep in mind when coding your persitent class;
- Primary key is passed into the constructor and is NOT part of the subclass (the class you create)
- All classes that extend BasePersistence CAN create a primary key variable name;
static String PKNAME = "yourPKName"; If you do not, the database column will be named 'ID'.
If, on your constructor, you want to have the database automatically create a primary key for you (auto-indexing) then just call super(primaryKeyObject, true) where 'primaryKeyObject' is the primary key object (could be null, just needs this to get the object type).
ie:

public Employee(Integer employeeID)
{
    super(employeeID, true); super.PKNAME = "employee_id";
}

This is a constructor for a java object called Employee that has an auto-generated primary key of type Integer whose database column name will be 'employee_id'.

You can also create transactions. If you have a for a series of objects that have to be read/created/updated/deleted and if some combination thereof fails and you don't want it to commit something that happened before the failure then you need a transaction. To put a series of tasks in a transaction just pass the same connection to all the Persistable java objects you want to include in the transaction.
ie:
    try
    {
        Connection connection = PersistenceSystem.instance().getDefaultConnection();
        connection.setAutoCommit(false);
        Employee emp = new Employee("userid");
        emp.setFirstName("Bob");
....
        emp.create(connection);
        InsurancePolicy insurance = new InsurancePolicy(new Integer(someInsVal));
        insurance.setEmployee(emp);
        insurance.update(connection);
        connection.commit();
    }
    catch(Exception ex)
    {
        try{connection.rollback();}
        catch(Exception exc) { exc.printStackTrace(); }
        ex.printStackTrace();
    }

Here it tries to create an Employee in the database and then add that new Employee to an already existing InsurancePolicy (which extends BasePersistence). If any step in here fails, it will try to rollback the transaction which will cause the program not to enter any partial data into the database.
Note: You use the update() method on objects that were already loaded from the database but need to be changed, not created.
- If you get an IllegalAccessError then you probably haven't made your class variables public. They are in a format the base class does not have rights to.
- Must conform to bean interface
- static String PKNAME must be declared and access level of public

Connecting EZPersistence To Your Database

To hook your code into the database, just run the admin utility included in this archive. Just double click on the ezpersistence.jar file and you will see a screen like this;


Persistence Admin GUI

The administration program (double click on the jar) fills in most of the parameters needed to connect to your database. You may have to change the fields to connect to your database. In this case (the default) it is connecting to My SQL database with its default configuration installed with a username and password of persistence/persistence on a database I created called persistence. I highly reccommend this database if you do not already have one. It is very stable, fast and free! And, considering your using this program because its easy, this just makes it even easier on you. Follow this link to download My SQL.

The Admin utility creates a file called persistence.properties. This file has to be in the directory where your app runs. Considering everything we use is in jars, it should stick it in that directory. The EmployeeGui example uses this file. If your database connection is not set up properly, then the example will not work (obviously). The max number of objects in pool is the number of EZPersistence java objects (a java class that extends BasePersistence) created/read/updated. You can increase/decrease this number to tweak your performance. The number of objects to remove is the number of objects to remove from the pool at a time. These objects are removed when an EZPersistence object is created/updated/read that does not exist in the cache. Keep in mind, this is a cached read, not the employee.read() which forces a database read and overwrites the objects fields with those in the database.

EZPersistence uses the apache commons connection pooling.

To help you find what values to enter for the different fields, here are some mappings for the tested databases;

Database Driver Class Database URL Driver URL (where to get jdbc driver) Jars to include in classpath
MS SQL Server com.microsoft.jdbc.sqlserver.SQLServerDriver

jdbc:microsoft:sqlserver://hostname:port[;property=value...]

SQL Server 2000 JDBC drivers msbase.jar
msutil.jar
mssqlserver.jar
My SQL com.mysql.jdbc.Driver jdbc:mysql://hostname:port/database Download the driver for your version mysql-connector-java-xxxxx-bin.jar
Oracle (thin type 4) oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@server_name_or_IP:port:SID http://technet.oracle.com/software/tech/java/sqlj_jdbc/content.html classes12.zip
Access sun.jdbc.odbc.JdbcOdbcDriver jdbc:odbc:persistence none. included in core packages None. You have to create a database using the odbc interface in control panel.
PostgreSQL org.postgresql.Driver jdbc:postgresql://host:port/database Download PostgreSQL Drivers here postgres.jar
HSQL DB org.hsqldb.jdbcDriver jdbc:hsqldb:hsql://localhost Download HSQLDB Drivers here hsqldb.jar

Looking At the Example

The Admin tool will create a file called persistence.properties. It has to be placed in the same directory where you run your program.

All this code can be found in the class com.ezsoft.ezpersistence.gui.EmployeeGuiFrame.java. The program that uses this class is contained in ezpersistence_x_x_x.jar. You can find the source code at the project page. To set up your application the same way you set up this example;
Include the following jars in your application's classpath

Don't forget to include the generated persistence.properties in the directory where you run your application.
Before you can run this program, you have to have set up the system to point to your database. If you have not, look below to the section Connecting EZPersistence To Your Database.

Run java -jar ezpersistence_x_x_x.jar com.ezsoft.ezpersistence.gui.EmployeeGui.
You should see this screen;


Employee EZPersistence Example GUI

This screen shows many fields that are typical to most employee databases. The six buttons show many of the common features you could do to an employee database (look familiar :)). This example took me less than 2 hours to write. Almost all of that was gui work. The code is included in the file employee.jar. Two of the main files you might want to look at are Employee.java and EmployeeGuiFrame.java. Employee.java is the bean object I want to persist and EmployeeGuiFrame.java is the code that manipulates the object. The code examples given above were, more of less, from EmployeeGuiFrame.java. Just type in the employee's information and click create and it will create that employee in the database. There is no coding on your part what so ever to connect to the database. You can concentrate on business code. If the table does not exist, it will create it for you! Create a bunch of employees. Then click the clear button to wipe out the form. Type just the email of one of the employees. It updates automatically! Change just a bit of their information and click update. All that has to happen in the code is to call employee.update() and thats it! Click delete and that employee is gone from the database! Click clear again and type in a few fields that you want to search on. Then click the Find button. You will see a list of email addresses at the bottom that match your criteria. Thats the employee.find()! Just double click on any of the matches to load that employee's data! Its that easy! Beautiful thing is, it's all cached too so it's EXTREMELY fast! It uses LRU algorithms and parameters you can set up to optimize your program!

Feature List

Addendum

This has been tested to work on Oracle, MS SQL Server, Access, HSQLDB, PostgreSQL and My SQL (recommended).

That said, there are some data types that do not have equivalents on particular databases. For example;
SQL Types that all databases tested may not support that map to equivalent java objects are:
Boolean=BIT, java.sql.Date=DATE, java.sql.Timestamp=TIMESTAMP, java.lang.Short=SMALLINT

The java object types supported are String, Integer, java.sql.Date, java.math.BigDecimal, Boolean, Byte, Double, Float, Long, Short, Character, java.sql.Time, java.sql.Timestamp.

Future plans;
- Additional java types
- Database Foreign keys references. In the code you can create a field that is an object that extends BasePersistence and it matches up to another table (foreign key references). And it loads transparently also.
- Use JNDI and Data Sources
- Multi object primary keys
- Empty constructors
- Remove need to extend BasePersistence but Rather implement interface.

Here is an excellent article that shows what types are supported by all databases. I used all of these in my code, and a few extras where they could be used. For example, take the object Boolean, which Oracle does not like. Oracle can use a character instead.

If you find any bugs, have any suggestions, check out the project page.
Happy coding!