EasyUI学习笔记8:MIS开发利器_ datagrid插件(下)(终结篇)
博客专区 > ooad 的博客 > 博客详情
EasyUI学习笔记8:MIS开发利器_ datagrid插件(下)(终结篇)
ooad 发表于3年前
EasyUI学习笔记8:MIS开发利器_ datagrid插件(下)(终结篇)
  • 发表于 3年前
  • 阅读 335
  • 收藏 1
  • 点赞 0
  • 评论 5

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: 使用datagrid实现数据列表和CRUD操作,并实现与后台action交互,支持后台分页与排序。

一、引言

最后一篇是easyui与struts传递数据。拖了好多天,因为一直没想好怎么写。这部分代码参考了一个开源项目,很早之前写的,具体是哪个我也忘了。例子是easyui+ssh全注解+maven。刚开始笔记想写easyui+ssh+maven完整的,发现内容太多,作为easyui的系列笔记,加上ssh全注解和maven的内容似乎跑题了。

本篇笔记重点介绍如何写action以便于easyui交换数据。其他的部分如感兴趣,可以从我git@osc里面名称为mis项目下载完整代码。项目zip包下载地址为:

http://git.oschina.net/ooad/mis/repository/archive?ref=master

二、SSH必要说明

尽管后台部分本篇不涉及,但是有些内容还是交代一下。

1. 数据库表

示例数据还是之前的客户数据。mysql建表脚本如下:

DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `CUSTOMERNO` varchar(36) NOT NULL,
  `CUSTOMERNAME` varchar(36) NOT NULL,
  `TELEPHONE` varchar(36) DEFAULT NULL,
  `ADDRESS` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `CUSTOMERNO` (`CUSTOMERNO`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;

2 实体类

实体类Customer属性必须与easyui中列名称必须相同,否则无法对应。

3. 服务类

Action代码会有调用service层,CustomerService接口名称及作用如下:

添加客户saveCustomer(Customer customer)

修改用户 updateCustomer(Customer customer)

删除用户 deleteCustomer(int id)

列出所有用户并支持分页和排序List<Customer> findAllCustomer(int page, int rows, String sort, String order)

得到客户总数int getTotal() 

4.控制类

控制层代码采用了注解方式,因此项目需要添加struts2-convention-plugin.jar依赖。

三、Action基类

我们必须清楚两个问题:(1) easyui如果要显示后台的数据,必须向action发出请求。因此action需要接收并处理easyui传递过来的参数。(2)easyui只能认识json,所以后台获取的对象或集合必须转换成json格式。这两个问题都需要在action里进行解决。

为了方便编写action,写了一个封装easyui页面参数的action基类BaseAction,并能实现对象转json,其他Action需继承该类。该类代码如下:

public class BaseAction extends ActionSupport{
    protected int page = 1;
    protected int rows = 20;
    protected String sort;
    protected String order;
    protected int id;
    public void writeJson(int total,List list) {
	try {
		Map<String, Object> maps = new HashMap<String, Object>();		
		maps.put("rows", list);
		maps.put("total", total);
		String json = JSON.toJSONString(maps);
		ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
		ServletActionContext.getResponse().getWriter().write(json);
		ServletActionContext.getResponse().getWriter().flush();
	} catch (IOException e) {
		logger.debug(ExceptionUtil.getExceptionMessage(e));
		}
	}
    public void writeJson(Object object) {
	try {			
		String json = JSON.toJSONString(object);
		ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
		ServletActionContext.getResponse().getWriter().write(json);
		ServletActionContext.getResponse().getWriter().flush();
	} catch (IOException e) {
		logger.debug(ExceptionUtil.getExceptionMessage(e));
		}
	//此处省略了setter和getter
}

对该段代码解释:

1. 分页与排序

为了实现分页,action必须接收easyui的两个参数page和rows,page为页数,rows为每页记录数。

但是在数据库进行分页查找操作是需要指定的参数为第一条记录数和最后一条记录数,因此涉及转换问题。

这个转换可以再action层转换,也可以在dao层转换。

本笔记采用后者。这样目的以便让easyui与action交互更为清晰。此处以Hibernate条件查询为例,dao层基类BaseDao处理分页代码为:

criteria.setFirstResult((page-1) * rows);
criteria.setMaxResults(rows);

这样,在Service层查询分页查找客户的方法findAllCustomer(int page, int rows, String sort, String order)直接用这两个参数。

为了实现字段排序,则需接收sort和order两个参数。sort指定排序字段,order指定升降序

方案同前,BaseDao中支持排序代码如下:

if ("asc".equals(order)) {
	criteria.addOrder(Order.asc(sort));
} else {
	criteria.addOrder(Order.desc(sort));
}
}

2 对象转json

对象转json需要用到工具,Struts本身自带一个json插件。本笔记使用了阿里巴巴的fastjson工具,其实用法都差不多,据说fastjson性能强很多。

Fastjson API入口类是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON类上的静态方法直接完成。

Api如下:

public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本 

参考笔记6,要让datagrid显示数据,远程传递或本地读取的json数据格式如下:

{"total": ,"rows":[
{……},
{…....}
]}

需要提醒的是,这里的rows不是前面的每页记录数rows,这是后台向前台传递的。此处rows实际为数据集合,也就是java对象集合转换后的json。easyui为什么非得用一样的名字呢?

所以此处封装了一个writeJson(int total,List list)的方法,子类action中如果需要将List集合转成json在datagrid中显示就调用该方法。

为了提高可用性,本笔记会将后台操作的结果在前台通过消息提示框显示。写了一个向前台传递消息或数据的类(我竟然也照搬命名为Json,晕掉。此Json非彼Json,容易造成误解,应该改成Result,与前篇easyui的代码中的result相呼应),代码如下:

public class Json implements java.io.Serializable {
	private boolean success = false;
	private String msg = "";
	private Object obj = null;
	//此处省略setter和getter
}

因此,基类中还封装了一个writeJson(object)方法可用来将其转换成json。

四、CustomerAction类

代码有点长,如下:

@Controller
@Action(value = "customer", results = { @Result(name = "customer", location = "/page/ /customer.jsp") })
public class CustomerAction extends BaseAction implements ModelDriven<Customer> {
	@Autowired
	private CustomerService customerService;
	public Customer customer = new Customer();
	/**
	 * 得到数据列表
	 */
	public void grid(){
		int total = customerService.getTotal();
		List<Customer> list = customerService.findAllCustomer(page, rows, sort, order);		
		writeJson(total,list);
	}
	/**
	 * 添加操作
	 */
	public void add(){
			Json result = new Json();
			try {
				customerService.saveCustomer(customer);
				result.setSuccess(true);
				result.setMsg("添加客户成功");				
			} catch (Exception e) {
				result.setMsg("添加客户失败");				
			}
			writeJson(result);
	}
	/**
	 * 修改操作
	 */
	public void edit() {
			Json result = new Json();
			try {
				customerService.updateCustomer(customer);
				result.setSuccess(true);
				result.setMsg("修改客户成功");
				result.setSuccess(true);
			} catch (Exception e) {
				result.setMsg("添加客户失败");
			}
			writeJson(result);
	}
	/**
	 * 删除操作
	 */
	public void remove() {
			Json result = new Json();
			try {
				customerService.deleteCustomer(customer.getId());
				result.setSuccess(true);
				result.setMsg("删除客户成功");
			} catch (Exception e) {
				result.setMsg("删除客户失败");
			}
			writeJson(result);
	}
	@Override
	public Customer getModel() {
		return customer;
	}	
}

说明如下:

(1) @Controller注解这是一个action,不需要再写配置文件了。

(2) @Action(value = "customer", results = { @Result(name = "customer", location = "/page/ /customer.jsp") })

这一长串是干嘛的呢?因为没有配置文件了。此处定义action的名字为customer,对应页面为某路径下的customer.jsp。

(3) 客户控制器(CustomerAction) 继承了基类BaseAction,从而可以接收easyui参数并实现json转换。

(4) 该控制器还实现了Struts的ModelDriven这个接口,并覆写了getModel()。以前还真不知道struts还有这个接口,参考之后发现真心好方便。

Action不用去写vo的setter,直接把easyui中的字段值赋值进入了实例化的customer对象中。爽歪歪!

当然前提条件是表单控件名称必须与实体类中的属性名相同,否则..........

(5) 为了在客户端消息提示操作结果,实例化Json(再次恶心下自己,真心命名不好)对象,把消息内容赋值进去,并调用writejson方法转成json在前台显示。

五、customer.jsp

很简单,把前面笔记的customer.html后缀改成jsp,在<html>前面加上下面这一段就可以了:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
	String contextPath = request.getContextPath();
%>

需要强调的是,使用了注解的action,访问地址有了一些变化,规则为:action名!方法名.action

比如datagrid需要显示数据,需将本地读取url :datagridData.json改成从action中读取,url:customer!grid.action,即调用CustomerAction中的grid()方法得到数据。

grid()实现代码重复下:

public void grid(){
	int total = customerService.getTotal();
	List<Customer> list = customerService.findAllCustomer(page, rows, sort, order);	
	writeJson(total,list);
}

相信看到这,逻辑你已经清楚了。

运行界面和之前没什么变化,只是数据换成了从后台读取。另外,增删改等操作、分页、排序都可以使用了。

共有 人打赏支持
粉丝 93
博文 23
码字总数 17510
评论 (5)
scaujohn
老师,把customer.html的后缀改成jsp是不是有什么别的需要?为什么我在customer.html的url里调用action的grid或者读取本地json都能够正常显示,但是改成jsp文件后却显示不了json里的内容了?
ooad
加上完整路径试下
ooad
或是从git下载完整代码看下
scaujohn

引用来自“ooad”的评论

或是从git下载完整代码看下
路径没有问题,对比了完整代码后,发现我的jsp页面多了一段新建文件时自动生成的DTD声明,应该是不符合W3C标准,删掉之后就可以正常了,谢谢老师
Gelbert
protected int page = 1;
protected int rows = 20;
protected String sort;
protected String order;
protected int id;

这里的参数都是前台直接传来的,添加get,set方法就能自动接收了吗?
这里id干啥用的?接收前台传来的用于删除数据的吗?
×
ooad
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: