Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Pseudo-Static Row Mappers, a Healthy Alternative to Static Row Mapping

DZone's Guide to

Pseudo-Static Row Mappers, a Healthy Alternative to Static Row Mapping

Enjoy the power of BeanPropertyRowMapper in your work with Spring? Let's try a different spin on it that mixes optimization and control with BeanPropertyRowMapper's freedom.

· Java Zone ·
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

If you know Spring, chances are pretty good that you've also worked with RowMappers and everyone's #1 favorite BeanPropertyRowMapper. Okay, maybe not EVERYONE. But EVERYONE will acknowledge BPRM's power potential and how wonderfully easy it is to use!

While BeanPropertyRowMapper may be the smartest and most beautiful on the RowMapper block, many in the industry refuse to give it the time of day, and for perfectly justified reasons.

Sometimes, when we can't have beauty and wisdom, we're forced to settle for loud and predictable. Yes, I'm talking about hardcoded, unchanging, tell-it-like-it-is, static RowMapper. Hate on them all you like, Static RowMappers are fast, easy to understand, and they seem to replicate like tribbles.

But, as many of you know, an application can grow into a swamp of one-off RowMappers. ESPECIALLY if you are working with a lot of high-throughput batch operations that need to run strictly optimized queries for performance as to avoid any unnecessary marshaling of data.

Recently, I've tried a mildly clever alternative to RowMapping I like to call Pseudo-Static Row Mappers. In this post, I introduce the basics of Pseudo-Static Row Mappers. We show how they give the tough rigid optimization and control of hard-coded naming and data typing while retaining BeanPropertyRowMapper's spirit of freedom.

Pseudo-Static Behavior

Note: Check out my blog on vacuole encapsulation so you won't be angry with me for not making sense in the next paragraphs.

(Okay fine! The gist of vacuoles: collections of meaty key-like bits that could be partially consumed, transported, shared, exchanged, etc. in an amoeba-like form, for singular or shared objectives of data binding.)

To accomplish this pseudo-static behavior, I use a collection of vacuole classes; one for each column, using the data source metadata to initialize & eliminate unused vacuoles on the first read.

After the initialization occurs, the remaining subset of vacuoles is iterated over and used to access the resultset data. (See the bottom source snippet for more information)

Here is an example.

public abstract class Vacuole<T> {
    public Vacuole(String key){this.KEY = key}
    private final String KEY;
    private Mapping(String name) {KEY = name;}    
    private abstract void translate(T instance, ResultSet rs) throws SQLException;
    // A lambda would have been REALLY cool, if it weren't for the blasted SQLException ��
}


... And applied, it looks like this:

public class YetAnotherRowMapper extends PseudoStaticRowMapper <Pojo> {
        public YetAnotherRowMapper() {
            super(PanelCheckHeader::new);
            // Yay lambda constructors!

            add(new Vacuole <Pojo> ("FKey_That_Looks_Exactly_the_same_in_1000_places") {
                // The vacuole pattern enables you to reuse in all 1000 unchanging places
                public void translate(Pojo item, ResultSet rs) throws SQLException {
                    item.setColumnA(rs.getInt(KEY));
                }
            });

            add(new Vacuole <Pojo> ("Column_B") {
                public void translate(Pojo item, ResultSet rs) throws SQLException {
                    item.setColumnB(rs.getString(KEY));
                }
            });
            add(new Vacuole <Pojo> ("YetAbotherColumn") {
                public void translate(Pojo item, ResultSet rs) throws SQLException {
                    item.setColumnC(rs.getTimestamp(KEY));
                }
            });


As you can see, the end result isn't as brutally honest as the familiar static mapper. However, because these pseudo-static row mappers so effortlessly replace static mappers, they make fast work in drying up a swamp of one-off mappers.

Unfortunately, I can't share all of the secret sauce from the PseudoStaticRowMapper itself as it was used on a recent client (proprietary) project. But I will share a generic snippet to entertain your curiosity.

public void init(ResultSet rs) {
        if (rs.isFirst() {
                for (Vacuole < T > v: vacuoles) {
                    for (int i = 0; i <= rs.getMetaData().getColumnCount();) {
                        if (!v.KEY.equals(rs.getMetaData().getColumnName(++i))) {
                            eject(v);
                            // you might also have validation to ensure all colums were handled ��
                        }
                    }
                }
            }
        }


Final Thoughts

I dare you: implement this approach just one time. You'll never go back.

Demonstrate it to someone else who understands this pain, and they'll love you for it.

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:
rowmapper ,java ,spring batch ,beanpropertymapper ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}