Struts2学习总结(十一):Struts2的CRUD

CRUD是Create(创建)、Read(读取)、Update(更新)和Delete(删除)的缩写。

如果你熟练的掌握了CRUD,就可以应用某个框架来创建普通的应用程序

示例:创建,读取全部信息,删除,更新

(1)创建一个Employee对象:并实现对象属性的set和get方法。创建这个对象的有参和无参的构造方法

package com

public class Employee {
    private Integer id;
    private String firstName;
    private String lastName;
    private String email;

    public void setId(Integer id) {
        this.id = id;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getEmail() {
        return email;
    }

    public String getLastName() {
        return lastName;
    }
    public Employee(Integer id,String firstName,String lastName,String email)
    {
        super();
        this.email=email;
        this.firstName=firstName;
        this.lastName=lastName;
        this.id=id;
    }
    public Employee()
    {

    }
    public String toString() {
        return "Employee [employeeId=" + id + ", firstName="
                + firstName + ", lastName=" + lastName + ", email=" + email
                + "]";
    }
}

(2)创建一个 关数据的基本操作的类:实现获取信息,删除,保存等方法。并没有数据库连接,所以只是用容器存储了数据。

将信息存放在一个Map容器里。因为request是一个Map类型的,将信息就可以存放在request中,以方便读取。

package com;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class Dao {
    /*
    * 对数据进行操作
    *
    * */
    private static Map<Integer ,Employee> emps=new HashMap<Integer,Employee>();
    static {
        emps.put(1001, new Employee(1001, "AA", "aa", "aa@atguigu.com"));
        emps.put(1002, new Employee(1002, "BB", "bb", "bb@atguigu.com"));
        emps.put(1003, new Employee(1003, "CC", "cc", "cc@atguigu.com"));
        emps.put(1004, new Employee(1004, "DD", "dd", "dd@atguigu.com"));
        emps.put(1005, new Employee(1005, "EE", "ee", "ee@atguigu.com"));
    }

    //获取全部信息
    public List<Employee> getEmps() {
        return  new ArrayList<>(emps.values());
    }
    //删除
    public void delete(int id)
    {
        emps.remove(id);
    }
    //存储
    public void save(Employee employee)
    {
        long time=System.currentTimeMillis();
        employee.setId((int)time);
        emps.put(employee.getId(),employee);
    }

    //获取
    public Employee get(Integer id)
    {
        return emps.get(id);
    }


    //更新
    public void update(Employee emp)
    {
        emps.put(emp.getId(),emp);
    }

}

(3)创建Action并实现RequestAware接口 :调用dao层的方法进行操作。

思路一:(较为麻烦),在当前的Action类中定义Employee对象的属性,用于接收参数

package com;

import org.apache.struts2.interceptor.RequestAware;

import java.util.Map;
public class EmpAction implements RequestAware{
    private Dao dao=new Dao();
    private Map<String,Object> request;
    //获得所有信息
    public String list()
    {
        request.put("emps",dao.getEmps());
        return "list";
    }
    //对request进行初始化
    @Override
    public void setRequest(Map<String, Object> arg0) {
        this.request = arg0;
    }

    //定义employee的id属性,以便接受参数
    private Integer id;
    private String firstName;
    private String lastName;
    private String email;

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setId(Integer id) {
        this.id = id;
    }

 

//    private Employee employee;


    //会把请求参数给栈顶的属性。删除后要显示删除后的信息,所以可以跳转到action
    public String delete()
    {
        //返回类型为:redirectAction
        //也可以是chain, 实际上可以不需要用chain
        // 因为:不需要在下一个Action时保留当前Action状态
        //若使拥chain,则达到目标页面后,地址栏显示的依然是删除的页面,刷新时会重复提交
        dao.delete(id);

        return "success";
    }

    public String save()
    {
        //1.获取请求参数:通过定义对应属性的方式
        //2.调用Dao的save方法
       Employee employee=new Employee(null,firstName,lastName,email);
        dao.save(employee);
        //3.通过redirectAction的方式相应给emp-list
        return "success";
    }
}

思路二:

上面的代码因为Action再次编写了Employee属性的set方法,使代码较为冗长。为了程序的简洁性,Struts2框架会将Action和Model分隔开。

 没使用struts-default.xml默认的拦截器栈,而是使用了paramsPrepareParams拦截器栈(params->prepare->modelDriven->params)。

