表設計
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 ©