| 1 |
lars |
1 |
<com:TContent ID="body">
|
|
|
2 |
|
|
|
3 |
<h1>Working With Data Maps</h1>
|
|
|
4 |
|
|
|
5 |
<p>If you want to know how to configure and install SQLMap,
|
|
|
6 |
see the <a href="?page=Manual.Installing">Installation</a> and
|
|
|
7 |
<a href="?page=Manual.Configuring">Configuration</a>.
|
|
|
8 |
But if you want to know how SQLMap really
|
|
|
9 |
works, continue from here.</p>
|
|
|
10 |
|
|
|
11 |
<p>The Data Map definition file is where the interesting stuff happens. Here, you
|
|
|
12 |
define how your application interacts with your database. As mentioned, the
|
|
|
13 |
Data Map definition is an XML descriptor file. By using a service routine
|
|
|
14 |
provided by SQLMap, the XML descriptors are rendered into a client object (or
|
|
|
15 |
Mapper). To access your Data Maps, your application calls the client object
|
|
|
16 |
and passes in the name of the statement you need.</p>
|
|
|
17 |
|
|
|
18 |
<p>The real work of using SQLMap is not so much in the application code, but in
|
|
|
19 |
the XML descriptors that SQLMap renders. Instead of monkeying with application
|
|
|
20 |
source code, you monkey with XML descriptors instead. The benefit is that the
|
|
|
21 |
XML descriptors are much better suited to the task of mapping your object
|
|
|
22 |
properties to database entities. At least, that's our own experience with our
|
|
|
23 |
own applications. Of course, your mileage may vary.</p>
|
|
|
24 |
|
|
|
25 |
<h1>What's in a Data Map definition file, anyway?</h1>
|
|
|
26 |
|
|
|
27 |
<p>If you read the <a href="?page=Tutorial.TestFirst">Tutorial</a>, you've already
|
|
|
28 |
seen some simple Data Map examples like the one below.</p>
|
|
|
29 |
|
|
|
30 |
<com:TTextHighlighter Language="xml" CssClass="source">
|
|
|
31 |
<?xml version="1.0" encoding="UTF-8" ?>
|
|
|
32 |
<sqlMap namespace="LineItem">
|
|
|
33 |
<insert id="InsertLineItem" parameterClass="LineItem">
|
|
|
34 |
INSERT INTO [LinesItem]
|
|
|
35 |
(Order_Id, LineItem_LineNum, Item_Id, LineItem_Quantity, LineItem_UnitPrice)
|
|
|
36 |
VALUES
|
|
|
37 |
(#Order.Id#, #LineNumber#, #Item.Id#, #Quantity#, #Item.ListPrice#)
|
|
|
38 |
</insert>
|
|
|
39 |
</sqlMap>
|
|
|
40 |
</com:TTextHighlighter>
|
|
|
41 |
|
|
|
42 |
<p>This map takes some properties from a <tt>LineItem</tt> instance and merges the
|
|
|
43 |
values into the SQL statement. The value-add is that our SQL in separated from
|
|
|
44 |
our program code, and we can pass our <tt>LineItem</tt> instance directly to a
|
|
|
45 |
library method:</p>
|
|
|
46 |
|
|
|
47 |
<com:TTextHighlighter Language="php" CssClass="source">
|
|
|
48 |
TMapper::instance()->insert("InsertLineItem",$lineItem);
|
|
|
49 |
</com:TTextHighlighter>
|
|
|
50 |
<p>No fuss, no muss.</p>
|
|
|
51 |
|
|
|
52 |
<div class="info"><b class="tip">Info:</b>
|
|
|
53 |
<b>A Quick Glance at Inline Parameters</b>
|
|
|
54 |
<p>
|
|
|
55 |
Say we have a mapped statement element that looks like this:</p>
|
|
|
56 |
<com:TTextHighlighter Language="xml" CssClass="source">
|
|
|
57 |
<statement id="InsertProduct">
|
|
|
58 |
insert into Products (Product_Id, Product_Description)
|
|
|
59 |
values (#Id#, #Description#);
|
|
|
60 |
</statement>
|
|
|
61 |
</com:TTextHighlighter>
|
|
|
62 |
|
|
|
63 |
<p>The inline parameters here are <tt>#Id#</tt> and <tt>#Description#</tt>. Let's
|
|
|
64 |
also say that we have an object with the properties <tt>Id</tt> and
|
|
|
65 |
<tt>Description</tt>. If we set the object properties to 5 and "dog",
|
|
|
66 |
respectively, and passed the object to the mapped statement, we'd end up with
|
|
|
67 |
a runtime query that looked like this:
|
|
|
68 |
<com:TTextHighlighter Language="sql" CssClass="source">
|
|
|
69 |
insert into Products (Product_Id, Product_Description) values (5, 'dog');
|
|
|
70 |
</com:TTextHighlighter>
|
|
|
71 |
See <a href="?page=Manual.InlineParameterMaps">inline parameters</a> for further details.
|
|
|
72 |
</div>
|
|
|
73 |
|
|
|
74 |
<p>But, what if you wanted some ice cream with that pie? And maybe a cherry on
|
|
|
75 |
top? What if we wanted to cache the result of the select? Or, what if we
|
|
|
76 |
didn't want to use SQL aliasing or named parameters. (Say, because we were
|
|
|
77 |
using pre-existing SQL that we didn't want to touch.)
|
|
|
78 |
The following example shows a Data Map that specifies a cache, and uses a
|
|
|
79 |
<tt><parameterMap></tt> and a <tt><resultMap></tt> to keep our SQL pristine.
|
|
|
80 |
</p>
|
|
|
81 |
|
|
|
82 |
<com:TTextHighlighter Language="xml" CssClass="source">
|
|
|
83 |
<?xml version="1.0" encoding="UTF-8" ?>
|
|
|
84 |
<sqlMap namespace="Product">
|
|
|
85 |
|
|
|
86 |
<cacheModel id="productCache" type="LRU">
|
|
|
87 |
<flushInterval hours="24"/>
|
|
|
88 |
<property name="CacheSize" value="1000" />
|
|
|
89 |
</cacheModel>
|
|
|
90 |
|
|
|
91 |
<resultMap id="productResult" class="Product">
|
|
|
92 |
<result property="Id" column="Product_Id"/>
|
|
|
93 |
<result property="Description" column="Product_Description"/>
|
|
|
94 |
</resultMap>
|
|
|
95 |
|
|
|
96 |
<select id="GetProduct" parameterMap="productParam" cacheModel="productCache">
|
|
|
97 |
select * from Products where Product_Id = ?
|
|
|
98 |
</select>
|
|
|
99 |
|
|
|
100 |
<parameterMap id="productParam" class="Product">
|
|
|
101 |
<parameter property="Id"/>
|
|
|
102 |
</parameterMap>
|
|
|
103 |
|
|
|
104 |
</sqlMap>
|
|
|
105 |
</com:TTextHighlighter>
|
|
|
106 |
|
|
|
107 |
<p>In the above example, <tt><parameterMap></tt> maps the SQL "?" to the
|
|
|
108 |
product <tt>Id</tt> property. The <tt><resultMap></tt> maps the columns to our object
|
|
|
109 |
properties. The <tt><cacheModel></tt> keeps the result of the last one thousand of
|
|
|
110 |
these queries in active memory for up to 24 hours.</p>
|
|
|
111 |
|
|
|
112 |
<p>The above example is longer and more complex than
|
|
|
113 |
the previous example, but considering what you get in return, it seems
|
|
|
114 |
like a fair trade. (A bargain even.)</p>
|
|
|
115 |
|
|
|
116 |
<p>Many agile developers would start with something like
|
|
|
117 |
the first example and add features like caching later. If you changed
|
|
|
118 |
the Data Map from the first example to the second example, you
|
|
|
119 |
would not have to touch your application source code at all. You can start
|
|
|
120 |
simple and add complexity only when it is needed.</p>
|
|
|
121 |
|
|
|
122 |
<p>A single Data Map definition file can contain as many Cache Models, Result Maps,
|
|
|
123 |
Parameter Maps, and Mapped Statements (including stored
|
|
|
124 |
procedures), as you like. Everything is loaded into the same configuration, so
|
|
|
125 |
you can define elements in one Data Map and then use them in another. Use
|
|
|
126 |
discretion and organize the statements and maps appropriately for your
|
|
|
127 |
application by finding some logical way to group them.</p>
|
|
|
128 |
|
|
|
129 |
</com:TContent>
|