Butterfly Persistence

Jakob Jenkov
Last update: 2022-02-04

Butterfly Persistence is an open source light-weight Java persistence API (<200 KB JAR) for reading and writing data from and to relational databases. Butterfly Persistence is a thin layer on top of JDBC which takes care of most of the boring boilerplate code needed to perform the most common JDBC actions, such as CRUD, batch inserts and updates, and simple select statements with simple filtering. Butterfly Persistence has functionality for:

  • Connection Management
  • Simple JDBC operations - such as:
    • Insert
    • Update
    • Delete
    • Select
    • All with or without the use of parameterized SQL (via PreparedStatements).
  • Reading ResultSet into Java Map instances
  • Reading ResultSet into Java objects - using:
    • Automatic mapping of objects to database table columns
    • Annotation based mapping of objects to database table columns
    • Programmatic mapping of objects to database table columns
    • Combinations of the mapping methods

Butterfly Persistence History

Butterfly Persistence was originally created around 2003-2005 under the name Mr. Persister. Later, Mr. Persister was added to a small suite of lightweight Java toolkits I was developing, which I called Butterfly Components. Mr. Persister was renamed to Butterfly Persistence at that time.

Keep in mind that Butterfly Persistence was started around 2004 or so and was maintained for around 5 years or so. People did use Butterly Persistence at the time, but it never gained a huge following - because at the time everyone wanted JPA and Hibernate.

Today, more than 15 years later, more people appreciate lightweight toolkits, so Butterfly Persistence has gained a "second life" with these enthusiasts.

Butterfly Persistence GitHub Repository

Butterfly Persistence is available in a GitHub repository here:

https://github.com/jjenkov/butterfly-persistence

Installation and Setup

The only thing required to use Butterfly Persistence is that you add the JAR file to the classpath of your application. That is all. All configuration etc. is done from inside your code, so you don't have to mess around with configuration files and JVM parameters.

There is, unfortunately, no Maven central repository distribution of Butterfly Persistence at this point in time, but I might add that in the future. If you want Butterfly Persistence to be part of a build pipeline, you can always clone the GitHub repository, and build that via your build pipeline too. It should not be too heavy on your build pipeline (maybe disable Butterfly Persistence unit tests so you avoid any problems with running against a real database during builds...)

Creating a PersistenceManager

All actions you need to perform with Butterfly Persistence start from the PersistenceManager. Therefore you will have to create a PersistenceManager instance. Here is how it could look:

public static final PersistenceManager persistenceManager =
    new PersistenceManager();

Notice that the PersistenceManager instance is declared public static final. A lot of things are cached internally in the PersistenceManager instance, like object mappings, sql etc., so you should not create a new instance everytime you need it. Rather you should create a single instance and reuse that throughout the life time of your application. If your application uses more than one database, create one instance per database.

The PersistenceManager can also be created with a DataSource as parameter to its constructor. That way the PersistenceManager can obtain Connection instances automatically from this DataSource. You can read more about how that works in Butterfly Persistence Connection Management. Here is an example of how that looks:

DataSource dataSource = new SimpleDataSource(
        "driverName", "dbUrl", "user", "password");

PersistenceManager persistenceManager =
        new PersistenceManager(dataSource);

Creating an IDaos

In order to use any of Butterfly Persistence's functions you must create an IDaos instance. An IDaos instance is a collection of utility DAO's you can use to ease the interaction with JDBC and the database. Here is how creating an IDaos instance looks:

IDaos daos = persistenceManager.createDaos();

From the IDaos instance you have access to a database connection and three utility daos:

  1. IJdbcDao
  2. IMapDao
  3. IObjectDao

Using these three dao utilities you can interact more easily with the database. This is explained in a bit more detail in the following sections.

By the way, if the PersistenceManager that created the IDaos instance had a DataSource passed to its constructor when created, the IDaos instance will automatically be given a new Connection - which is kept internally, and is accessible to the IJdbcDao, IMapDao and IObjectDao . You can obtain that Connection object via the IDaos.getConnection() method, like this:

Connection connection = daos.getConnection();

The IJdbcDao

The IJdbcDao is a DAO object that makes it easier to perform simple JDBC operations against the database you are using. The IJdbcDao is explained in more detail in Butterfly Persistence IJdbcDao.

Here is a simple example of inserting a record into a table using an SQL statement with parameters. Internally the IJdbcDao uses a PreparedStatement, but you don't need to know that.

String insertSql = "insert into persons(name) values(?)";

daos.getJdbcDao().update(insertSql, "John Doe");

This code will run the insert sql statement and replace the ? with the value "John Doe" using a standard PreparedStatement.

The IMapDao

From the IDaos object you can also obtain an IMapDao instance. The IMapDao is used to read one or more records from a ResultSet into a Java Map. You can read more about the IMapDao in Butterfly Persistence Map DAO.

Here is an example:

Map result = daos.getMapDao().readMap("select * from persons where id=123");

The IMapDao also supports parameterized SQL statements, like this:

Map result = daos.getMapDao().readMap("select * from persons where id=?", 123);

The IObjectDao

The IObjectDao can be used to read and write Java objects (POJOs) from and to a relational database. The IObjectDao takes care of mapping the object(s) to an SQL statement during writes, and from a JDBC ResultSet to Java objects during reads.

The IObjectDao is explained in more detail in Butterfly Persistence Object DAO.

The IObjectDao supports the following styles of mapping Java objects to database tables and ResultSet metadata:

Here is an IObjectDao object reading / writing example:

Person person = daos.getObjectDao().readByPrimaryKey(Person.class, 0);

person.setName("Joe Blocks");

daos.getObjectDao().update(person);

This code will first read the person having primary key 0. Then it will change the name of the read object. Finally the record matching the object in the database is updated to reflect the changed name.

Partial Object Reading and Writing

Butterfly Persistence supports partial object reading and writing.

Partial object reading means that you only read a subset of the columns in a database table into the corresponding object. Thus, even if the object and table contains 25 fields and columns, you may only want to read 3, 6 or N < 25 of them in a given situation.

Partial object writing means you only update a subset the columns in a database table. For instance, if the object contains 25 fields and the table 25 columns, but you know you only updated at most 3 of them in this situation, you don't have to update all 25 fields in the database table record. You can just update the 3 columns you know might have changed.

You can read more about partial object reading and writing in Butterfly Persistence Partial Object Reading and Writing

What is Next?

If you like what you have seen so far, you should familiarize yourself with the more advanced features of Butterfly Persistence. It is recommendable to start out reading about connection management, then the JDBC utilities, and finally the object reading and writing utilities. You can get a long way with just connection management and the JDBC utilities, so that's a good place to start.

Jakob Jenkov

Featured Videos

Java ConcurrentMap + ConcurrentHashMap

Java Generics

Java ForkJoinPool

P2P Networks Introduction

















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next