struts ibatis 学习笔记

有关于示例本身 ( 基础代码源自 learntechnology ,结合自己的习惯有较多改进 )

表设计 PDM :

ibatis_pdm.jpg  
类图:

ibatis_uml.jpg 
所涉及的页面:浏览员工的页面 employee_list.jsp

ibatis_list.jpg 
增加 / 编辑员工信息的页面 employee_add.jsp

ibatis_add.jpg 

学习笔记:

Ibatis 方面:如果要把 ibatis 引入到项目中来,需要做以下方面的工作。

ibatis_jar.jpg 
  * 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 ©

ibatis_project.jpg


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值