以药品表(drug)为例,记录一下struts2框架实现连接数据库,进行数据库的增删改查,连接数据库部分见前一篇博客
使用mysql数据库,drug表结构设计如下图:
增加操作
struts2是基于mvc的设计模式,实现模型、视图和控制器分离,各司其职。我的设计是先将实体数据封装到实体类中(模型),通过jsp页面进行人机交互(视图),由过滤器实现控制(控制器)。
- 模型层设计,即实体类的设计,封装实体属性,并提供get、set方法,代码如下:
package struts2.model;
public class drug {
private String id_drug;
private String name_drug;
private String type_drug;
private String effect;
private String specification;
private String price_purchase;
private String price;
private String date_manufacture;
private String date_expiry;
private String place_origin;
private String name_manufactor;
public String getId_drug() {
return id_drug;
}
public void setId_drug(String id_drug) {
this.id_drug = id_drug;
}
public String getName_drug() {
return name_drug;
}
public void setName_drug(String name_drug) {
this.name_drug = name_drug;
}
public String getType_drug() {
return type_drug;
}
public void setType_drug(String type_drug) {
this.type_drug = type_drug;
}
public String getEffect() {
return effect;
}
public void setEffect(String effect) {
this.effect = effect;
}
public String getSpecification() {
return specification;
}
public void setSpecification(String specification) {
this.specification = specification;
}
public String getPrice_purchase() {
return price_purchase;
}
public void setPrice_purchase(String price_purchase) {
this.price_purchase = price_purchase;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getDate_manufacture() {
return date_manufacture;
}
public void setDate_manufacture(String date_manufacture) {
this.date_manufacture = date_manufacture;
}
public String getDate_expiry() {
return date_expiry;
}
public void setDate_expiry(String date_expiry) {
this.date_expiry = date_expiry;
}
public String getPlace_origin() {
return place_origin;
}
public void setPlace_origin(String place_origin) {
this.place_origin = place_origin;
}
public String getName_manufactor() {
return name_manufactor;
}
public void setName_manufactor(String name_manufactor) {
this.name_manufactor = name_manufactor;
}
}
- 视图层的设计,jsp页面接收数据,输入药品名等药品信息,主键id_drug我是用mysql自动递增的,所以不用人为输入id_drug
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>添加药品</title></head>
<body>
<div align="center">
<h2>新增药品信息</h2>
<form method="post" action="drugAdd.action">
<table>
<tr><th>药品名:</th><td><input type="text" name="name_drug" size="20"></td></tr>
<tr><th>药品类型:</th><td><input type="radio" name="type_drug" value="中成药" checked>中成药
<input type="radio" name="type_drug" value="中草药">中草药
<input type="radio" name="type_drug" value="西药">西药
<input type="radio" name="type_drug" value="静脉注射">静脉注射
<input type="radio" name="type_drug" value="仪器类" >仪器类</td></tr>
<tr><th>主治功效:</th><td><textarea name="effect" rows="3" cols="30"></textarea></td></tr>
<tr><th>规格:</th><td><input type="text" name="specification" size="10"></td></tr>
<tr><th>生产日期:</th><td><input id='date' name="date_manufacture" onfocus="WdatePicker()"></td></tr>
<tr><th>有效期:</th><td><input id='date' name="date_expiry" onfocus="WdatePicker()"></td></tr>
<tr><th>进价:</th><td><input type="text" name="price_purchase" size="10"></td></tr>
<tr><th>售价:</th><td><input type="text" name="price" size="10"></td></tr>
<tr><th>产地:</th><td><input type="text" name="place_origin" size="30"></td></tr>
<tr><th>厂家:</th><td><input type="text" name="name_manufactor" size="30"></td></tr>
<tr><td colspan="2" align="center"><input type="submit" value="提交">
<input type="reset" value="重置"></td></tr>
</table>
</form>
</div>
</body>
</html>
- 控制器设计,首先控制器拦截操作,映射到action类,在调用action类中的方法method,可以将添加操作封装到action类中。从jsp页面接收传递参数我使用的是模型驱动法,首先在action定义中添加模型驱动接口,在action中定实例化类对象,使用该对象的getModel方法,就可以实现封装数据啦。然后调用前一节是用过的DButil类连接数据库,即可进行数据库操作,这部分的代码如下:
public class DrugAction extends ActionSupport implements ModelDriven<drug>{
private static final long serialVersionUID = 1L;
private drug dr=new drug();
public drug getModel() {
return dr;
}
private DButil db=new DButil();
public String drugAdd() {
int result=0;
String sql="insert into drug values(?,?,?,?,?,?,?,?,?,?,?)";
String[] params= {null,dr.getName_drug(),dr.getType_drug(),dr.getEffect(),
dr.getSpecification(),dr.getPrice_purchase(),dr.getPrice(),
dr.getDate_manufacture(),dr.getDate_expiry(),dr.getPlace_origin(),
dr.getName_manufactor()};
result=db.update(sql, params);
if(result==1)
return "success";
else
return "error";
}
从jsp页面接受数据并封装到实体类对象中,连接数据进行添加操作,添加成功,即可返回success
- 配置文件struts.xml,配置该action的名称方法路径,调用方法的传递参数,跳转到不同的界面(即添加成功和失败),struts.xml中加入如下代码:
<package name="drug" extends="struts-default" namespace="/">
<action name="drugAdd" class="struts2.action.DrugAction" method="drugAdd">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
action名随意,但是可以根据方法来命名,class是该action的全路径,method是调用该action的方法,默认是execute(也可以重写)
result是返回的页面,根据调用方法的返回值配置不同的jsp页面
- 以上就配置成功了,打开浏览器,地址栏输入:http:localhost:8080/你的项目名/drugAdd.action就可以访问啦
查询操作
基本步骤和前边一样,这里只说控制器部分。查询也分为两种,一种是查询实体类对象的属性参数值(例如查询某药品的信息);还有一种是查询对象数组(例如查询所有的药品列表)
- 药品信息的查询,和上边一样的方法,现在数据库中查询,例如根据id_drug查询,这里我是用的是值栈valueStack,action操作先将数据放入到值栈中,跳转到显示页面后在将值栈中的数据取出来。值栈是struts2的一种数据结构,使用方法,首先获取context对象,在I调用contex的方法获得valueStack对象,然后使用set方法将数据放到值栈中,部分代码如下:
public String drugCheck() {
ActionContext context=ActionContext.getContext();
ValueStack stack=context.getValueStack();
String sql="select * from drug where id_drug=?";
String[] params= {request.getParameter("id_drug")};
Map dr=null;
dr=db.getMap(sql, params);
try {
if(dr!=null) {
stack.set("drug", dr);
return “success”;
}
else
return "error";
}catch (Exception e) {
e.printStackTrace();
return "error";
}
}
这里说明一下,struts2无request对象,需要先获取request对象才能使用,刚看到截图没截到这部分HttpServletRequest request=ServletActionCOntext.getRequest();
下一步是将查询到的数据在jsp页面中显示出来,这里用到了struts2的标签<s:property>可以获取传递的参数,使用方法,首先引入struts2的标签库
<%@ taglib uri="/struts-tags" prefix="s"%>
然后使用<s:property value="drug.name_drug"/>
传递参数
- 查询对象列表,这里展示查询的另一种方法,现在action中定义一个list对象(因为数据要封装到List中),然后获得该对象的get方法,将查询到的数据封装到list即可,部分代码展示:
public class DrugAction extends ActionSupport implements ModelDriven<drug>{
private static final long serialVersionUID = 1L;
private ArrayList<drug> list=new ArrayList<drug>();
public ArrayList<drug> getList() {
return list;
}
private DButil db=new DButil();
public String drugFindAll() {
String sql="select * from drug";
list=(ArrayList)db.getList(sql, null);
try {
if(list!=null) {
return page;
}
else
return "error";
}catch (Exception e) {
e.printStackTrace();
return "error";
}
}
}
在jsp页面接收显示数据可以用<s:iterator value=“list”/>标签,可以遍历数组集合,使用<s:property value=“name_drug”/>显示数据
修改操作
先查询数据,然后从jsp页面输入要修改的值,链接数据库进行修改。这里有一个问题,查询时执行的操作action完全可以使用上一个,但方便区分可以在跳转到action时添加一个标记,当从修改页面跳到查询action的,他就会跳转到修改页面,否则会跳转到查询页面,部分代码如下:
public String drugEdit() {
int result=0;
String sql="update drug set specification=?,date_manufacture=?,"
+ "date_expiry=?,price_purchase=?,price=?,place_origin=?,name_manufactor=? where id_drug=?";
String[] params= {dr.getSpecification(),dr.getDate_manufacture(),
dr.getDate_expiry(),dr.getPrice_purchase(),dr.getPrice(),
dr.getPlace_origin(),dr.getName_manufactor(),request.getParameter("id_drug")};
result=db.update(sql, params);
if(result==1)
return "success";
else
return "error";
}
删除操作
这里再jsp页面可以有一个小设计,在跳转之前(执行删除操作之前)先提醒(确定要删除吗)<a href="drugDelete.action?id_drug=<s:property value="id_drug"/>" on Click="return confirm('确定要删除吗')">删除药品</a>
删除部分的action代码如下:
public String drugDelete() {
int result=0;
String sql="delete from drug where id_drug=?";
String[] params= {request.getParameter("id_drug")};
result=db.update(sql, params);
if(result==1)
return "success";
else
return "error";
}
到这里就完成基本的增删改查操作啦,别忘了每个action都要配置到struts.xml中,因为这篇文章是后来补的,所以我也忘记了当初报过哪些错了,不过总之也没有很难的地方,所以这次没有我遇到的问题模块了