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:
- 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:
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.
PersistenceManager can also be created with a
DataSource as parameter
to its constructor. That way the
PersistenceManager can obtain
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 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 daos = persistenceManager.createDaos();
IDaos instance you have access to a database connection and three
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
DataSource passed to its constructor when created, the
instance will automatically be given a new
Connection - which is kept internally,
and is accessible to the
You can obtain that
Connection object via the
Connection connection = daos.getConnection();
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
IDaos object you can also obtain an
IMapDao is used to read one or more records from a
into a Java Map. You can read more
IMapDao in Butterfly Persistence Map DAO.
Here is an example:
Map result = daos.getMapDao().readMap("select * from persons where id=123");
IMapDao also supports parameterized SQL statements, like this:
Map result = daos.getMapDao().readMap("select * from persons where id=?", 123);
IObjectDao can be used to read and write Java objects (POJOs) from and to a relational database.
IObjectDao takes care of mapping the object(s) to an SQL statement during writes,
and from a JDBC
ResultSet to Java objects during reads.
IObjectDao is explained in more detail in Butterfly Persistence Object DAO.
IObjectDao supports the following styles of mapping Java objects to database tables and
- Automatic Object Mapping
- Annotation Based Object Mapping
- Programmatic Object Mapping
- Combined Object Mapping (all of the above 3 combined)
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.