📄 lib0082.html
字号:
<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Data Access Object Coding Guidelines</title>
<link rel="STYLESHEET" type="text/css" href="images/xpolecat.css">
<link rel="STYLESHEET" type="text/css" href="images/ie.content.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0081.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0083.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
<br>
<div class="chapter">
<a name="ch12"></a>
<div class="section">
<h2 class="first-section-title"><a name="378"></a><a name="ch12lev1sec1"></a>Data Access Object Coding Guidelines</h2><p class="first-para">The guidelines presented here apply only to custom-coded data access objects (entity bean users can skip to the <a href="LiB0083.html#383" target="_parent" class="chapterjump">next section</a>). <a class="internaljump" href="#ch12list01">Listing 12.1</a> is an example of the guidelines in use.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 12.1: </span>Sample Data Access Object Code</span><a name="379"></a><a name="ch12list01"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
1:import book.sample.vo.PurchaseOrderVO;
2:
3:// some code omitted
4:
5:public class PurchaseOrderDAO
6:{
7: private static final String SELECT_SQL =
8: "select CUSTOMER_ID, DATE_CREATED, DATE_SHIPPED "+
9: " from PURCHASE_ORDER "+
10: " where ORDER_NBR = ?";
11: public PurchaseOrderVO getPurchaseOrder(int orderNbr)
12: throws SQLException
13: {
14: PurchaseOrderVO order = null;
15:
16: PreparedStatement pStmt = null;
17: ResultSet results = null;
18:
19: try
20: {
21: OrderLineItemDAO lineDAO =
22: new OrderLineItemDAO(this._dbConnection);
23: pStmt = this._dbConnection.prepareStatement(
24: SELECT_SQL);
25: pStmt.setInt(1, orderNbr);
26:
27: results = pStmt.executeQuery();
28: if (results.next())
29: {
30: order = new PurchaseOrderVO();
31: order.setOrderNbr(orderNbr);
32: order.setCustomerId(results.getString(
33: "CUSTOMER_ID"));
34: order.setOrderDate(results.getDate(
35: "DATE_CREATED"));
36: order.setShipDate(results.getDate(
37: "DATE_SHIPPED"));
38: order.setOrderedItems(
39: lineDAO.getPOItems(orderNbr));
40: }
41: else
42: {
43: throw new DataNotFoundException
44: ("Purchase order not found. OrderNbr=" +
45: orderNbr);
46: }<a name="380"></a><a name="IDX-156"></a>
47: }
48: finally
49: {
50: // CementJ alternative for close
51: //—> DatabaseUtility.close(results, pStmt);
52:
53: if (results != null)
54: {
55: try {results.close();}
56: catch (SQLException s)
57: {
58: // Log warning here.
59: }
60: }
61: if (pStmt != null)
62: {
63: try {pStmt.close();}
64: catch (SQLException s)
65: {
66: // Log warning here.
67: }
68: }
69: }
70:
71: return order;
72: }
73:}
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<a name="381"></a><a name="IDX-155"></a>
<p class="para">
<i class="emphasis">Source</i>: /src/book/sample/dao/db/PurchaseOrderDAO.java</p>
<p class="para">
<b class="bold">Always pass the database connection from the business logic layer.</b> How database connections are created is deployment specific. For example, you'll do a JNDI look-up for a database connection pool if the deployment is within a container, but you'll create one directly from the JDBC driver if the code is deployed as part of an application. DAO code should be application generic and usable in either place.</p>
<p class="para">The code to make a database connection a settable property isn't complicated. The easiest way is to extend <span class="fixed">DbDataAccessObject</span> (package <span class="fixed">org.cementj.base</span>) from CementJ, which already contains connection-related code.</p>
<p class="para">
<b class="bold">Database objects created within a method should be closed within the</b> <b class="bold">same method.</b> Examples of this kind of object include <span class="fixed">PreparedStatement</span>, <span class="fixed">Statement</span>, <span class="fixed">ResultSet</span>, <span class="fixed">CallableStatement</span> objects. For many database platforms, it's necessary to close <span class="fixed">ResultSet</span>, <span class="fixed">PreparedStatement</span>, <span class="fixed">CallableStatement</span>, and <span class="fixed">Statement</span> objects. Some JDBC drivers close <a name="382"></a><a name="IDX-157"></a>these objects when the <span class="fixed">Connection</span> is closed, and some don't. It's easier to spot bugs involving not closing an objects later if you adopt the convention of closing everything you create at this layer.</p>
<p class="para">Because most JDBC objects throw a checked exception when they are closed, <span class="fixed">close()</span> method calls must be enclosed in verbose try/catch logic. As you can see in <a class="internaljump" href="#ch12list01">listing 12.1</a>, the finally block for the <span class="fixed">SQLException</span> is very verbose. CementJ has a one-line convenience method to close JDBC objects. If you use the CementJ alternative, illustrated in line 51, you can omit lines 53 to 68.</p>
<p class="para">CementJ logs errors on <span class="fixed">close()</span> as a warning but does not produce an exception. If you want different behavior on an error from <span class="fixed">close()</span>, you need to custom code that logic.</p>
<p class="last-para">
<b class="bold">Do not close connection objects or issue commits, rollbacks, or savepoints</b> <b class="bold">within a DAO.</b> Connection objects are created and closed in the business logic layer. Units of work, such as commits and rollbacks, are also handled in the business logic layer. <a href="LiB0089.html#429" target="_parent" class="chapterjump">Chapter 13</a> provides details on how to handle connection class creation, closing, and committing.</p>
</div>
</div><br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0081.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0083.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -