Discussions

News: O/R Broker 2.0 released

  1. O/R Broker 2.0 released (39 messages)

    O/R Broker v2.0 has been released. O/R Broker is another object-relational tool, except it differs from most in that it allows use of constructors, setter methods, and direct field access, as well as JavaBean properties. The developer maintains all control over SQL, allowing very fine-grained performance.

    O/R Broker serves solely as a broker between the database and an object model. It allows object encapsulation, and doesn't require an object model to follow strict JavaBean rules, which can be useful.

    One of the design goals for O/R Broker was simplicity. There are are only 4 public classes, and an XML Schema file for validation of the configuration. The only dependency is Java 1.4 or better, and there is optional support for Velocity and FreeMarker for dynamic SQL generation.

    Changes from v1.1:
    • Support for static factory methods
    • Support for circular references
    • Better support for stored procedures
    • Support for external connection handling
    Features maintained:
    • Inheritance mapping
    • SQL statements externalized in individual text files
    • Simple API
    Links:

    Threaded Messages (39)

  2. ibatis clone?[ Go to top ]

    Does that project look like http://www.ibatis.com/ clone? Could anyone write short comparison?
  3. ibatis clone?[ Go to top ]

    Does that project look like http://www.ibatis.com/ clone? Could anyone write short comparison?
    This question also came up when v1.1 was released, so I prepared a feature comparison.
  4. ibatis clone?[ Go to top ]

    Does that project look like http://www.ibatis.com/ clone? Could anyone write short comparison?

    Let me also give you this simple Customer mapping example:

    Table definition:
    CREATE TABLE Customer (
       CustomerID INTEGER NOT NULL,
       Name VARCHAR(50) NOT NULL,
       Address VARCHAR(100) NOT NULL,
       LastOrderDate DATE,

       PRIMARY KEY (CustomerID)
    )

    Customer class:
    public class MyCustomer {
        private java.lang.Number customerID;
        private java.lang.CharSequence name;
        private java.lang.StringBuffer address;
        private org.joda.time.YearMonthDay lastOrderDate;
        
        // Setters omitted
    }
    Notice the use of the abstract class Number, interface CharSequence, StringBuffer class, and the JodaTime date class YearMonthDay.

    This will be mapped using this XML configuration:
    <broker>
       <result-object id="Customer" class="package.MyCustomer" key-columns="CustomerID">
          <property name="customerID"><column name="CustomerID"/></property>
          <property name="name"><column name="Name"/></property>
          <property name="address"><column name="Address"/></property>
          <property name="lastOrderDate"><column name="LastOrderDate"/></property>
         </result-object>

       <sql-statement id="selectCustomer" result-object="Customer">
          SELECT
             CustomerID, Name, Address, LastOrderDate
          FROM
             CustomerTable C
          WHERE
             CustomerID = :customerID
       </sql-statement>
    </broker>

    Application code:
    Query qry = broker.startQuery();
    try {
       qry.setParameter("customerID", customerID);
       Customer customer = (Customer) qry.selectOne("selectCustomer");
    } finally {
       qry.close();
    }

    This will execute fine in O/R Broker, because of the intelligent transparent mapping. A similar configuration would choke in iBatis and would require additional configuration and coding of CustomTypeHandlers.
  5. This will be mapped using this XML configuration:
    <broker>&nbsp;<result-object id="Customer" class="package.MyCustomer" key-columns="CustomerID">
    <property name="customerID"><column name="CustomerID"/></property>
    <property name="name"><column name="Name"/></property>
    <property name="address"><column name="Address"/></property>
    <property name="lastOrderDate"><column name="LastOrderDate"/></property>
    </result-object>
    This example actually brings an interesting point. As you can see, the property and column names are almost the same. Hence, with some extra (and not too complicated) logic in the framework you may not need to provide property-to-column mapping, providing that Java/db design allows. There's a couple of O/R products I know of that supports this. O/R Broker?

    Regards,

    Igor Zavialov, Factoreal Corp.
    Factoreal Web Service API for Financial Data
  6. This example actually brings an interesting point. As you can see, the property and column names are almost the same. Hence, with some extra (and not too complicated) logic in the framework you may not need to provide property-to-column mapping, providing that Java/db design allows. There's a couple of O/R products I know of that supports this. O/R Broker?
    I'm not too sure about this, because O/R Broker is about more than just mapping to properties. For one, it also maps to fields, so which should an automapping default to? And what about mixed mapping (constructor, methods, fields and properties)? Do we specify the constructor, methods and fields, and automap the properties? Now mapping transparency is lost. I'll need to consider this some more, but it's an option for v2.1.
  7. ibatis clone?[ Go to top ]

    Does that project look like http://www.ibatis.com/ clone? Could anyone write short comparison?

    They say imitation is the highest form of flattery. Well, I for one am flattered (can't speak for the rest of our team). ;-)

    Nils has done some nice work with ObjectBroker. The best thing about it is the support for more class designs without having to follow the beans spec. This is something that is important to the iBATIS team as well. We've definitely seen an increase in the number of people abandoning the JavaBeans specification for more flexibility in their class designs. It is for this reason that iBATIS will soon support constructor and field based mappings.

    That said, kudos to Nils for making this a priority in his framework.

    This flexibility does come at a cost though. The O/R Broker XML file is complex and heavily nested. Granted, O/R broker supports constructors, custom setter methods, fields and properties....all of this flexibility does come at the cost of the complex mapping file. However, I can't believe that it had to be this complex. For example:

    <result-object id="Employee" class="my.package.Employee">
    <constructor>
    <argument class="int">
    <column name="EmployeeId"/>
    </argument>
    </constructor>
    <property name="name">
    <column name="Name"/>
    </property>
    <method name="setSalary">
    <argument class="java.util.BigDecimal">
    <column name="Salary"/>
    </argument>
    <argument class="string">
    <column name="Currency"/>
    </argument>
    </method>
    <field name="SSN">
    <column name="SSN"/>
    </field>
    </result-object>

    Some might argue that this example doesn't use a good class design (which probably makes it a good example). Sometimes we don't have a choice, in which case, O/R broker is awesome for supporting this. However, given a choice, I'd probably not want Salary and Currency as peer properties of my Employee class. A better design IMHO would be Salary of type "Money" on my employee class. Money is responsible for supporting the currency value. With such a class design, and using iBATIS, this mapping would look like this:

    <resultMap id="Employee" class="my.package.Employee">
    <result property="id" column="EmployeeId"/>
    <result property="name" column="Name"/>
    <result property="salary.value" column="Salary"/>
            <result property="salary.currency" column="Currency"/>
    <result property="SSN" column="SSN"/>
    </resultMap>

    * of course, salary would be better as an immutable class with constructor value and currency params.

    Or, with iBATIS and a mapping this simple, you don't need this stanza at all. This statement will automatically map the properties without a separately defined result map.

    <select id="getEmployee" resultClass="my.package.Employee" parameterClass="int">
      SELECT EmployeeId as id,
             Name,
             Salary as "salary.value",
             Currency as "currency.value",
             SSN
      FROM
        Employee
      WHERE
        EmployeeId = #id#
    </select>

    In addition, iBATIS does support quite a few other features not supported by O/R broker. Those that immediately come to mind are:

      * Join mapping of M:N relationships (N+1 selects solution)
      * Optimized dynamic SQL [1]
      * Pluggable Cache models
      * Custom type handlers
      * SQL fragments
      * Pluggable transaction managers (think WebSphere)
      * XML parameters and results
      * Map parameters and results
      * Support for arrays[]
      * Lazy loading of ANY complex type
      * Type aliases
      * Automatic result and parameter mapping
      * More...

    [1] Although O/R broker supports Velocity and Freemarker, the resulting dynamic conditionals and iteration will not be much better than typical Java code. It simply moves the same amount of logic and introduces a 3rd language. iBATIS uses optimized XML tags to allow you to _reduce_ the amount of logic required to implement a dynamic SQL statement.

    Then of course there are the non-technical reasons:

      * Three years worth of production use
      * A very large user community
      * A growing team of 6 committers
      * An active, production quality .NET version

    Finally, I just want to mention a few corrections from the comparison found at the website:

     * Resolves circular references - iBATIS solves circular references the same way O/R broker does...with a cache. But yes, you do have to configure the cache in iBATIS for this to work.

     * Supports declarative and programmatic transaction isolation levels - iBATIS has supported this for the last two versions (at least).

     * Supports inheritance mapping - This has been in the .NET version since day one, and was added to the Java version in 2.1.0.

    When all is said and done, I think Nils did a great job on O/R Broker. I hope this message helped to describe some of the key differences. We always welcome newcomers to he SQL Mapping space, there's lots of room!

    Awesome job Nils!

    Best regards,

    Clinton Begin
    http://www.ibatis.com
  8. Dear TSS staff..... ;-)[ Go to top ]

    Could you please fix the general formatting for messages such that they hold the indentation for pasted code? We do discuss quite a bit of code on this site... ;-)
  9. Dear TSS staff..... ;-)[ Go to top ]

    Could you please fix the general formatting for messages such that they hold the indentation for pasted code? We do discuss quite a bit of code on this site... ;-)

    Clinton, point noted. I fixed the blockquote you had.

    Floyd
  10. ibatis clone?[ Go to top ]

    They say imitation is the highest form of flattery. Well, I for one am flattered (can't speak for the rest of our team). ;-)Nils has done some nice work with ObjectBroker.
    Thank you Clinton.
    The O/R Broker XML file is complex
    Actually, it's simpler than the iBatis DTD.
    and heavily nested.
    More nested than iBatis, yes, but that's a general XML design debate i.e. attributes vs. elements.
    Granted, O/R broker supports constructors, custom setter methods, fields and properties....all of this flexibility does come at the cost of the complex mapping file.


    Nesting != complexity
    There are so many more options to configure in the iBatis configuration than with O/R Broker. Anyone can compare the two iBatis DTDs to the single O/R Broker schema.
    However, I can't believe that it had to be this complex. For example:<result-object id="Employee" class="my.package.Employee"> <constructor> <argument class="int"> <column name="EmployeeId"/> </argument> </constructor> <property name="name"> <column name="Name"/> </property> <method name="setSalary"> <argument class="java.util.BigDecimal"> <column name="Salary"/> </argument> <argument class="string"> <column name="Currency"/> </argument> </method> <field name="SSN"> <column name="SSN"/> </field></result-object>

    Actually, the class attributes are no longer necessary. I need to update the user's guide.
    A better design IMHO would be Salary of type "Money" on my employee class.

    Agreed.
    of course, salary would be better as an immutable class with constructor value and currency params.

    Exactly, which O/R Broker supports.
    Or, with iBATIS and a mapping this simple, you don't need this stanza at all. This statement will automatically map the properties without a separately defined result map.<select id="getEmployee" resultClass="my.package.Employee" parameterClass="int">SELECT EmployeeId as id,
     Name,
     Salary as "salary.value",
     Currency as "currency.value",
     SSN
    FROM
     Employee
    WHERE
     EmployeeId = #id#
    </select>

    Yes, iBatis is great IF you can live with the (in practice) non-encapsulated JavaBeans model.
    * Support for arrays[]

    Arrays are of course fully supported.
    Although O/R broker supports Velocity and Freemarker, the resulting dynamic conditionals and iteration will not be much better than typical Java code. It simply moves the same amount of logic and introduces a 3rd language.


    I would argue that iBatis introduces a new language. O/R Broker simply makes two of the most popular template languages available for dynamic SQL generation, so there is no new language to learn if either is already known. If neither is known, I would argue that both Velocity and FreeMarker are MUCH easier to learn than the iBatis syntax. A look at the iBatis mailing list seems to confirm this.
    * Resolves circular references - iBATIS solves circular references the same way O/R broker does
    From the Developer's Guide:
    Currently the SQL Map framework does not automatically resolve circular relationships. Be
    aware of this when implementing parent/child relationships (trees).
    Maybe it needs updating?
    * Supports declarative and programmatic transaction isolation levels - iBATIS has supported this for the last two versions (at least).
    How would you declare a transaction isolation level in iBatis?
    * Supports inheritance mapping - This has been in the .NET version since day one, and was added to the Java version in 2.1.0.
    I saw that v2.1.0 was just released. Congratulations on finally getting this important feature.
    When all is said and done, I think Nils did a great job on O/R Broker. I hope this message helped to describe some of the key differences. We always welcome newcomers to he SQL Mapping space, there's lots of room!Awesome job Nils!
    Thank you very much Clinton. As you know, I have a lot of respect for your project, and I have never hidden the fact that I was inspired by it.
  11. ibatis clone?[ Go to top ]

    I would argue that iBatis introduces a new language. O/R Broker simply makes two of the most popular template languages available for dynamic SQL generation, so there is no new language to learn if either is already known. If neither is known, I would argue that both Velocity and FreeMarker are MUCH easier to learn than the iBatis syntax. A look at the iBatis mailing list seems to confirm this.
    I would argue that both do not introduce a new language and I think a new client side data access language can be more readable than XML,SQL and template mix. It is a very good idea to separate data access logic, but It must be a good idea to separate mapping engine from parser too (It can help to use custom language)
  12. ibatis clone?[ Go to top ]

    can be more readable than XML,SQL and template mix.

    I don't like having my SQL inside the XML, so I use separate text files per statement. This just leaves the Velocity or FreeMarker syntax, which is really quite readable.
  13. Hi,

    I would be interested in learning how better to deal with circular references using iBATIS SQL Maps 2.1. I just downloaded the new release, and I noticed there are a number of new features that are not yet documented.

    So far I'm following the advice in the 2.0 Developer's Guide and using a second result map, but I feel the problem should be easy to avoid via correct use of a cache (or "Identity Map" pattern).

    Regards

    John Hurst
  14. Hi,I would be interested in learning how better to deal with circular references using iBATIS SQL Maps 2.1

    You should post this to the user mailing list. TSS is not a support forum. :-)

    Cheers,
    Clinton
  15. Transaction support[ Go to top ]

    O/R Broker support transaction?
  16. Transaction support[ Go to top ]

    O/R Broker support transaction?
    Yes, through the Transaction class.
  17. Connection Pool and Cache[ Go to top ]

    How about the support of Connection Pool and Cache?
  18. Connection Pool and Cache[ Go to top ]

    How about the support of Connection Pool and Cache?
    A Broker object wraps a DataSource, which should be supplying the connection pool.
    Because of the potential thread safety issues with caching, I believe that caching belongs at least one layer closer to the application, e.g. the DAO layer.
  19. Connection Pool and Cache[ Go to top ]

    That means I need to do the caching by myself. I am now studying the Object Relationl Mapping solution for my company.
  20. Connection Pool and Cache[ Go to top ]

    That means I need to do the caching by myself.
    All caching requires serious consideration. Since O/R Broker cannot predict or enforce modifications to an object, it is unreliable to have that layer do the caching.
    Caching is a trade-off between competing interest, among those performance and thread safety, something that makes it better handled in the semantically more accurate DAO layer.
  21. All caching requires serious consideration. Since O/R Broker cannot predict or enforce modifications to an object, it is unreliable to have that layer do the caching. Caching is a trade-off between competing interest, among those performance and thread safety, something that makes it better handled in the semantically more accurate DAO layer.

    Would you say more about this? Or could you give me more reference resource?
  22. Would you say more about this?
    A tool like O/R Broker cannot know if an object is immutable or if it is retrieved for display or modification purposes.
    Also it cannot know when an object is updated and persisted.
    One solution is to inform the tool of intended usage through configuration. Unfortunately such intended use cannot be enforced, nor does it provide any semantic means to help a developer avoid non-intended use. This is typically not a problem during development, because the same developers are working on the project, but often becomes a problem when the software enters maintenance mode, and other developers unfamiliar with the intended use, modifies code.
    By puttng the caching in DAO layer, proper semantics can be applied through properly described method names.
  23. O/R Broker 2.0 released[ Go to top ]

    And neither of iBatis or this pile offers anything at all that JDBC doesn't already give you. Yeah, very nice to have beans populated by Resultset objects, but really.. instead of typing up one row for each column in the table, you could:

    bean.setFoo(rs.getObject("foo"));

    And insead of hard-wiring SQL statements for one rdbms in the xml-file you could hard-wire that anywhere else you like. Both of these frameworks are worthless really. They solve problems that don't exist in the first place. They're pimp-my-ride rims. That's all they are.
  24. O/R Broker 2.0 released[ Go to top ]

    And neither of iBatis or this pile offers anything at all that JDBC doesn't already give you.
    Of course not, they rely on JDBC.
    Yeah, very nice to have beans populated by Resultset objects,

    Exactly, they are convenience frameworks.
    instead of typing up one row for each column in the table, you could:bean.setFoo(rs.getObject("foo"));
    Almost. What about null values? What about column names being renamed in JOINs?
    And insead of hard-wiring SQL statements for one rdbms in the xml-file
    O/R Broker allows stand-alone text files.
    Both of these frameworks are worthless really.
    Ouch.
    They're pimp-my-ride rims. That's all they are.
    There's something to be said for a pimped ride.
  25. Pimped Rides[ Go to top ]

    And separating concerns into multiple Java classes is just yet another way to pimp your ride. What a waste of time.
  26. much more fun to get Overhauled[ Go to top ]

    overhaulin' is much cooler than pimping a ride :)

    peter
  27. O/R Broker 2.0 released[ Go to top ]

    Of course not, they rely on JDBC.

    Er.. so does EJB, Hibernate, JDO, EntityEngine, you name it. You missed the point. The point is: O/R Broker doesn't OFFER anything. It's JDBC with a thin layer of uselessness ontop.

    > Almost. What about null values? What about column names being renamed in JOINs?

    What about them?

    > There's something to be said for a pimped ride.

    Pimped ride != crappy ride with pimped rims. This is the same old 92 accord with a two-by-four in the back seat. Only this 92 accord has shiny rims.
  28. O/R Broker 2.0 released[ Go to top ]

    The point is: O/R Broker doesn't OFFER anything.

    iBATIS has hundreds of projects and thousands of users that would indicate that there are many people who would disagree with you.

    You're not wrong for stating your opinion, but that doesn't make you right either.

    O/R Broker has much to offer. We're certainly learning from it.

    Clinton
  29. O/R Broker 2.0 released[ Go to top ]

    Er.. so does EJB, Hibernate, JDO, EntityEngine, you name it. You missed the point. The point is: O/R Broker doesn't OFFER anything. It's JDBC with a thin layer of uselessness ontop.
    Yes, you almost get it. It's a JDBC abstraction layer. It allows you to externalize your SQL statements, it provides unchecked exceptions, it has declarative mapping of queries to objects, it resolves circular references, it enforces transactional integrity, etc.
    As I said earlier, it is basically a convenience framework.
    If you prefer to intermix your SQL with your Java code, have try/catch statements for every little method call in the JDBC API, have other methods accidently modify connection behavior, etc, then more power to you.
    Almost. What about null values? What about column names being renamed in JOINs?
    What about them?
    You gave this example:
    instead of typing up one row for each column in the table, you could:
    bean.setFoo(rs.getObject("foo"));
    That example does not take into consideration if it's a nullable column, nor if it's a renamed column from a JOIN. So you would have to write additional logic and duplicate object mapping code to handle things that are declaratively handled in O/R Broker. Again, if you prefer to code that yourself, that's just fine and dandy with me.
  30. Null values.[ Go to top ]

    So you would have to write additional logic and duplicate object mapping code to handle things that are declaratively handled in O/R Broker. Again, if you prefer to code that yourself, that's just fine and dandy with me.

    Great point nils.

    JDBC is VERY verbose when it comes to nulls. Setting and getting nulls is a practical nightmare.

    Setting:

    if (myObj.getProperty() == null) {
      ps.setNull(3, Types.VARCHAR);
    } else {
      ps.setString(3, myObj.getProperty());
    }

    Getting:

    String s = rs.getString("SOME_COLUMN");
    if (rs.wasNull()) {
      s = null;
    }
    myObj.setProperty(s);

    That's for EACH parameter or result. Yuck!

    iBATIS, O/R Broker, Spring JDBC, Mr. Persister, Axamol SQL, SQLC....all of them offer some value in an effort to reduce the verbosity of JDBC.

    Cheers,
    Clinton
  31. O/R Broker 2.0 released[ Go to top ]

    And neither of iBatis or this pile offers anything at all that JDBC doesn't already give you...Both of these frameworks are worthless really

    Let me help you understand, by giving you an example of the value of both of these frameworks.

    ---This is iBATIS--------------------------------------

    <select id="getEmployee" parameterClass="int" resultClass="my.domain.Employee">
      SELECT EMP_ID as id,
             EMP_NUMBER as employeeNumber
             EMP_FIRST_NAME as firstName,
             EMP_LAST_NAME as lastName,
             EMP_TITLE as title
      FROM EMPLOYEE
      WHERE EMPLOYEE_NUMBER = #id#
    </select>

    Employee emp = (Employee)sqlMap.queryForObject("getEmployee", 99);

    ---This is JDBC---------------------------------------

     public Employee getEmployee (int id) throws SQLException {
        Employee employee = null;
        String sql = "SELECT * FROM EMPLOYEE " +
            "WHERE EMPLOYEE_NUMBER = ?";
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
          conn = dataSource.getConnection ();
          ps = conn.prepareStatement(sql);
          ps.setInt(1, id);
          rs = ps.executeQuery();
          employee = null;
          while (rs.next()) {
            employee = new Employee();
            employee.setId (rs.getInt("EMP_ID"));
            employee.setEmployeeNumber (rs.getInt("EMP_NUMBER"));
    employee.setFirstName (rs.getString("EMP_FIRST_NAME"));
            employee.setLastName (rs.getString("EMP_LAST_NAME"));
            employee.setTitle (rs.getString("EMP_TITLE"));
          }
        } finally {
          try {
            if (rs != null) rs.close();
          } finally {
            try {
              if (ps != null) ps.close();
            } finally {
              if (conn != null) conn.close();
            }
          }
        }
        return employee;
      }
    -------------------

    I'm sure Nils will be happy to share an example of O/R Broker.

    If you don't have a problem with JDBC, then good on you. Enjoy your JDBC coding experience!

    Clinton
  32. Let me help you understand, by giving you an example of the value of both of these frameworks.
    Not an entirely accurate example, but the essence of it is very valid, namely much less code.
    With O/R Broker you also get unchecked exceptions.
  33. Not an entirely accurate example, but the essence of it is very valid, namely much less code.With O/R Broker you also get unchecked exceptions.

    How is it not accurate? You could run that code!

    Also, with iBATIS, you can choose to use unchecked exceptions using either the DAO framework, or by simply wrapping SQLMapClient.

    Unchecked exceptions are a bit dangerous when working with transactions though...a checked exception is notification to the developer that they should use a try{}finally{} block to ensure the transaction ends cleanly.

    Clinton
  34. How is it not accurate? You could run that code!
    Sorry, I misread the code.
    Also, with iBATIS, you can choose to use unchecked exceptions using either the DAO framework, or by simply wrapping SQLMapClient.
    You can always wrap things into something else, but O/R Broker supports unchecked exceptions by default.
    Unchecked exceptions are a bit dangerous when working with transactions though...a checked exception is notification to the developer that they should use a try{}finally{} block to ensure the transaction ends cleanly.
    Whether you simply query or perform transactions, you should always have a finally block to either close your query or transaction. All O/R Broker examples use a finally block for that.
  35. You can always wrap things into something else, but O/R Broker supports unchecked exceptions by default.

    Yes, but I suppose my point is, this isn't an "exceptional" feature (sorry for the pun). :-)

    Checked vs. unchecked is a design choice that the Java community is 50/50 on. There is no "right" way, nor is there significant advantage to either way.

    iBATIS throws the true, original SQLException. If developers choose to change that to an unchecked exception, it's a trivial exercise.

    Cheers,
    Clinton
  36. Yes, but I suppose my point is, this isn't an "exceptional" feature
    I never claimed it as "exceptional", but it's a feature nonetheless.
    Checked vs. unchecked is a design choice that the Java community is 50/50 on. There is no "right" way, nor is there significant advantage to either way. iBATIS throws the true, original SQLException.
    Actually you can go very far in finding the "right" way. If the API user can be expected to reasonably deal with an exception, make it checked. If not, make it unchecked. SQLExceptions are mostly caused by issues outside the developers control, and are widely recognized as annoying because of that.
    O/R Broker wraps the SQLException in into an unchecked exception hierarchy, throwing specific exceptions such as ConstraintException and DeadlockException, which can the be caught as necessary.
  37. The exception hierarchy is nice, and I would agree, that is indeed a feature (checked or not)! ;-)

    Clinton
  38. O/R Broker 2.0 released[ Go to top ]

    Both iBATIS and O/R Broker provide a good solution when you have a lot of SQL that you want to externalize and when you want to map the results to Java objects. If you only have a small amount of SQL code, then Spring's JDBC framework will give you a nice middleground. You can either just query for a RowSet or use a MappingSqlQuery to provide similar functionality.

    --- This is Spring JDBC -------------

    EmpQuery q = new EmpQuery(ds);
    Object[] param = new Object[] {new Integer(99)};
    Employee emp = (Employee)q.findObject(param);

    private class EmpQuery extends MappingSqlQuery {
    private static String sql =
     " SELECT EMP_ID as id," +
     "EMP_NUMBER as employeeNumber" +
     "EMP_FIRST_NAME as firstName," +
     "EMP_LAST_NAME as lastName, " +
     "EMP_TITLE as title" +
     " FROM EMPLOYEE " +
     " WHERE EMPLOYEE_NUMBER = ?";

    public EmpQuery(DataSource dataSource) {
     super(dataSource, sql);
     declareParameter(new SqlParameter("emp_id", Types.NUMERIC));
     compile();
    }

    public Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
     Employee emp = new Employee();
     emp.setId (rs.getInt("EMP_ID"));
     emp.setEmployeeNumber (rs.getInt("EMP_NUMBER"));
     emp.setFirstName (rs.getString("EMP_FIRST_NAME"));
     emp.setLastName (rs.getString("EMP_LAST_NAME"));
     emp.setTitle (rs.getString("EMP_TITLE"));
      return emp;
    }

    }

    This does get you away from the ugly try/catch/finally code that you are forced to use as you saw in Clinton's JDBC example. Spring also integrates with iBATIS to give you unchecked Exceptions in the form of Spring DataAccesExceptions. This is plus in a mixed environment when you use multiple persistence frameworks together with JDBC code -- only one exception hierarchy to worry about.

    Thomas
  39. O/R Broker 2.0 released[ Go to top ]

    This might be easier to read:

    --- This is Spring JDBC -------------

      EmpQuery q = new EmpQuery(ds);
      Object[] param = new Object[] {new Integer(99)};
      Employee emp = (Employee)q.findObject(param);

    private class EmpQuery extends MappingSqlQuery {
        private static String sql =
           " SELECT EMP_ID as id," +
           " EMP_NUMBER as employeeNumber" +
           " EMP_FIRST_NAME as firstName," +
           " EMP_LAST_NAME as lastName, " +
           " EMP_TITLE as title" +
           " FROM EMPLOYEE " +
           " WHERE EMPLOYEE_NUMBER = ?";

        public EmpQuery(DataSource dataSource) {
            super(dataSource, sql);
            declareParameter(new SqlParameter("emp_id", Types.NUMERIC));
            compile();
        }

        public Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
            Employee emp = new Employee();
            emp.setId (rs.getInt("EMP_ID"));
            emp.setEmployeeNumber (rs.getInt("EMP_NUMBER"));
            emp.setFirstName (rs.getString("EMP_FIRST_NAME"));
            emp.setLastName (rs.getString("EMP_LAST_NAME"));
            emp.setTitle (rs.getString("EMP_TITLE"));
            return emp;
        }

    }
  40. 2.0.1 released[ Go to top ]

    Version 2.0.1 released.