表设计
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 ©