  • 采用了ModelDriven: Action 类实现了 ModelDriven 接口,该拦截器将把 ModelDriven 接口的 getModel() 方法返回的对象置于栈顶。
  • 采用params:把请求参数的值赋给栈顶对象对应的属性.
  • 实现了Prepare接口:执行PrepareInterceptor拦截器。在执行execute()方法前加入一些其他业务逻辑。为ModelDriven的getModel()方法准备model

处理流程:     

  a:  执行ParametersInteceptors的Intecept()方法(params)。把请求参数的值赋给栈顶对象对应的属性. 若栈顶对象没有对应的属性, 则查询
值栈中下一个对象对应的属性...

注意:getModel方法不能提供以下的实现,的确会返回一个Employee对象到值栈的栈顶,但是返回的Emplyoee的成员变量为空

public Employee getModel() {
	return new Employee();
}    

b:实现Prepareable接口,在为Action的方法编写prepareXxx()方法。为ModelDriven准备model

c:先回执行ModelDrivenInterceptor的intecept方法,对这个方法进行解释:

 public String intercept(ActionInvocation invocation) throws Exception {
    	//获取 Action 对象: EmployeeAction 对象, 此时该 Action 已经实现了 ModelDriven 接口
    	//public class EmployeeAction implements RequestAware, ModelDriven<Employee>
        Object action = invocation.getAction();

		//判断 action 是否是 ModelDriven 的实例
        if (action instanceof ModelDriven) {
        	//强制转换为 ModelDriven 类型
            ModelDriven modelDriven = (ModelDriven) action;
            //获取值栈
            ValueStack stack = invocation.getStack();
            //调用 ModelDriven 接口的 getModel() 方法
            //即调用 EmployeeAction 的 getModel() 方法
            /*
            public Employee getModel() {
				employee = new Employee();
				return employee;
			}
            */
            Object model = modelDriven.getModel();
            if (model !=  null) {
            	//把 getModel() 方法的返回值压入到值栈的栈顶. 实际压入的是 EmployeeAction 的 employee 成员变量
            	stack.push(model);
            }
            if (refreshModelBeforeResult) {
                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
            }
        }
        return invocation.invoke();
    }
   

代码示例:

import java.util.Map;

import org.apache.struts2.interceptor.RequestAware;

import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import com.qiaobc.crud.dao.Dao;
import com.qiaobc.crud.domin.Employee;

public class EmployeeAction implements RequestAware, ModelDriven<Employee>, Preparable {

    private Dao dao = new Dao();

    /**
     * 1. 查找所有员工信息
     * @return
     */
    public String list() {
        // 获取所有员工信息,并保存在request请求域中
        request.put("emps", dao.getAll());
        return "list";
    }

    // 获取request请求域所对应的Map对象
    private Map<String, Object> request;

    @Override
    public void setRequest(Map<String, Object> arg0) {
        this.request = arg0;
    }

    /**
     * 2. 删除一条员工信息
     * 方法:在当前Action类中定义employeeId属性,用于接收请求参数
     * 注意:返回结果的类型应为redirectAction,即重定向到action:struts.xml文件配置
     *  若使用chain,则到达目标页面后,地址栏显示的仍为emp-delete.do,会重复提交,不需要在下一个Action时保留上一个Action的状态
     * @return
     */

    public String delete() {
        // 获取请求参数employeeId
        dao.delete(employeeId);
        return "success";
    }

  

    // 定义成员变量employee,利用ModelDriven的getModel()方法为其创建对象并压入值栈

