MrBool
You must be logged in to give feedback. Click here to login
[Close]

You must be logged to download.

Click here to login

[Close]

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

[Close]

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Active Record: Free Enterprise Patterns Framework

This article will see some alternatives to the frameworks we use with such abandon. I’ll describe the Active Record pattern.

[close]

You didn't like the quality of this content?

Would you like to comment what you didn't like?

Introduction

Most modern enterprise applications are written using a variety of frameworks to provide basic services: a web framework for presenting data to the user, a persistence framework for storing it to the database, perhaps a data binding framework to make moving data between different layers of the application easier, a logging framework so you know what it’s done, a testing framework so you know it does something at least vaguely resembling what it’s supposed to, and usually a dependency injection framework to make putting all the frameworks together easier.... You could say modern development is overloaded with frameworks. We tend to reach for them instinctively, but we don’t always need them. That’s not to say using them is necessarily bad, but that we should think about what we’re achieving with each framework we use, and question whether we can achieve the same result another way and whether that way might be better. Sure, Hibernate can make storing your data much easier, but if it stops working for any reason the extra layer of complexity can make finding the source of the trouble so much harder.

In this article, and the articles to follow, I present some alternatives to the frameworks we use with such abandon. In the current article, I’ll describe the Active Record pattern. Active Record is a very old pattern (it was commonplace for a very long time before Martin Fowler gave it its name in his book Patterns of Enterprise Application Architecture), and one of the simplest ways of keeping your database access code neat and organised.

Just to show I’m not a total luddite, and because it lets me concentrate on what’s important in the article, I’m using one framework here: I use Spring to connect my objects with their dependencies, including my Servlets. If you’re not familiar with the techniques available to cause Spring to create Servlet objects for you, you should read my earlier article Servlet dependency injection with Spring which describes in depth how I’m using it. You may also want to read my article Spring transaction handling: transaction-per-request with AOP which describes the approach I’m taking to connecting to the database and attaching transactions to user requests. Because these are handled automatically, this is the last time I’ll mention them.

The Active Record pattern

Fowler defines the Active Record pattern thus:

“An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.”

This sounds simple enough. Let’s start with a database. Here’s the SQL to set up a simple database for a simple application. I’m using MySQL because it’s what I have installed on my development machine, but you could use any modern SQL implementation for the purpose with only minor changes.

Listing 1: SQL to create the database

 
create database test;
use test
grant all on test.* to 'test'@'localhost' identified by 'test';
create table customers (
   id int primary key auto_increment not null,
   name varchar(255) not null
) engine=innodb;
insert into customers values (1, "Joe");
insert into customers values (2, "Carinna");
create table accounts (
   id int primary key auto_increment not null,
   balance decimal(9,2) not null,
   customer int not null references customers 
) engine=innodb;
insert into accounts values (1, 0, 1);
insert into accounts values (2, 0, 1);
insert into accounts values (3, 0, 2);

I’ve created two rather simple tables, with one reference between them. We’ll see how that’s implemented soon, but let’s start by implementing a class for the simpler of the two tables, customers. We’ll start with a simple class with fields for the database columns, and we’ll have a constructor to build one from a ResultSet.

Listing 2: Starting the ‘Customer’ class

 
public class Customer
{
	private final int id;
	private String name;
	
	private Customer (ResultSet rs) throws SQLException
	{
		id = rs.getInt ("id");
		name = rs.getString ("name");
	}
	public String getName ()
	{
		return name;
	}

	public void setName (String name)
	{
		this.name = name;
	}

	public int getId ()
	{
		return id;
	}
}

That’s a reasonably good start, but to be useful we’ll need a way to construct them. Let’s add a couple of static methods for pulling them out of the database.

Listing 3: Reading Customers from the database

 
	public static Customer get (Connection connection, int id) throws SQLException
	{
		try (PreparedStatement s = connection.prepareStatement ("select * from customers where id=?"))
		{
			s.setInt (1, id);
			try (ResultSet r = s.executeQuery ())
			{
				if (r.next ()) 
					return new Customer (r);
				return null;
			}
		}
	}
	
	public static List<Customer> getAll (Connection connection) throws SQLException
	{
		try (Statement s = connection.createStatement ();
			 ResultSet r = s.executeQuery ("select * from customers"))
		{
			ArrayList<Customer> result = new ArrayList<> ();
			while (r.next ()) 
				result.add (new Customer (r));
			return result;
		}
	}

These methods are relatively simple: they just perform the SQL query we’re interested in, then create a new Customer object for each ResultSet row they return. If we wanted any more interesting queries (e.g. finding a customer based on a partial name) we’d implement them in basically the same way. Only the query changes.

Note that I’m using Java 7’s “try-with-resources” statement, which radically simplifies cleanup after SQL operations by ensuring the statements and result sets are always closed for us. This makes life much simpler, especially when you consider that ensuring the resources are closed correctly when exceptions occur requires finally blocks and nested exception handlers, a complicated structure that is very easy to get wrong.

As well as reading Customers, we obviously need to be able to write them to the database. This is just as simple. There are two cases we care about: creating new customers and updating existing ones.

Listing 4: Writing Customers to the database

	public boolean create (Connection connection) throws SQLException
	{
		try (PreparedStatement s = connection.prepareStatement (
"insert into customers (name) values (?)"))
		{
			s.setString (1, name);
			return s.execute ();
		}
	}
	public boolean update (Connection connection) throws SQLException
	{
		try (PreparedStatement s = connection.prepareStatement (
"update customers set name=? where id=?"))
		{
			s.setString (1, name);
			s.setInt (2, id);
			return s.execute ();
		}
	}

Things get a little more interesting when we implement a class that has a reference to another type. Here’s the code for Account:

Listing 5: Starting the Account class

 
public class Account
{
	private final int id;
	private double balance;
	private Customer customer;
	
	private Account (Connection connection, ResultSet resultSet) throws SQLException
	{
		id = resultSet.getInt ("id");
		balance = resultSet.getDouble ("balance");
		customer = Customer.get (connection, resultSet.getInt ("customer"));
	}
	// getters and setters go here

	public static Account get (Connection connection, int id) throws SQLException
	{
		try (PreparedStatement s = connection.prepareStatement (
"select * from accounts where id=?"))
		{
			s.setInt (1, id);
			try (ResultSet r = s.executeQuery ())
			{
				if (r.next ()) 
					return new Account (connection, r);
				return null;
			}
		}
	}
}

The rest of the class proceeds as per the Customer class: a getAll() method, and create() and update() methods that work the obvious way (using customer.getId() to supply the value for the customer column).

Using the objects is simple. Here’s an example:

Listing 6: Using object

	@Override
	protected void doGet (HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException
	{
		PrintWriter out = resp.getWriter ();
		out.println ("<html><body><table>");
		try
{
			for (Customer c : Customer.getAll (connectionManager.getConnection ()))
	        		out.format ("<tr><td>%d</td><td>%s</td><td>”+
“<a href='customerDetails?customer=%1$d'>details</a></td>", 
	        		c.getId(), c.getName ());
}
catch (SQLException e)
{
throw new ServletException (e);
}		
		out.println ("</table>");
		out.println ("<h1>New customer</h1><form method=post>");
		out.println ("Name: <input type=text name=name> <input type=submit></form>");
		out.println ("</body></html>");
	}

And an example of writing objects:

Listing 7: creating new Customers

 
	@Override
	protected void doPost (HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException
	{
		Customer c = new Customer();
		c.setName (req.getParameter ("name"));
		// should perform some validation here!
		try
{
c.create (connectionManager.getConnection ());
}
catch (SQLException e)
{
throw new ServletException (e);
}
		resp.sendRedirect (req.getRequestURL ().toString ());
	}

But wait - we’re not actually complying with Fowler’s definition of Active Record. Here it is again, with added emphasis:

“An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.”

We’re not adding any domain logic. Let’s fix that - there was a comment in the last method about validation, so let’s do that. In the Customer object, add the following method:

Listing 8: Customer validation

 
	public void validate ()
	{
		if (name == null || name.trim ().length () == 0)
			throw new IllegalArgumentException ("You must specify a name");
	}

Now we just need to call that from the customer servlet’s doPost() method, and we have a working example of the Active Record pattern that needed no framework at all.

This is all for this article. Hope you liked it. See you next time.



My main area of specialization is Java and J2EE. I have worked on many international projects like Recorders,Websites,Crawlers etc.Also i am an Oracle Certified java professional as well as DB2 certified

What did you think of this post?

Did you like the post?

Help us to keep publishing good contents like this.

SUPPORT US

funded

remaining

[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually � in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits � in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login