?
有關于示例本身
(
基礎代碼源自
learntechnology
,結合自己的習慣有較多改進
)
表設計
PDM
:
?
類圖:
所涉及的頁面:瀏覽員工的頁面
employee_list.jsp
增加
/
編輯員工信息的頁面
employee_add.jsp
?
學習筆記:
Ibatis
方面:如果要把
ibatis
引入到項目中來,需要做以下方面的工作。
? * If you want to use bytecode enhancement for advanced lazy loading:
????? CGLIB 2.0????????????? (http://cglib.sf.net)
?
? * If you want to use the Jakarta DBCP connection pool you'll need:
DBCP 1.1?????????????? (http://jakarta.apache.org/commons/dbcp/)
?
? * If you want to use distributed caching you'll need:
????? OSCache 2.0.1????????? (http://www.opensymphony.com/oscache/)
?
? * If you want to use advanced logging you'll need one or both of the following:
????? Commons Logging??????? (http://jakarta.apache.org/commons/)
????? Log4J 1.2.8??????????? (http://logging.apache.org/log4j/docs/)
?
That's it!
Ibatis
基礎配置文件:文件名
,
位置可以任意,一般為
SqlMapConfig.xml
?1
<?
xml?version="1.0"?encoding="UTF-8"
?>
?2
<!
DOCTYPE?sqlMapConfig
?3
????????PUBLIC?"-//iBATIS.com//DTD?SQL?Map?Config?2.0//EN"
?4
????????"http://www.ibatis.com/dtd/sql-map-config-2.dtd"
>
?5
?6
<
sqlMapConfig
>
?7
????
<
properties?
resource
="jdbc.properties"
/>
?8
????
<
settings
?9
???????
cacheModelsEnabled
="true"
10
????????enhancementEnabled
="true"
11
????????useStatementNamespaces
="true"
12
???????lazyLoadingEnabled
="true"
13
???????errorTracingEnabled
="true"
14
???????maxRequests
="32"
15
???????maxSessions
="10"
16
???????maxTransactions
="5"
17
????????????
/>
18
19
????
<
transactionManager?
type
="JDBC"
>
20
????????
<
dataSource?
type
="DBCP"
>
21
????????????
<
property?
name
="JDBC.Driver"
?value
="${driver}"
/>
22
????????????
<
property?
name
="JDBC.ConnectionURL"
?value
="${jdbcURL}"
/>
23
????????????
<
property?
name
="JDBC.Username"
?value
="${username}"
/>
24
????????????
<
property?
name
="JDBC.Password"
?value
="${password}"
/>
25
????????????
<
property?
name
="Pool.MaximumWait"
?value
="30000"
/>
26
????????????
<
property?
name
="Pool.ValidationQuery"
?value
="select?1?from?employee"
/>
27
????????????
<
property?
name
="Pool.LogAbandoned"
?value
="true"
/>
28
????????????
<
property?
name
="Pool.RemoveAbandonedTimeout"
?value
="1800000"
/>
29
????????????
<
property?
name
="Pool.RemoveAbandoned"
?value
="true"
/>
30
????????
</
dataSource
>
31
????
</
transactionManager
>
32
33
????
<
sqlMap?
resource
="ibatis/demo/dao/Employee.xml"
/>
34
????
<
sqlMap?
resource
="ibatis/demo/dao/Department.xml"
/>
35
36
</
sqlMapConfig
>
37
?
以上各參數的涵義及默認值見
ibatsi
官方文檔:
iBATIS-SqlMaps-2_en.pdf
?
iBATIS
基礎
dao
啟動類
?1?public?class?BaseIbatisDao?{
?2?
?3?????private?static?BaseIbatisDao?instance?=?new?BaseIbatisDao();
?4?
?5?????private?static?Logger?log?=?Logger.getLogger(BaseIbatisDao.class.getName());
?6?
?7?????protected?static?final?SqlMapClient?sqlMap;
?8?
?9?????static?{
10?
11?????????try?{
12?
13?????????????log.debug("Attempting?to?initialize?SqlMap");
14?
15?????????????String?resource?=?"ibatis/demo/dao/SqlMapConfig.xml";
16?
17?????????????Reader?reader?=?Resources.getResourceAsReader(resource);
18?
19?????????????sqlMap?=?SqlMapClientBuilder.buildSqlMapClient(reader);
20?
21?????????????log.debug("Initialized?SqlMap");
22?
23?????????}?catch?(Exception?e)?{
24?
25?????????????log.error("Error?intializing?BaseIbatisDao?",?e);
26?
27?????????????e.printStackTrace();
28?
29?????????????throw?new?RuntimeException("Error?initializing?BaseIbatisDao?class.?Cause:?"?+?e);
30?
31?????????}
32?
33?????}
34?
35?????protected?BaseIbatisDao()?{
36?
37?????}
38?
39?????public?static?BaseIbatisDao?getInstance()?{
40?
41?????????return?instance;
42?
43?????}
44?
45?}
46?
項目中的
dao
實現類均繼承該
dao
類,調用該類中
SqlMapClient sqlMap
上的各種方法可進行
CRUD
等操作。
sqlMap.queryForList("Employee.getAll", null);
emp = (Employee) sqlMap.queryForObject("Employee.getById", id);
sqlMap.delete("Employee.delete", id);
sqlMap.update("Employee.update", employee);
sqlMap.insert("Employee.insert", employee);
?
iBATIS
典型的
O/R
映射文件配置
Employee.xml
?1?<?xml?version="1.0"?encoding="UTF-8"?>
?2?<!DOCTYPE?sqlMap?PUBLIC?"-//iBATIS.com//DTD?SQL?Map?2.0//EN"?"http://www.ibatis.com/dtd/sql-map-2.dtd">
?3?<sqlMap?namespace="Employee">
?4?
?5?????<typeAlias?type="ibatis.demo.vo.Employee"?alias="emp"/>
?6?????<cacheModel?id="employeesCache"?type="MEMORY"?readOnly="false"?serialize="true">
?7?????????<flushInterval?hours="24"/>
?8?????????<flushOnExecute?statement="Employee.update"/>
?9?????????<flushOnExecute?statement="Employee.insert"/>
10?????????<flushOnExecute?statement="Employee.delete"/>
11?????</cacheModel>
12?
13?????<resultMap?id="employeeResult"?class="emp">
14?????????<result?property="id"?column="id"/>
15?????????<result?property="firstName"?column="firstname"/>
16?????????<result?property="lastName"?column="lastname"/>
17?????????<result?property="age"?column="age"/>
18?????????<result?property="department.id"?column="dept_id"/>
19?????????<result?property="department.name"?column="name"/>
20?????</resultMap>
21?
22?????<select?id="getAll"?resultClass="java.util.HashMap"?cacheModel="employeesCache">
23?????????SELECT
24?????????e.id?AS?id,
25?????????e.firstname?AS?firstName,
26?????????e.lastname?AS?lastName,
27?????????e.age?AS?age,
28?????????d.id?AS?deptId,
29?????????d.name?AS?deptName
30?????????FROM?employee?e,?department?d
31?????????WHERE?e.dept_id?=?d.id
32?????</select>
33?
34?????<!--?the?alias?in?the?following?select?must?match?the?above?employeeResult?'column'!?-->
35????<select?id="getById"?resultMap="employeeResult"?parameterClass="java.lang.Integer">
36?????????SELECT
37?????????e.id,
38?????????e.firstname,
39?????????e.lastname,
40?????????e.age,
41?????????d.id?AS?dept_id,
42?????????d.name?AS?name
43?????????FROM?employee?e,?department?d
44?????????WHERE?e.id?=?#value#
45?????????AND?e.dept_id?=?d.id
46?????</select>
47?
48?????<update?id="update"?parameterClass="emp">
49?????????UPDATE?employee
50?????????SET
51?????????firstname?=?#firstName#,
52?????????lastname?=?#lastName#,
53?????????age?=?#age#,
54?????????dept_id?=?#department.id#
55?????????WHERE?employee.id?=?#id#
56?????</update>
57?
58?????<insert?id="insert"?parameterClass="emp">
59?????????INSERT?INTO?employee?(?id,?firstname,?lastname,?age,?dept_id?)
60?????????VALUES?(?null,?#firstName#,?#lastName#,?#age#,?#department.id#?)
61?????</insert>
62?
63?????<delete?id="delete"?parameterClass="java.lang.Integer">
64?????????DELETE?FROM?employee?WHERE?employee.id?=?#value#
65?????</delete>??
66?
67?</sqlMap>
68?
以上配置中各參數用法涵義見
iBATIS
官方文檔。需要注意的問題
,
用
##
包裹的是
bean
中
property
的名字,要特別注意
<select>
標簽中取出的字段名或別名和
resultMap
,
resultClass
及在
JSP
頁面取出這些數據時的命名關系
?
Struts
學習筆記:
Struts-config.xml
的位置可以和其它所有的配置文件一起放到
WEB-INF/classes
目錄下便于集中管理。
?
ActionForm
和
VO
之間數值的傳遞
添加的時候從
ActionForm
到
VO
BeanUtils.copyProperties(employee, employeeForm)
而編輯的時候從
VO
到
ActionForm
BeanUtils.copyProperties(employeeForm, employee);
?
頁面中使用
struts
標簽和
JSTL,EL
標簽的好處
,
1
.
URL
前面不用加上
contextRoot
的名字,便于項目的移植
eg: <link href="<c:url value='/css/main.css'/>" rel="stylesheet" type="text/css" />
?
eg: <html:form action="/employee">
?
<
c:url
var
=
"url"
scope
=
"page"
value
=
"/employee.do"
>
???
<
c:param
name
=
"p"
value
=
"addOrUpdateIn"
/>
</
c:url
>
<
a
href
=
"
${url}">Add New Employee</a>
eg: <html:link page="/employee.do?p=chart">View Chart</html:link>
?
2
.
<html:text >
標簽具有數值自動綁定的功能,無需使用
<input>
中的
value
,在編輯記錄或提交記錄出錯時,原有表單數據不會丟失
<html:text property="age" size="10"/>
?
3
.在
ActionForm
中添加錯誤信息可以使用
errors.add("age", new ActionMessage("errors.number", "Age"));
其中
age
表示取出消息的鍵值,
errors.number
是
i18N
文件中的那句,
Age
是那句的參數占位符,可以設計一個通用的
BaseAction,
增加一個寫入消息的方法
可以在頁面中以如下方式取出
?<html:errors property="age"/>
或
?<html:messages id="info">
??? <bean:write name="info" />
?</html:messages>
或
??<html:messages id="info">
???<c:out value="${info}" escapeXml="false" />
??</html:messages>
?
4,
在
actionForm
中可以使用復合類型的數據
public class EmployeeForm extends BaseForm {
??? String id;
??? String firstName;
??? String lastName;
??? String age;
??? Department department; //
使用復合類型
?
在
JSP
中存取復合類型數據時,可以使用打
.
的方式
以前項目中的寫法:
<SELECT name="category_id">
?? <c:forEach items="${categorys}" var="category">
??? <OPTION value="${category.id}" <c:if test="${category == blog.category}">selected="selected"</c:if>>
?????? ${category.name}
??? </OPTION>
?? </c:forEach>
</SELECT>
改進后的寫法
(
再不用做
if
判斷了
!)
<
html:select
property
=
"department.id"
>
???
??
<
c:forEach
var
=
"dept"
items
=
"
${departments}">
?????????
<
html:option
value
=
"
${dept.id}">
${dept.name}
?????????
</
html:option
>
?????
</
c:forEach
>
</
html:select
>
?
其它:
關于業務異常
BusinessException,
應設計為
unchecked Exception
在
dao
層的實現類中拋出
在
service
層的接口上聲明
在
struts action
中的關鍵方法如
addOrUpdate, delete
中捕獲
這一步將會增加許多無關代碼,應該放到最后。
?
如果不使用
ant,
而直接使用
MyEclipse
發布,方法是
MyEclipse->Add Web Capability ->
填寫
contextRoot ->
取消
create web.xml
前面的小勾,
OK ?