    private Employee employee;
  @Override
    public Employee getModel() {
//      if(employeeId == null) {    
//          // 注意:不能直接使用return new Employee();
//          employee = new Employee();
//      } else {
//          employee = dao.get(employeeId);
//      }
        return employee;
    }
 public String save() {  
// 获取请求参数并封装为Employee对象,添加到数据库中 
dao.add(employee); 
// 返回结果类型仍为redirectAction 
    return "success"; 
   } 
     public void prepareSave() {
         employee = new Employee(); 
     } 



private Integer employeeId; 
public void setEmployeeId(Integer employeeId) 
   { this.employeeId = employeeId; } 
     public String edit() {
     /*************************思路1:*************************/
      // 此时栈顶对象即为employee,其除employeeId属性外均为null
      // 1. 根据请求参数employeeId获取对应的Employee对象
     // Employee emp = dao.get(employee.getEmployeeId());// 
     // 2. 封装栈顶对象employee的属性信息
    // employee.setFirstName(emp.getFirstName());
    // employee.setLastName(emp.getLastName());
   // employee.setEmail(emp.getEmail()); 
/*************************思路2:失败**************************/ 
   // // 经过重新赋值的employee对象不再是栈顶对象
   // employee = dao.get(employee.getEmployeeId()); 
/*************************思路3:**************************/ 
// // 将获取的emp对象直接压入值栈,但有浪费之嫌(此时值栈中有两个Employee对象)
// ActionContext.getContext().getValueStack().push(dao.get(employee.getEmployeeId())); 
/*************************解决方案******************************/ 
// 方案:在genModel()方法中根据请求参数employeeId获取Employee对象并返回 
// 判断是Add还是Edit(判定标准:是否有employeeId参数),Add新建而Edit从数据库中获取 
// 注意:若通过employeeId来判断,则需要在modelDriven拦截器执行前先执行一个params拦截器!
 // 此时可以通过使用paramsPrepareParams拦截器栈来实现,在struts.xml文件中配置即可。 
        return "edit";
} 
public void prepareEdit() 
{ 
      employee = dao.get(employeeId); 
} 
public String update() 
{ 
      dao.update(employee); 
      return "success"; 
 } 
public void prepareUpdate() 
{ 
    employee = new Employee(); 
}
 // 配置PrepareInterceptor的alwaysInvokePrepare属性为false,使当前方法不执行
 @Override 
public void prepare() throws Exception { 
     System.out.println("prepare..."); 
}
}



struts.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <package name="default" namespace="/" extends="struts-default">

        <!-- 配置使用 paramsPrepareParamsStack 作为默认的拦截器栈 -->
        <!-- 修改 PrepareInterceptor 拦截器的 alwaysInvokePrepare 属性值为 false -->
        <interceptors>
            <interceptor-stack name="atguigustack">
                <interceptor-ref name="paramsPrepareParamsStack">
                    <param name="prepare.alwaysInvokePrepare">false</param>
                </interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <default-interceptor-ref name="atguigustack"/>

        <action name="emp-*"
                class="com.EmpAction"
                method="{1}">
            <result name="{1}">emp-{1}.jsp</result>
            <result name="success" type="redirectAction">emp-*</result>
        </action>

        <action name="emp-list"
                class="com.EmpAction"
                method="list">
            <result name="list">/emp-list.jsp</result>
        </action>
    </package>


</struts>
jsp:
emp-edit.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<s:debug></s:debug>
	
	<br>
	<br>
	
	<s:form action="emp-update">
		
		<s:hidden name="employeeId"></s:hidden>
		
		<s:textfield name="firstName" label="FirstName"></s:textfield>
		<s:textfield name="lastName" label="LastName"></s:textfield>
		<s:textfield name="email" label="Email"></s:textfield>
		
		<s:submit></s:submit>		
	</s:form>
	
</body>
</html>
emp-list.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>    
    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

	<s:form action="emp-save">
		
		<s:textfield name="firstName" label="FirstName"></s:textfield>
		<s:textfield name="lastName" label="LastName"></s:textfield>
		<s:textfield name="email" label="Email"></s:textfield>
		
		<s:submit></s:submit>		
	</s:form>

	<br>
	<hr>
	<br>
	
	<table cellpadding="10" cellspacing="0" border="1">
		<thead>
			<tr>
				<td>ID</td>
				<td>FirstName</td>
				<td>LastName</td>
				<td>Email</td>
				<td>Edit</td>
				<td>Delete</td>
			</tr>
		</thead>
		
		<tbody>
			<s:iterator value="#request.emps">
				<tr>
					<td>${employeeId }</td>
					<td>${firstName }</td>
					<td>${lastName }</td>
					<td>${email }</td>
					<td><a href="emp-edit?employeeId=${employeeId }">Edit</a></td>
					<td><a href="emp-delete?employeeId=${employeeId }">Delete</a></td>
				</tr>
			</s:iterator>
		</tbody>
		
	</table>

</body>
</html>

<%
	System.out.println("now: " + new java.util.Date());
%>
index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<a href="emp-list">List All Employees</a>
	
</body>
</html>




总结:
    通过这个增添改查了解到了Struts2的CRUD。实现CRUD时,注意:
保证Action和Model分割开,使用ModelDriven
 为向ModelDriven的getModel()方法准备Model,实现了params拦截器和prepare拦截器。前一个向栈顶对象赋值,后一个获取对象
 在struts.xml不再使用默认拦截器栈,改为paramsPrepareParams拦截器栈(提供了params,prepare,modelDriven)



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值