840 likes | 1.54k Views
iBATIS Background (1). iBATIS project started by Clinton Begin in 2001. In early 2002 Microsoft published a paper claiming that .Net was 10 times faster and 4 times more productive than J2EE. Realizing that this was simply not the case, the iBATIS project quickly responded and on July 1, 2002, JPetStore 1.0 was released. .
E N D
1. iBATIS Framework Presented by
Joe Borosky,
Chris DeCelles,
Yvonne Krashkevich
11-16-05
2. iBATIS Background (1) iBATIS project started by Clinton Begin in 2001.
In early 2002 Microsoft published a paper claiming that .Net was 10 times faster and 4 times more productive than J2EE.
Realizing that this was simply not the case, the iBATIS project quickly responded and on July 1, 2002, JPetStore 1.0 was released.
3. iBATIS Background (2) Based on the same Pet Store requirements, JPetStore demonstrated that Java could not only be more productive than .Net, but could also do so while achieving a better architecture than was used in the Microsoft implementation.
JPetStore made use of an interesting persistence layer that quickly captured the attention of the open source community.
Shortly after releasing JPetStore, questions and requests for the SQL Maps and DAO frameworks spawned the project that would become known as iBATIS Database Layer.
4. iBATIS Background (3) The iBATIS Database Layer includes two frameworks that simply happen to be packaged together: SQL Maps and DAO.
Today the iBATIS project is heavily focused on the persistence layer frameworks known as SQL Maps and Data Access Objects (DAO).
JPetStore lives on as the official example of typical usage of these frameworks.
5. iBATIS Introduction The iBATIS Data Mapper Framework makes it easier to use a database with Java and .Net applications.
iBATIS couples objects with stored procedures or SQL statements using a XML descriptor.
Simplicity is the biggest advantage of the iBATIS Data Mapper over object relational mapping tools.
6. iBATIS Introduction To use the iBATIS Data Mapper you rely on your own objects, XML, and SQL.
There is little to learn that you do not already know.
With the iBATIS Data Mapper you have full power of both SQL and stored procedures at your fingertips.
7. iBATIS Frameworks Overview iBATIS encompasses two completely independent frameworks:
DataMapper framework
DAO Framework
8. iBATIS Data Mapper Framework Significantly reduces the amount of Java and .NET code that is normally needed to access a relational database.
Maps classes to SQL statements using a very simple XML descriptor.
To use iBATIS you need only be familiar with your own application domain objects (basic JavaBeans or .NET classes), XML, and SQL.
Can map nearly any database to any object model and is very tolerant of legacy designs, or even bad designs, without using special database tables, peer objects or code generation.
9. iBATIS DAO Framework iBATIS Data Access Objects is an abstraction layer that hides the details of your persistence solution and provides a common API to the rest of your application.
DAOs allow you to create simple components that provide access to your data without revealing the specifics of the implementation to the rest of your application.
Using DAOs you can allow your application to be dynamically configured to use different persistence mechanisms.
10. iBATIS and SQL Maps The SQL Maps framework is very tolerant of bad database models and even bad object models
However it is recommended to use best practices when designing your database and object model.
By using best practices you will get good performance and a Clean Design.
11. iBATIS and SQL Maps The easiest place to start is to analyze what you’re working with
What are your business objects?
What are your database tables?
How do they relate to each other?
12. First Example: Person Person.Java
package examples.domain;
//imports implied….
public class Person {
private int id;
private String firstName;
private String lastName;
private Date birthDate;
private double weightInKilograms;
private double heightInMeters;
public int getId () {
return id;
}
public void setId (int id) {
this.id = id;
}
//…let’s assume we have the other getters and setters to save space…
}
13. First Example: Person Person.sql
CREATE TABLE PERSON(
PER_ID NUMBER (5, 0) NOT NULL,
PER_FIRST_NAME VARCHAR (40) NOT NULL,
PER_LAST_NAME VARCHAR (40) NOT NULL,
PER_BIRTH_DATE DATETIME ,
PER_WEIGHT_KG NUMBER (4, 2) NOT NULL,
PER_HEIGHT_M NUMBER (4, 2) NOT NULL,
PRIMARY KEY (PER_ID)
)
14. iBATIS and SQL Map Configuration File Once we are comfortable with the classes and tables we are working with the best place to start is the SQL Map configuration file.
This file acts as the root configuration for our SQL Map implementation.
The configuration file is an XML file.
Within the file we will configure properties, JDBC DataSources, and SQL Maps.
15. iBATIS and SQL Map Configuration File The configuration file is a convenient location to centrally configure your DataSource which can be any number of different implementations.
The framework can handle a number of DataSource implementations including
iBATIS Simple DataSource, Jakarta DBCP (Commons), and any DataSource that can be looked up via a JNDI context (Example from within an application server).
16. Sample Configuration File SqlMapConfigExample.xml
Will be discussed later
SqlMapConfigExample.properties
# This is just a simple properties file that simplifies automated
# configuration of the SQL Maps configuration file (e.g. by Ant
# builds or continuous integration tools for different
# environments… etc.) These values can be used in any
# property value in the file above (e.g. “${driver}”)
# Using a properties file such as this is completely optional.
# Driver, url, username, and password change accordingly to fit
# your needs.
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:oracle1
username=jsmith
password=test
17. SQL Map File(s) Person.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN“ "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Person">
<select id="getPerson" resultClass="examples.domain.Person">
SELECT PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms,
PER_HEIGHT_M as heightInMeters
FROM PERSON
WHERE PER_ID = #value#
</select>
</sqlMap>
18. SQL Map File(s) It shows the simplest form of SQL map.
It uses a feature of the SQL Maps framework that automatically maps the columns of a ResultSet to JavaBeans properties (or Map keys, etc.) based on name matching.
The #value# token is an input parameter
More specifically the use of “value” implies that we are using a simple primitive wrapper type.
19. SQL Map File(s) Although very simple there are limitations of using the auto result mapping approach.
There is no way to specify the types of the output columns or
to automatically load related data, and
there is a slight performance implication in that this approach requires accessing the ResultSetMetaData.
We can overcome these limitations by using a resultMap
20. SQL Map File(s) Person.xml (Insert, Update, Delete parts)
<!-- Use Person object (JavaBean) properties as parameters. Each of the parameters in the #hash# symbols is a JavaBeans property. -->
<insert id="insertPerson" parameterClass="examples.domain.Person">
INSERT INTO
PERSON (PER_ID, PER_FIRST_NAME, PER_LAST_NAME,
PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M)
VALUES (#id#, #firstName#, #lastName#, #birthDate#, #weightInKilograms#, #heightInMeters#)
</insert>
<update id="updatePerson" parameterClass="examples.domain.Person">
UPDATE PERSON
SET PER_FIRST_NAME = #firstName#,
PER_LAST_NAME = #lastName#, PER_BIRTH_DATE = #birthDate#,
PER_WEIGHT_KG = #weightInKilograms#,
PER_HEIGHT_M = #heightInMeters#
WHERE PER_ID = #id#
</update>
<delete id="deletePerson" parameterClass="examples.domain.Person">
DELETE PERSON
WHERE PER_ID = #id#
</delete>
21. Programming with the SQL Map Framework Now that we are configured and mapped we need to code in our Java application.
The first step is to configure the SQL Map (this is simply a matter of loading the SQL Map configuration XML file that we created before)
To simplify loading the XML file we can make use of the Resources class included with the framework.
22. Programming with the SQL Map Framework The SqlMapClient object is a long lived thread safe service object.
For a given run of an application you only need to instantiate/configure it once.
This makes it a good candidate for a static member of a base class, or if you prefer to have it more centrally configured and globally available you could wrap it up in a convenience class of your own.
23. Reading Objects from the Database Now that the SqlMap instance is initialized and easily accessible we can make use of it.
To get a Person object from the database we simply need the SqlMap instance, the name of the mapped statement and a PersonID.
SqlMapClient sqlMap = MyAppSqlMapConfig.getSqlMapInstance(); Integer personPk = new Integer(5);
Person person = (Person)
sqlMap.queryForObject (“getPerson”, personPk);
24. Writing Objects to the Database Once we have the database we can modify the data using Insert, Update and Delete
Update
person.setHeightInMeters(1.83); sqlMap.update(“updatePerson”, person);
Delete
sqlMap.delete (“deletePerson”, person);
Insert
Person newPerson = new Person();
newPerson.setId(11);
newPerson.setFirstName(“Clinton”);
…
sqlMap.insert (“insertPerson”, newPerson);
25. Data Mapper Framework One definition of a Mapper is an "object that sets up communication between two independent objects.“
A Data Mapper is a "layer of mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.
You provide the database and the objects; iBATIS provides the mapping layer that goes between the two.
26. Problems solved by iBATIS Data Mapper Separating SQL code from programming code
Passing input parameters to the library classes and extracting the output
Separating data access classes from business logic classes
Caching often-used data until it changes
Managing transactions and threading
27. iBATIS Data Mapper Workflow Provide a parameter, either as an object or a native type. The parameter can used to set runtime values in your SQL statement or stored procedure. If a runtime value is not needed, the parameter can be omitted.
Execute the mapping by passing the parameter and the name you gave the statement or procedure in your XML descriptor. This step is where the magic happens. The framework will prepare the SQL statement or stored procedure, set any runtime values using your parameter, execute the procedure or statement, and return the result.
In the case of an update, the number of rows affected is returned. In the case of a query, a single object, or a collection of objects is returned. Like the parameter, the result object, or collection of objects, can be a plain-old object or a native type. The result can also be given as XML.
28. iBATIS Data Mapper Workflow
29. Generic iBATIS Workflow
30. The SQL Map XML Configuration File The <properties> Element
The <settings> Element
The <typeAlias> Element
The <transactionManager> element
The <dataSource> Element
The <sqlMap> Element
31. Config: <properties> The SQL Map can have a single <properties> element that allows a standard Java properties file (name=value) to be associated with the SQL Map XML configuration document.
By doing so, each named value in the properties file can become a variable that can be referred to in the SQL Map configuration file and all Data Mapper referenced within.
E.g.
<properties resource="properties/database.properties"/>
32. Config: <settings> Note: All settings are optional.
maxRequests:
The maximum number of threads that can execute an SQL statement at a time.
Should usually be at least 10 times maxTransactions and should be greater than maxSessions and maxTransactions.
Reducing the maximum number of concurrent requests can increase performance.
Example: maxRequests=”256”
Default: 512
33. Config: <settings> maxSessions
Number of sessions (or clients) that can be active at a time.
Includes both explicit sessions, requested programmatically, or whenever a thread makes use of an SqlMapClient instance (e.g. executes a statement etc.).
Should always be greater than or equal to maxTransactions and less than maxRequests.
Reducing the maximum number of concurrent sessions can reduce the overall memory footprint.
Example: maxSessions=”64”
Default: 128
34. Config: <settings> maxTransactions
Maximum number of threads that can enter SqlMapClient.startTransaction() at a time.
Should always be less than or equal to maxSessions and always much less than maxRequests.
Often reducing the maximum number of concurrent transactions can increase performance.
Example: maxTransactions=”16”
Default: 32
35. Config: <settings> cacheModelsEnabled
Globally enables or disables all cache models for a SqlMapClient.
Example: cacheModelsEnabled=”true”
Default: true (enabled)
lazyLoadingEnabled
Globally enables or disables all lazy loading for a SqlMapClient.
Example: lazyLoadingEnabled=”true”
Default: true (enabled)
36. Config: <settings> enhancementEnabled
Enables runtime bytecode enhancement to facilitate optimized JavaBean property access as well as enhanced lazy loading.
Example: enhancementEnabled=”true”
Default: false (disabled)
useStatementNamespaces
With this setting enabled, you must always refer to mapped statements by their fully qualified name, which is the combination of the sqlMap name and the statement name.
For example:
queryForObject(“sqlMapName.statementName”);
Example: useStatementNamespaces=”false”
Default: false (disabled)
37. Config: <typeAlias> Allows you to specify a shorter name to refer to what is usually a long, fully qualified classname.
For example:
<typeAlias alias="shortname" type="com.long.class.path.Class"/>
38. Config: <transactionManager> Allows configuration of transaction management services for an SQL Map.
JDBC - Allows JDBC to control the transaction via the usual Connection commit() and rollback() methods.
JTA - Uses a JTA global transaction such that the SQL Map activities can be included as part of a wider scope transaction that possibly involves other databases or transactional resources. Requires a UserTransaction property set to locate the user transaction from a JNDI resource.
EXTERNAL – This allows you to manage transactions on your own. Some part of your application external to Data Mapper must manage the transactions.
39. Config: <dataSource> Included as part of the transaction manager configuration is a dataSource element and a set of properties to configure a DataSource for use with your SQL Map.
There are currently three datasource factories provided with the framework, but you can also write your own.
SimpleDataSourceFactory
DbcpDataSourceFactory
JndiDataSourceFactory
40. Config: <sqlMap> Used to explicitly include an SQL Map or another SQL Map Configuration file.
Each SQL Map XML file that is going to be used by this SqlMapClient instance must be declared.
The SQL Map XML files will be loaded as a stream resource from the classpath or from a URL.
You must specify any and all Data Mappers (as many as there are).
41. Simple SQL Map XML File <sqlMap id=“Product”>
<select id=“getProduct” parameterClass=“ com.ibatis.example.Product”
resultClass=“com.ibatis.example.Product”>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #id#
</select>
</sqlMap>
42. Alternative SQL Map XML File <sqlMap id=“Product”>
<cacheModel id=“productCache” type=”LRU”>
<flushInterval hours=“24”/>
<property name=“size” value=”1000” />
</cacheModel>
<typeAlias alias=“product” type=“com.ibatis.example.Product” />
<parameterMap id=“productParam” class=“product”>
<parameter property=“id”/>
</parameterMap>
<resultMap id=“productResult” class=“product”>
<result property=“id” column=“PRD_ID”/>
<result property=“description” column=“PRD_DESCRIPTION”/>
</resultMap>
<select id=“getProduct” parameterMap=“productParam”
resultMap=“productResult” cacheModel=“product-cache”>
select * from PRODUCT where PRD_ID = ?
</select>
</sqlMap>
43. SQL Maps The Data Mapper concept is centered around mapped statements.
Mapped statements can be any SQL statement and can have parameter maps (input) and result maps (output).
If the case is simple, the mapped statement can be configured directly to a class for parameters and results.
The mapped statement can also be configured to use a cache model to cache popular results in memory.
44. Statement Types <statement>
<insert>
<update>
<delete>
<select>
<procedure>
45. The SQL You can use any SQL that is valid for your database and JDBC driver.
Note: Potential for conflicting SQL/XML special characters, such as the greater-than and less-than symbols.
By using a standard XML CDATA section, none of the special characters will be parsed and the problem is solved.
For example:
<statement id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person">
<![CDATA[
SELECT *
FROM PERSON
WHERE AGE > #value#
]]>
</statement>
46. parameterClass The value of the parameterClass attribute is the fully qualified name of a Java class (including package).
Used to limit parameters passed to the statement, as well as to optimize the performance of the framework.
Example parameterClass with inline parameters:
<statement id=“statementName” parameterClass=” examples.domain.Product”>
insert into PRODUCT values (#id#, #description#, #price#)
</statement>
47. External parameterMap <parameterMap id=“insert-product-param” class=“com.domain.Product”>
<parameter property=“id”/>
<parameter property=“description”/>
</parameterMap>
<statement id=“insertProduct” parameterMap=“insert-product-param”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>
48. Primitive Type Parameters It is not always necessary or convenient to write a JavaBean just to use as a parameter.
In these cases you are perfectly welcome to use a primitive type wrapper object (String, Integer, Date etc.) as the parameter directly.
For example:
<statement id=“insertProduct” parameter=“java.lang.Integer”>
select * from PRODUCT where PRD_ID = #value#
</statement>
49. resultClass The value of the resultClass attribute is the fully qualified name of a Java class (i.e. including package).
The resultClass attribute allows us to specify a class that will be auto-mapped to our JDBC ResultSet based on the ResultSetMetaData.
Wherever a property on the JavaBean and a column of the ResultSet match, the property will be populated with the column value.
50. resultClass Example <statement id="getPerson" parameterClass=“int” resultClass="examples.domain.Person">
SELECT
PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms,
PER_HEIGHT_M as heightInMeters
FROM PERSON
WHERE PER_ID = #value#
</statement>
51. resultMap The value of the resultMap attribute is the name of a defined resultMap element.
The resultMap attribute allows you to control how data is extracted from a result set and which properties to map to which columns.
Unlike the auto-mapping approach using the resultClass attribute, the resultMap allows you to describe the column type, a null value replacement and complex property mappings (including other JavaBeans, Collections and primitive type wrappers).
52. resultMap Example <resultMap id=“get-product-result” class=“com.ibatis.example.Product”>
<result property=“id” column=“PRD_ID”/>
<result property=“description” column=“PRD_DESCRIPTION”/>
</resultMap>
<statement id=“getProduct” resultMap=“get-product-result”>
select * from PRODUCT
</statement>
53. cacheModel The cacheModel attribute value is the name of a defined cacheModel element.
A cacheModel is used to describe a cache for use with a query mapped statement.
Each query mapped statement can use a different cacheModel, or the same one.
54. cacheModel Example <cacheModel id="product-cache" implementation="LRU">
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”size” value=”1000” />
</cacheModel>
<statement id=“getProductList” parameterClass=“int” cacheModel=“product-cache”>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
55. xmlResultName Example <select id="getPerson" parameterClass=”int” resultClass="xml" xmlResultName=”person”>
SELECT
PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms,
PER_HEIGHT_M as heightInMeters
FROM PERSON
WHERE PER_ID = #value#
</select>
56. Resultant XML <person>
<id>1</id>
<firstName>Clinton</firstName>
<lastName>Begin</lastName>
<birthDate>1900-01-01</birthDate>
<weightInKilograms>89</weightInKilograms>
<heightInMeters>1.77</heightInMeters>
</person>
57. iBATIS Data Access Objects Note! The DAO framework and SQLMaps Framework are completely separate and are not dependent on each other in any way.
You can use either one separately, or both together.
58. Introduction
Data Access Objects allow you to create simple components that provide access to your data without revealing the specifics of the implementation to the rest of your application.
If you have a complex application with a number of different databases and persistence approaches involved, DAOs can help you create a consistent API for the rest of your
application to use. iBATIS Data Access Objects
59. iBATIS Data Access Objects Data Access Objects (DAO)
The iBATIS Data Access Objects API can be used to help hide persistence layer implementation details
from the rest of your application by allowing dynamic, pluggable DAO components to be swapped in and
out easily.
For example, you could have two implementations of a particular DAO, one that uses the iBATIS SQL Maps framework to persist objects to the database, and another that uses the Hibernate framework.
60. iBATIS Data Access Objects Data Access Objects (DAO) cont’d
Another example would be a DAO that provides caching services for another DAO.
Depending on the situation (e.g. limited database performance vs. limited memory), either the cache DAO could be “plugged in” or the standard un-cached DAO could be used.
Finally, the DAO pattern protects your application from possibly being tied to a particular persistence approach.
In the event that your current solution becomes unsuitable (or even unavailable), you can simply create new DAO implementations to support a new solution, without having to modify any code in the other layers of your application.
61. iBATIS Data Access Objects There are a number of classes that make up the DAO API. Each has a very specific and important role.
Components of the Data Access Objects API
Class/ Interface (Pattern)
DaoManager (Façade)
DaoTransaction (Marker Interface)
DaoException (Runtime Exception)
Dao (Marker Interface)
62. iBATIS Data Access Objects DaoManager
Responsible for configuration of the DAO framework (via dao.xml), instantiating Dao implementations and acts as a façade to the rest of the API.
63. iBATIS Data Access Objects Reading the Configuration File
The dao.xml file is read by the static buildDaoManager() method of the DaoManagerBuilder class.
The buildDaoManager() method takes a single Reader instance as a parameter, which can be a simple FileReader that points to a dao.xml file.
64. iBATIS Data Access Objects For example:
65. iBATIS Data Access Objects The DaoConfig (ex: jPetStore)
package com.ibatis.jpetstore.persistence;import com.ibatis.common.resources.Resources;import com.ibatis.dao.client.DaoManager;import com.ibatis.dao.client.DaoManagerBuilder;import java.io.Reader;
/** * <p/> * Date: Mar 6, 2004 11:24:18 PM * * @author Clinton Begin */
66. iBATIS Data Access Objects public class DaoConfig { private static final DaoManager daoManager; static { try { String resource = "com/ibatis/jpetstore/persistence/dao.xml"; Reader reader = Resources.getResourceAsReader(resource); daoManager = DaoManagerBuilder.buildDaoManager(reader); } catch (Exception e) { throw new RuntimeException("Could not initialize DaoConfig. Cause: " + e); } } public static DaoManager getDaomanager() { return daoManager; }}
67. iBATIS Data Access Objects Dao.xml – The Configuration File
The DaoManager is able to parse a special XML file with configuration information for the framework.
The configuration XML file specifies the following:
DAO context
The Transaction Manager implementation for each context
Properties for configuration of the Transaction Manager
The Dao implementations for each associated DAO interface.
68. iBATIS Data Access Objects DAO Context
A DAO context is a grouping of related configuration information and DAO implementations.
Usually a context is associated with a single data source such as a relational database or a flat file.
By configuring multiple contexts, you can easily centralize access configuration to multiple databases.
The DaoManager instance that is built from a dao.xml file is aware of all of the contexts contained within the configuration file.
The context basically bundles DAO implementations together with a transaction manager. The DaoManager knows which DAOs and transaction managers belong to which contexts.
69. iBATIS Data Access Objects Context and the DaoManager
When you request a DAO instance from the DaoManager, the proper transaction manager will be provided with it. Therefore, there is no need to ever access the context or transaction manager directly.
Similarly, depending on which DAOs you work with, transactions will be appropriately started and/or committed appropriately. A transaction will only be started for a context when a method is called on one of the DAOs that belong to the context.
The structure of the DAO configuration file is as follows. Values that you will likely change for your application are highlighted.
70. iBATIS Data Access Objects
71. <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE daoConfig (View Source for full doctype...)>
- <daoConfig>
- <context>
- <transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-config.xml" />
</transactionManager>
<dao interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao" />
<dao interface="com.ibatis.jpetstore.persistence.iface.SequenceDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.SequenceSqlMapDao" />
<dao interface="com.ibatis.jpetstore.persistence.iface.AccountDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao" />
<dao interface="com.ibatis.jpetstore.persistence.iface.CategoryDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.CategorySqlMapDao" />
<dao interface="com.ibatis.jpetstore.persistence.iface.ProductDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.ProductSqlMapDao" />
<dao interface="com.ibatis.jpetstore.persistence.iface.OrderDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.OrderSqlMapDao" />
</context>
</daoConfig> iBATIS Data Access Objects
72. iBATIS Data Access Objects DaoTransaction
A generic interface for marking transactions (connections).
73. iBATIS Data Access Objects Transaction Manager Implementation
SQLMAP - Manages transactions via the SQL Maps framework
Its transaction management services including various DataSource and transaction
manager configurations.
All you need to specify is the SQL Maps configuration file.
74. iBATIS Data Access Objects SQLMAP Transaction Manager
Here is an example configuration:
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource" value="com/domain/dao/sqlmap/SqlMapConfig.xml"/>
</transactionManager>
jPetStore example configuration:
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-
config.xml" />
</transactionManager>
75. iBATIS Data Access Objects Alternate Transaction Managers
HIBERNATE Provides easy integration for Hibernate
and its associated transaction facilities (i.e. SessionFactory, Session, Transaction).
JDBC Manages transactions via the JDBC API using the basic DataSource and Connection interfaces.
JTA Manages JTA global (distributed) transaction services. Requires managed DataSource that can be accessed via JNDI.
EXTERNAL Allows transactions to be controlled externally.
76. iBATIS Data Access Objects DAO Implementation Templates
You may be wondering how the transaction manager configuration works.
Well, for each transaction manager implementations, there is a DAO Template to match it.
The templates provide easy access to the artifacts of each implementation. For example the SQLMAP template provides access to the SqlMapExecutor instance.
77. iBATIS Data Access Objects Templates and Implementation
78. iBATIS Data Access Objects Templates and Implementation
79. iBATIS Data Access Objects Dao Interfaces (ex: jPetStore)
AccountDao
ItemDao
ProductDao
CategoryDao
OrderDao
SequenceDao
<dao interface="com.ibatis.jpetstore.persistence.iface.OrderDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.OrderSqlMapDao" />
80. iBATIS Data Access Objects Implementing the OrderDao Interface
* User: Clinton Begin * Date: Jul 13, 2003 * Time: 8:18:50 PM */package com.ibatis.jpetstore.persistence.iface;import com.ibatis.jpetstore.domain.Order;import com.ibatis.common.util.PaginatedList;import java.util.List;public interface OrderDao { public PaginatedList getOrdersByUsername(String username); public Order getOrder(int orderId); public void insertOrder(Order order);}
81. iBATIS Data Access Objects DaoException
All methods and classes in the DAO API throw this exception exclusively.
Dao implementations should also throw this exception exclusively. Avoid throwing any other exception type, and instead nest them within the DaoException.
82. iBATIS Data Access Objects Dao
A marker interface for all DAO implementations.
This interface must be implemented by all DAO classes.
This interface does not declare any methods to be implemented, and only acts as a marker (i.e.
something for the DaoFactory to identify the class by).
83. Conclusion iBATIS Framework
Easy to learn.
SQL Maps/ Data Mapper and Data Access Objects can be utilized together or independently.
Data Mapper
Provides a clean design for your system by separating your programming code from the SQL code.
Provides additional features such as caching, threading and transaction management.
Data Access Objects
Allows you to create simple components that provide access to your data without revealing the specifics of the implementation to the rest of your application
If you have a complex application with a number of different databases and persistence approaches involved, DAOs can help you create a consistent API for the rest of your
application to use.
84. References iBATIS Home Page:
http://ibatis.apache.org/
Generic Developer Guide
SQL Maps Tutorial
SQL Maps Developer Guide
DAO Developer Guide
jPetStore Installation Instructions
http://alanning.freeshell.org/text/jpetstore/jpetstore_win32_install_walkthrough.html
Alternate iBATIS Example:
http://www.cppunit.org/article/Article/172
85. Questions/Comments