Mr. Persister 2.0 Released (ORM API)

Discussions

News: Mr. Persister 2.0 Released (ORM API)

  1. Mr. Persister 2.0 Released (ORM API) (29 messages)

    Mr. Persister is a small, fast, and simple open source Java object relational mapping API.
    You can download it from it's project page here:

    http://www.jenkov.dk/projects/mrpersister/mrpersister.jsp

    Mr. Persister's main features and differences from other ORM API's are:

    1) SQL as Query Language.
       That means you don't have to learn a new query language in order to use Mr. Persister. If your database understands your SQL, so does Mr. Persister.

       In addition to SQL Mr. Persister is capable of reading objects from
       JDBC's ResultSet, Statement, and PreparedStatement instances too.

    2) Mapping to SQL Queries
       When reading Mr. Persister just iterates through the columns of the ResultSet and checks if they are mapped to a setter method on the object. Therefore the columns in the ResultSet don't have to exist in any table. As long as they exist in the ResultSet Mr. Persister can read objects from it. This makes it easy to map objects to complex joins, or aggregate functions like "select sum (...) from ... group by ..."

    3) Automatic Mapping
       Mr. Persister is capable of guessing most trivial mappings between classes and tables, and between getters / setters and columns. This way you save the work of creating manual mapping files.

       You can also create manual mappings easily programmatically. Or you can use mixed mapping where you have Mr. Persister generate an automatic mapping that you modify before it's used.

    4) Mr. Persister can generate SQL for trivial operations like readByPrimaryKey, insert, update, delete, deleteByPrimaryKey. This SQL is generated at request time (lazy evaluation) and cached for later use, so there is no startup SQL generation time penalty.

    5) Mr. Persister supports batch updates (insert, update, delete, and deleteByPrimaryKey)

    4) Mr. Persister uses reflection to move data between the JDBC components and the objects.

    5) Small. 97 kb binary jar file.

    6) Fast. 5% overhead on reads from MySQL.

    7) Free. Released under the Apache License.

    Using Mr. Persister can be done in just 3 simple steps:

    1) Download the binary jar file.
    2) Include the binary jar file on your classpath
    3) Subclass com.jenkov.mrpersister.AbstractDao

    The AbstractDao works as a facade to the Mr. Persister components and has a lot of protected methods your DAO subclass can make use of when implementing your own read and write methods. Below is an example of a simple DAO class that uses Mr. Persister and automatic mapping:
    public class EmployeeDao extends AbstractDao {

        protected Connection getConnection() throws PersistenceException {
            //you need to override this method. It's used by the AbstractDAO methods.
        }

        public Employee readEmployee(String employeeId) throws PersistenceException{
            return (Employee) readByPrimaryKey(Employee.class, employeeId);
        }

        public List readAllEmployees() throws PersistenceException{
            return readList(Employee.class, "select * from employees");
        }

        public int insertEmployee(Employee employee) throws PersistenceException {
            return insert(Employee.class, employee);
        }

        public int updateEmployee(Employee employee) throws PersistenceException {
            return update(Employee.class, employee);
        }

        public int deleteEmployee(Employee employee) throws PersistenceException {
            return delete(Employee.class, employee);
        }

        public int[] insertEmployees(List employees) throws PersistenceException {
            return insertBatch(Employee.class, employees);
        }

        public int[] updateEmployees(List employees) throws PersistenceException {
            return updateBatch(Employee.class, employees);
        }

        public int[] deleteEmployees(List employees) throws PersistenceException {
            return deleteBatch(Employee.class, employees);
        }
        
    }
    ORM won't get much easier than this, we believe.

    Check it out here:

    http://www.jenkov.dk/projects/mrpersister/mrpersister.jsp

    Threaded Messages (29)

  2. ORM-apalooza[ Go to top ]

    Is it me, or are there alot of open source thin and lightweight ORM projects popping up? Cayenne, Pride, etc.
  3. ORM-apalooza[ Go to top ]

    anybody ever used simpleorm?
  4. Looks like limited iBatis. What are the limitations?
  5. Different from Ibatis[ Go to top ]

    Mr. Persister was indeed inspired by Ibatis, but has some differences. In Ibatis you have to alias ever column selected to the setter method to call when reading. In Mr. Persister you don't necessarily have to do this mapping. If you classes and / or getters / setters have names similar to the tables and columns they map to, Mr. Persister can do this mapping automatically at runtime.

    You should be able to do pretty much anything you can do with Ibatis with Mr. Persister (although I'm not an expert in Ibatis I must admit).
  6. Hi Jakob,

    Congratulations on a nice piece of software.

    I've had a look at the software and documentation and I'd like to say that the code quality and documentation are outstanding. I think you're the first to offer (free) flash video demonstration of an OSS product! [at least the first that I've seen]

    I think Mr. Persister is closer to iBATIS than it is to any ORM. For the most part I think we share the same values of simplicity and flexibility. We actually don't regard iBATIS as an ORM at all, as we don't map classes to tables. It sounds to me like Mr. Persister is similar in this respect, however it does have some ORM like qualities, including the simple CRUD mapping (w/SQL generation).
    In Ibatis you have to alias ever column selected to the setter method to call when reading. [...]If you classes and / or getters / setters have names similar to the tables and columns they map to [...] can do this mapping automatically at runtime.
    Just a small correction here, so people don't get the wrong idea. iBATIS has been able to do this since 1.2.0. Aliasing is only required if the column names don't match the bean.

    Once again, nice work!

    Clinton Begin
    http://www.ibatis.com
  7. iBATIS has been able to do this since 1.2.0. Aliasing is only required if the column names don't match the bean.
    Probably it is better to use private fields for read/write operations, It must not be a problem to use any names in java.

    BTW this kind of frameworks must be very interesting with new JDK features.
  8. Hi Clinton,
    Just a small correction here, so people don't get the wrong idea. iBATIS has been able to do this since 1.2.0. Aliasing is only required if the column names don't match the bean.
    It seems Ibatis and Mr. Persister are then indeed much alike :-) But like I said, I'm not an expert in Ibatis :-)

    Mr. Persister extends the column-bean mapping to similar names as well. I don't know if Ibatis does that? For instance, the setter method setEmployeeId will be mapped to any of these column names:

    EmployeeId
    employeeId
    employeeid
    EMPLOYEEID
    Employee_Id
    employee_id
    EMPLOYEE_ID

    So you can have a somewhat looser coupling between the naming convention of the database and the classes and getters and setters.
  9. Hi Jakob,

    I noticed that later. Yes, that is indeed a unique feature of Mr. Persister!

    Cheers,
    Clinton
  10. Seems that this is MORE work than, say, Hibernate or Cayenne. YOu have to subclass the AbstractDAO class for EVERY POJO that you want to persist. AND you have to write SQL.
  11. The work has to go somewhere[ Go to top ]

    David, I've been doing plain JDBC (using various patterns, code generation, utility classes, etc. so as to not do it all by hand) and am investigating ORM, JDO, and the various persistence mechanisms everybody talks about.

    It seems to me that if you're working from a text-editor/command-line standpoint with these various tools then the work to map from the database to the objects has to be done somewhere. With some technologies you do the work in the objects, in others you do it in configuration files. But you still have to do the work.

    For trivially complex database schemas you can certainly take what a tool or library gives you with minimal work and maximum functionality. For a moderately complex database schema, or a work process that requires some basic data manipulation to be done in the database during selects before sendig results, then you start to stretch the limits of what can be done with some of these technologies and by the developers themselves. Increasing the complexity further or having technical or process constraints based on your computing and business environment and you may find that some of these technologies are simply not a good fit or plain old wouldn't work. Some technologies even dictate a "preferred" database design, and in many workplaces you don't have the option of redoing an existing database.

    One of the things that people don't realize just how many scaling, training, experience, and contrstaint variables there are. In many environments it is a good thing that you can write SQL, so there's nothing wrong with Mr. Persister's approach. I've worked on teams recently where people were just learning Java but knew SQL very well, and overall we were very productive. I don't know that I'll use Mr. Persister or not, or even Hibernate or Cayenne or anything else on my next project, but I'm sure I'll find a spot for one of them in the future when one of those tools fits the job.

    Anyway, David, your comments may very well fit the work that you do, but I don't necessarily think they apply generally across the board.
  12. Woow, I was sleeping when this message was released. I see you have been discussing what Mr. Persister can do. I guess I better jump in with some answers :-)

    You DON'T have to subclass AbstractDao for every POJO you want to persist. I just like to keep thing separate. But if you want to write one big DAO class that takes care of all of your persistence, that's no problem. I usually keep the stuff thats common for my DAO classes in a BaseDao that extends AbstractDao. That way I only have to implement the getConnection() method once.
    The rest I keep separately in each their own class, just for fun... and better overview :-)
  13. Jakob - I think the thread starter was, as many people seem to be doing, implying that you shouldn't ever have to subclass anything in order to make a persistable POJO.

    Admirable goal, but at times unrealistic. I usually find that subclassing and *designing* a class hierarchy (no more than a few layers deep at most) can reap many benefits, and there are times where it makes sense to have a persistable object extend a base class. It depends on the persistence mechanism, and doesn't mean that one is bad if subclassing is preferrable for that mechanism. There's tradeoffs in any choice -- you just may not see the work done in the objects but in complicated config files. I like Jakob's approach because it doesn't try to do everything and leverages the experience that most developer's already have - SQL.
  14. Hi Again,

    You DAO class needs to subclass AbstractDao, but your POJO's don't. I guess that is confusing some readers.
  15. Well, actually the AbstractDao is only a facade that eases access to the components that really does the ORM work. You can go directly to those components if you like. That way no subclassing is necessary at all.
  16. Mr. Persister - what a great name!

    Now if they just had a catchy jingle...
  17. I would say that Mr. Persister is by far the best ORM product available.
  18. Do you mean "the best light ORM tool", "the best full ORM tool", or "the best I've-read-a-Fowler-book-and-started-an-open-source-project tool"?

    http://blog.hibernate.org/cgi-bin/blosxom.cgi/Christian%20Bauer/relational/comparingpersistence.html
  19. Do you mean "the best light ORM tool", "the best full ORM tool", or "the best I've-read-a-Fowler-book-and-started-an-open-source-project tool"?http://blog.hibernate.org/cgi-bin/blosxom.cgi/Christian%20Bauer/relational/comparingpersistence.html
    It's the best because it has the coolest name.
  20. Lightweight is ok, but...[ Go to top ]

    ...what about transactions, caching, lazy loading, resultset paging, object states, relationships and so on? Don't you think that putting all those things into it would make it far less lightweight? It seems to be a clean job and a good basis for a real orm, but I wouldn't go without automatic relationships handling and some kind of QBE thing, though (I hate SQL!). What about a pluggable architecture for all those missing things?
     
    The name, indeed, is nice.
  21. What's her name?[ Go to top ]

    The name, indeed, is nice.
    Mr Per's sister.

    ;)
  22. Lightweight is ok, but...[ Go to top ]

    You can manage your transactions in Mr. Persister just like you would normally do in JDBC. Only difference is that you can have Mr. Persister do some of the trivial jobs for you, and do the hard parts yourself with regular JDBC.

    You can achieve resultset paging using the IReadFilter's that Mr. Persisters readList methods can take. Filters can scroll to a certain position in the result set before reading takes place, and then the filter can accept or reject individual records from there on.

    Currently there is no object caching. Only caching of the object mappings and the little SQL Mr. Persister can generate for trivial cases.

    There is no notion either of relationships between objects / tables yet. In Mr. Persister you can still read an object and all of it's related objects in one left outer join if you want to.

    Pluggable architecture... The AbstractDao is merely a facade and delegates all of it's work to a set of components (ObjectReader, ObjectWriter, ObjectMapper, NameGuesser, NameDeterminer, PrimaryKeyDeterminer etc.). Each of these components implement an interface, and each of these components can be exhanged for your own implementation if you want to.

    These components are grouped into IPersistenceConfiguration instances. Each DAO class has a persistence configuration, so you can even use different implementations of these components for each of your DAO classes if you want to.

    I'd call that a reasonably pluggable architecture :-) Perhaps not perfect, but definately pluggable to a large degree.
  23. All in all[ Go to top ]

    All in all Mr. Persister is for those who like to have full control using JDBC and SQL, but don't like to do all the trivial mapping yourself.

    With Mr. Persister you can divide the work between you and the API. Mr. Persister can do the trivial JDBC stuff, and you can do the hard parts.

    That's what Mr. Persister was designed for. It wasn't really intended to be a full ORM implementation. I haven't had the need for one yet either, so that's possibly why :-)


    Thanks for all the comments, guys!!!
  24. All in all...[ Go to top ]

    All in all Mr. Persister is for those who like to have full control using JDBC and SQL, but don't like to do all the trivial mapping yourself.
    ... or need to have full control. Sometimes you need full control to take full advantage of the database you have purchased. Like using Oracle's Context free text search, or other build in functions.
  25. The name... + questions?[ Go to top ]

    Oh, and I'm happy you like the name :-D


    If anyone has anymore questions, follow the link to the website, find our email address and email us. I'll answer any questions within a day or two.
  26. All in all...[ Go to top ]

    All in all Mr. Persister is for those who like to have full control using JDBC and SQL, but don't like to do all the trivial mapping yourself.
    It should have said "but don't like to do all the trivial JDBC code yourself.".

    Even if you do end up creating object mappings manually with Mr. Persister, the API is still capable of doing most of the trivial jobs for you (readByPrimaryKey, insert, update, delete, deleteByPrimaryKey, batch updates etc.), and generate the need SQL for it automatically. Then it's just a single line method call away.

    So it's not just the automatic mapping you get. You are also relieved of the trivial JDBC tasks.
  27. I do indeed have Martin Fowlers "Patterns of Enterprise Application Architecture" on the shelf, and I have noted too that it contains a couple of chapters on ORM. I haven't read the book yet though, even if I probably should have :-)
  28. I would say that Mr. Persister is by far the best ORM product available.
    I dissagree with "by far the best...". But after looking over the site, I am impressed. It is a simple solution, I like that.
  29. neat[ Go to top ]

    Looks very interesting. To me, the main advantages of using this ORM are ease of use and productivity increases gained by eliminating mundane tasks. I also like the fact that you can maintain control over the SQL (complex joins, indeces for performance, or any vendor specific functionalities) and the clever automatic field mapping is neat.

    On the other hand, Mr. Persister doesn't have some of the features of the other products out there (object caching would top my wish list). Like any craftsman, you have to choose the right tool for the job, depending on your requirements.

    I like the clear documentation and I think the 10 minute flash walk through is a trend-setter. A Q&A section would be a nice addition (Do I need to subclass AbstractDao or not? What's the best way of working around subclassing AbstractDao? Do I have to write the SQL myself all the time?). Out-of-the-box functionality is important, especially when one is evaluating products.

    Whats in store for next release?
  30. On the other hand, Mr. Persister doesn't have some of the features of the other products out there (object caching would top my wish list).
    I considered including object caching in the 2.0.0 release or not, but decided to leave it out. The only situations I could see the caching giving any real benefit are in readByPrimaryKey, or readListByPrimaryKeys. That's the only situation in which you can know precisely in advance which object(s) would be loaded from the database. Thus, that would be the only situations you could effectively query the cache for these objects before loading them. You can do this pretty easily yourself. It may be added to a future release though.
    .Whats in store for next release?
    First of all a GenericDao will be added that can be used instead of subclassing AbstractDao. That'll give developers the choice.

    Second two standard ResultSet filters will be added. A PagedReadFilter that will make it easy to read pages (fx from record 200 to 220) from result sets. The other filter will be a CombinedFilter that can combine your own filters + evt. the PagedReadFilter, into one filter.

    Object caching could be another feature, though I'm still not sure of the real benefit.