The iBATIS DataMapper is configured using a central XML descriptor
file, usually named SqlMap.config
, which provides the
details for your data source, data maps, and other features like caching,
transactions, and thread management. At runtime, your application code
will call a class method provided by the iBATIS library to read and parse
your SqlMap.config
file. After parsing the
configuration file, a DataMapper client will be returned by iBATIS for
your application to use.
Currently, the DataMapper framework revolves around the
SqlMapper
class, which acts as a facade to the
DataMapper framework API. You can create a DataMapper client by
instantiating an object of the SqlMapper
class.
An instance of the SqlMapper
class (your
DataMapper client) is created by reading a single configuration file.
Each configuration file can specify one database or data source.
However, you can use multiple DataMapper clients in your application.
Just create another configuration file and pass the name of that file
when the DataMapper client is created. The configuration files might use
a different account with the same database, or reference different
databases on different servers. You can read from one client and write
to another, if that's what you need to do. See Section 4.4.1 for more
details on building a SqlMapper
instance, but
first, let's take a look at the DataMapper configuration file.
A sample configuration file for a .NET web application is shown in Example 4.1. Not all configuration elements are required. The following sections describe the elements of this SqlMap.config file in more detail.
Example 4.1. Sample SqlMap.Config for a .NET Web Application (placed in same directory as web.config)
<?xml version="1.0" encoding="utf-8"?> <sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <!-- Optional --> <properties resource="properties.config"/> <settings> <setting useStatementNamespaces="false"/> <setting cacheModelsEnabled="true"/> <setting validateSqlMap="false"/> </settings> <!-- Not required if providers.config is located in default location --> <providers embedded="resources.providers.config, IBatisNet.Test"/> <database> <provider name="sqlServer1.1"/> <dataSource name="NPetshop" connectionString="user id=${username}; password=${password}; data source=${datasource}; database=${database};"/> </database> <alias> <typeAlias alias="Account" type="IBatisNet.Test.Domain.Account, IBatisNet.Test"/> <typeAlias alias="YesNoBool" type="IBatisNet.Test.Domain.YesNoBoolTypeHandlerCallback, IBatisNet.Test"/> </alias> <typeHandlers> <typeHandler type="bool" dbType="Varchar" callback="YesNoBool"/> </typeHandlers> <sqlMaps> <sqlMap resource="${root}Maps/Account.xml"/> <sqlMap resource="${root}Maps/Category.xml"/> <sqlMap resource="${root}Maps/Product.xml"/> </sqlMaps> </sqlMapConfig>
Sometimes the values we use in an XML configuration file occur in more than one element. Often, there are values that change when we move the application from one server to another. To help you manage configuration values, you can specify a standard properties file (with name=value entries) as part of a DataMapper configuration. Each named value in the properties file becomes a shell variable that can be used in the DataMapper configuration file and your Data Map definition files (see Section 3). For example, if the "properties" file contains
<?xml version="1.0" encoding="utf-8" ?> <settings> <add key="username" value="albert" /> </settings>
then all elements in the DataMapper configuration can use the
variable ${username}
to insert the value
"albert". For example:
<dataSource connectionString="user id=${username};"
Properties are handy during building, testing, and deployment by making it easy to reconfigure your application for multiple environments or use automated tools for configuration such as NAnt.
The <properties> element can accept one of the following attributes to specify the location of the properties file.
Table 4.3. Attributes of the <properties> element
Attribute | Description |
---|---|
resource | Specify the properties file to be loaded from the
root directory of the applicationresource="properties.config" |
url | Specify the properties file to be loaded through an
absolute path.url=" |
embedded | Specify the properties file to be loaded as an
embedded resource in an assembly. Syntax for the embedded
attribute is '[extendednamespace.]filename, the
name of the assembly which contains the embedded
resource'embedded="Resources.properties.config, MyApp.Data" |
You can also specify more than one properties file or add
property keys and values directly into your
SqlMap.config
file by using <property>
elements. For example:
<properties> <property resource="myProperties.config"/> <property resource="anotherProperties.config"/> <property key="host" value="ibatis.com" /> </properties>
Table 4.4. Attributes of the <property> element
Attribute | Description |
---|---|
resource | Specify the properties file to be loaded from the
root directory of the applicationresource="properties.config" |
url | Specify the properties file to be loaded through an
absolute path.url=" |
embedded | Specify the properties file to be loaded as an
embedded resource in an assembly. Syntax for the embedded
attribute is '[extendednamespace.]filename, the
name of the assembly which contains the embedded
resource'embedded="Resources.properties.config, MyApp.Data" |
key | Defines a property key (variable)
namekey="username" |
value | Defines a value that will be used by the DataMapper
in place of the the specified property
key/variablevalue="mydbuser" |
Under ADO.NET, a database system is accessed through a provider.
A database system can use a custom provider or a generic ODBC
provider. The iBATIS .NET DataMapper uses a pluggable approach to
using providers. Each provider is represented by an XML descriptor
element found in a file called providers.config
.
The iBATIS .NET DataMapper distribution includes a standard
providers.config
file with a set of thirteen
prewritten provider elements:
Note | |
---|---|
If you use SQL Server 2005, you can configure the provider to allow Multiple Active Result Set (allowMARS="true") and add MultipleActiveResultSets=true in your connection string. |
The providers.config
file can be found
under \source\IBatisNet.DataMapper.Test\bin\Debug
in the iBATIS .NET source distribution or in the root folder of the
.NET DataMapper binary distribution.
A provider may require libraries that you do not have installed,. Therefore, the provider element has an "enabled" attribute that allows you to disable unused providers. One provider can also be marked as the "default" and will be used if another is not specified by your configuration.
The standard providers.config
file has
sqlServer1.1 set as the default and the sqlServer1.0 provider
disabled. Aside from sqlServer1.1, OleDb1.1, and Odbc1.1, all other
providers are disabled by default. Remember to set the "enabled"
attribute to "true" for the provider that you will be using.
Important | |
---|---|
ByteFx is the recommended provider if you are using MySQL. You may download ByteFx from the MySQLNet SourceForge site (http://sf.net/projects/mysqlnet/). If the ByteFx license is acceptable to you, you may install it as a reference within your application and enable the ByteFx provider. |
Tip | |
---|---|
Be sure to review the |
Table 4.5. Expected default locations of the providers.config file
Windows, Library, or Test projects (using NUnit or equivalent) | With the assembly (.dll) files with the
app.config file |
Web projects | In the project base directory, with the
web.config file |
To use the file, you can copy it into your project at the expected default location, give a path to the file relative to the project root directory, specify a url (absolute path) to its location, or make it an embedded resource of your project. If you copy the file into the expected default location, the <providers> element is not required in your sqlMap.config file.
The <providers> element can accept one of the following attributes to specify the location of the providers.config file.
Table 4.6. Attributes of the <providers> element
Attribute | Description |
---|---|
resource | Specify the file to be loaded from a relative path
from the project root directory. Since the root directory is
different depending on the project type, it is best to use a
properties variable to indicate the relative path. Having
that variable defined in a properties file makes it easy to
change the path to all your Data Mapper configuration
resources in one location.resource="${root}providers.config" |
url | Specify the providers.config to be loaded through an
absolute path.url=" |
embedded | Specify the providers.config file to be loaded as an
embedded resource in an assembly. Syntax for the embedded
attribute is '[extendednamespace.]filename, the
name of the assembly which contains the embedded
resource'embedded="Resources.providers.config, MyApp.Data" |
There are three default settings used by the framework.. The settings appropriate for one application may not be appropriate for another. The <settings> element lets you configure these options and optimizations for the DataMapper instance that is created from the XML document. Each <settings> attribute has a default, and you can omit the <settings> element or any of its attributes. The <settings> attributes and the behavior they control are described in the following table.
Table 4.7. Attributes of the <settings> element
Attribute | Description |
---|---|
cacheModelsEnabled | This setting globally enables or disables all cache models for an DataMapper client. This can come in handy for debugging. Example: cacheModelsEnabled=”true” Default: true (enabled) |
useStatementNamespaces | With this setting enabled, you must always refer
to mapped statements by their fully qualified name, which is
the combination of the sqlMap namesource and the statement id.
For example:
Example: useStatementNamespaces=”false” Default: false (disabled) |
validateSqlMap | This setting globally enables or disables the validation of mapping files against the SqlMapConfig.xsd schema. This can come in handy for debugging. Example: validateSqlMap=”false” Default: false (disabled) |
useReflectionOptimizer | This setting globally enables or disables the usage of reflection to access property/filed value of C# object. The reflection optimizer use will emit types for retrieving, populating, instantiating parameter and result objects. Example: useReflectionOptimizer=”true” Default: true (enabled) |
The <typeAlias> element lets you specify a shorter name in lieu of a fully-qualified classname. For example:
<typeAlias alias="LineItem" type="NPetshop.Domain.Billing.LineItem, NPetshop.Domain" />
You can then refer to LineItem
where you
would normally have to spell-out the fully qualified class name.
Note | |
---|---|
In the .NET implementation, zero or more <typeAlias> elements can appear in the Data Map definition file, within an enclosing <alias> element. |
The <typeAlias> element has two attributes:
Table 4.8. Attributes of the <typeAlias> element
Attribute | Description |
---|---|
alias | A unique identifier for this
elementalias="Category" |
type | The fully-qualified classname, including namespace
referencetype= "IBatisNet.Test.Domain.Category, IBatisNet.Test" |
type="[namespace.class], [assembly name], Version=[version], Culture=[culture], PublicKeyToken=[public token]"For example:
type="MyProject.Domain.LineItem, MyProject.Domain, Version=1.2.3300.0, Culture=neutral, PublicKeyToken=b03f455f11d50a3a"The strongly typed name is desired, although it is also legitimate to use the shorter style assembly type name:
type="MyProject.Domain.LineItem, MyProject.Domain"
The framework predefines some aliases that you can use in your DataMapper configuration and data map files, as shown in Table 4.9.
Table 4.9. Predefined Aliases
CLR Type | Alias |
---|---|
System.ArrayList | list |
System.Boolean | Boolean, bool |
System.Byte | Byte, byte |
System.Char | Char, char |
System.DateTime | dateTime, date |
System.Decimal | Decimal, decimal |
System.Double | Double, double |
System.Guid | guid |
System.Hashtable | map, hashmap, hashtable |
System.Int16 | Int16, short, Short |
System.Int32 | Int32, int, Int, integer, Integer |
System.Int64 | Int64, long, Long |
System.SByte | SByte, sbyte |
System.Single | Float, float, Single, single |
System.String | String, string |
System.TimeSpan | N/A |
System.UInt16 | Short, short |
System.UInt32 | Uint, uint |
System.UInt64 | Ulong, ulong |
The <typeHandler> element allows for the configuration and use of a Custom Type Handler (see the Custom Type Handler section). This extends the DataMapper's capabilities in handling types that are specific to your database provider, are not handled by your database provider, or just happen to be a part of your application design.
<typeHandler type="guid" dbType="Varchar2" callback="GuidVarchar"/>
Note | |
---|---|
The DataMapper for .NET allows for zero or more <typeAlias> elements to appear in the Data Map definition file, within an enclosing <alias> element. |
The <typeHandler> element has three attributes:
Table 4.10. Attributes of the <typeAlias> element
Attribute | Description |
---|---|
type | Refers to the name of the type to
handletype="guid" |
dbType | Indicates the provider dbType to
handledbType="Varchar2"Note: Omit this attribute if you want the type handler to replace the default iBATIS type handler. |
callback | The alias of the custom type handler class
namecallback="GuidVarchar" |
The <database> element encloses elements that configure the database system for use by the framework. These database configuration elements are the <provider> and <datasource> elements.
If the default provider is being used, the <provider>
element is optional. Or, if several providers are available, one may
be selected using the provider element without modifying the
providers.config
file.
<provider name="OleDb1.1" />
The <datasource> element specifies the ADO.NET connection string. Example 4.2, shows sample elements for SQL Server, Oracle, Access, MySql, and PostgreSQL.
Example 4.2. Sample <datasource> and <provider> elements (.NET)
<!-- The ${properties} are defined in an external file, --> <!-- but the values could also be coded inline. --> <!-- Connecting to SQL Server --> <database> <provider name="sqlServer1.1" /> <dataSource name="NPetstore" default="true" connectionString="data source=(local)\NetSDK;database=${database}; user id=${username};password=${password};"/> </database> <!-- Connecting to Oracle --> <database> <provider name="oracleClient1.0"/> <dataSource name="iBatisNet" connectionString="Data Source=${datasource};User Id=${userid};Password=${password}"/> </database> <!-- Connecting to Access --> <database> <provider name="OleDb1.1" /> <dataSource name="NPetstore" default="true" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=${database}"/> </database> <!-- Connecting to a MySQL database --> <database> <provider name="ByteFx" /> <dataSource name="NPetstore" default="true" connectionString="Host=${host};Database=${database}; Password=${password};Username=${username}" /> </database> <!-- Connecting to a PostgreSQL database --> <database> <provider name="PostgreSql0.7" /> <dataSource name="NPetstore" default="true" connectionString="Server=${server};Port=5432;User Id=${userid};Password=${password}; Database=${database};" /> </database>
On a daily basis, most of your work will be with the Data Maps, which are covered by Section 3. The Data Maps define the actual SQL statements or stored procedures used by your application. The parameter and result objects are also defined as part of the Data Map. As your application grows, you may have several varieties of Data Map. To help you keep your Data Maps organized, you can create any number of Data Map definition files and incorporate them by reference in the DataMapper configuration. All of the definition files used by a DataMapper instance must be listed in the configuration file.
Example 4.3 shows <sqlMap> elements for loading a set of Data Map definitions. Note that the <sqlMap> elements are nested in a <sqlMaps> element. For more about Data Map definition files, see Section 3.
Example 4.3. Specifying sqlMap locations
<!-- Relative path from the project root directory using a property variable --> <sqlMaps> <sqlMap resource="${root}Maps/Account.xml"/> <sqlMap resource="${root}Maps/Category.xml"/> <sqlMap resource="${root}Maps/Product.xml"/> </sqlMaps> <!-- Embedded resources using [extendednamespace.]filename, assemblyname --> <sqlMaps> <sqlMap embedded="Maps.Account.xml, MyApp.Data"/> <sqlMap embedded="Maps.Category.xml, MyApp.Data"/> <sqlMap embedded="Maps.Product.xml, MyApp.Data"/> </sqlMaps> <!-- Full URL with a property variable --> <sqlMaps> <sqlMap url="C:/${projectdir}/MyApp/Maps/Account.xml"/> <sqlMap url="C:/${projectdir}/MyApp/Maps/Category.xml"/> <sqlMap url="C:/${projectdir}/MyApp/Maps/Product.xml"/> </sqlMaps>
Tip | |
---|---|
Since the application root directory location differs by project type (Windows, Web, or library), it is best to use a properties variable to indicate the relative path when using the <sqlMap> "resource" attribute. Having a variable defined in a properties file makes it easy to change the path to all your Data Mapper configuration resources in one location (note the ${projectdir} and ${root} variables in the example above). |