《5K入门级项目实战:好来屋在线影院》之第 8 战 —— 电影动态管理、EasyUI DataGrid 数据网格、EasyUI Pagination 分页

OK,这一片博客将要介绍 EasyUI DataGrid 数据网格EasyUI Pagination 分页的使用。

说明:

1、fitColumns:设置为 true,则会自动扩大或缩小列的尺寸以适应网格的宽度并且防止水平滚动

2、pagination:设置为 true,则在数据网格(datagrid)底部显示分页工具栏。

3、rownumbers:显示行号

4、url="/admin/movieDynamic/list":调用 API 接口的地址

5、fit:自适应宽度

6、toolbar:工具栏,引用的是 id=tb 的组件,就是添加、删除的两个功能按钮。

7、field:就是我们后台返回的实体属性。

8、load:加载并显示第一页的行

9、reload:重新加载行,就像 load 方法一样,但是保持在当前页。

EasyUI DataGrid 默认在进入页面时,就加载数据。

可以自学一下 EasyUI DataGrid:http://www.jeasyui.net/plugins/183.html

EasyUI Pagination 分页:http://www.jeasyui.net/plugins/155.html

当然,我们还会涉及到根据条件搜索且分页的情况,绝大部分系统带搜索条件的分页都是重点!

比如我们做一个电影动态信息的模糊搜索功能。

OK,既然要分页,我们先搞好分页需要的类,为了方便,统一都放在 config 包下创建的 mybatis 包下。

如图,我们依次按顺序创建类:SearchInfo(对应前端 EasyUI 的请求参数)、PageQuery(用于数据库分页查询的实体)、SearchInfoUtil(用于构造数据库分页的实体、封装前端 EasyUI 返回参数的工具类)、SearchInterceptor(分页查询的拦截器,拦截每一次查询)、SQLHelper(用于查询总数和构建正确的分页查询语句工具类)

SearchInfo 类完整代码:

package com.movie.config.mybatis;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 对应前端请求的分页查询实体
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-11-24 下午 1:24
 */
public class SearchInfo implements Serializable {

    private static final long serialVersionUID = 3197129545912245975L;

    private int pageNumber;//当前页码

    private int pageSize;//每页显示的最大记录数

    private int total;//记录总数

    private int totalPages;//总页数

    private Map<String, Object> queryParams = new HashMap<>();//搜索条件

    为缩短篇幅,忽略了属性的 get、set 方法,请行增加。
}

PageQuery 类完整代码:

package com.movie.config.mybatis;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 对应操作数据库分页的实体
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-11-24 下午 3:28
 */
public class PageQuery implements Serializable {

    private static final long serialVersionUID = 6735335291649236251L;

    private int pageNumber;//当前页码

    private int pageSize;//每页显示的最大记录数

    private int total;//记录总数

    private int totalPages;//总页数

    private int startIndex;//开始查询的位置

    private int endIndex;//结束查询的位置

    private Map<String, Object> queryParams = new HashMap<>();//搜索条件

    public void setTotal(int total) {
        this.total = total;
        //如果当前页码为负数,则置为 1
        if(this.pageNumber <= 0){
            this.pageNumber = 1;
        }
        //计算总页数,先判断 总记录数 ÷ 每页显示记录数 是否可用整除
        if(this.total % this.pageSize == 0){
            this.totalPages = this.total % this.pageSize;
        }else {
            this.totalPages = (this.total % this.pageSize)+1;
        }
        //判断当前页是否大于总页数
        if(this.pageNumber > this.totalPages){
            this.pageNumber = 1;
        }
        //起始位置的计算
        this.startIndex = (this.pageNumber - 1) * pageSize;
        //结束位置的计算
        if(this.totalPages == 0){
            this.endIndex = 0;
        }else{
            this.endIndex = this.startIndex + this.pageSize -1;
        }
    }

    //重写 toString 方法
    @Override
    public String toString() {
        return "PageQuery{" +
                "pageNumber=" + pageNumber +
                ", pageSize=" + pageSize +
                ", total=" + total +
                ", totalPages=" + totalPages +
                ", startIndex=" + startIndex +
                ", endIndex=" + endIndex +
                ", queryParams=" + queryParams +
                '}';
    }

    //********************* 以下是 get、set 方法 ************************//
    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotal() {
        return total;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }

    public Map<String, Object> getQueryParams() {
        return queryParams;
    }

    public void setQueryParams(Map<String, Object> queryParams) {
        this.queryParams = queryParams;
    }
}

说明:

我们重写了 toString 方法,以及对 setTotal 函数进行了逻辑的处理,其它属性的 get、set 方法不变。

SearchInfoUtil 类完整代码:

package com.movie.config.mybatis;

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

/**
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-11-24 下午 3:23
 */
public class SearchInfoUtil {

    public static final int DEFAULT_PAGE_NUMBER = 1;//默认查询页码
    public static final int DEFAULT_PAGE_SIZE = 10;//默认查询的记录数

    //获取并构造分页查询的入参实体
    public static PageQuery getPageQuery(SearchInfo searchInfo,int page,int rows){
        PageQuery pageQuery = new PageQuery();
        //先设置默认值,后续会覆盖
        pageQuery.setPageNumber(DEFAULT_PAGE_NUMBER);
        pageQuery.setPageSize(DEFAULT_PAGE_SIZE);
        try{
            if(page > 0) pageQuery.setPageNumber(page);
            if(rows > 0) pageQuery.setPageSize(rows);
            //查询参数
            if(null != searchInfo && null != searchInfo.getQueryParams() && searchInfo.getQueryParams().size() > 0){
                pageQuery.setQueryParams(searchInfo.getQueryParams());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return pageQuery;
    }

    //构造成调用者需要的格式,返回给前端
    public static Map<String,Object> getResult(PageQuery pageQuery, List<?> list){
        Map<String,Object> map = new HashMap<>();
        map.put("rows",list);
        map.put("total",pageQuery.getTotal());
        return map;
    }
}

说明:

返回给前端的 getResult 方法里,我们注意到 map 的两个 key 分别是:rows 和 total,这是对应 EasyUI 的分页返回标准数据对象的:http://www.jeasyui.net/plugins/183.html

 

SearchInterceptor 拦截器完整代码:

package com.movie.config.mybatis;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 * 分页查询拦截器
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-11-24 下午 9:32
 */
@Component
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class SearchInterceptor implements Interceptor {

    //拦截器执行的内容
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object param = invocation.getArgs()[1];
        //判断是否要进行分页
        if (param != null && param instanceof PageQuery) {
            PageQuery pageQuery = (PageQuery) param;
            //获取绑定的sql,并将参数对象与sql语句的#{}一一对应
            BoundSql boundSql = mappedStatement.getBoundSql(pageQuery.getQueryParams());
            Object paramObject = boundSql.getParameterObject();
            //获取原始的数据库语句
            String originSql = boundSql.getSql().trim();
            System.out.println("originSql=" + originSql);
            //获取总数
            int total = SQLHelper.getCount(originSql, mappedStatement, paramObject, boundSql);
            pageQuery.setTotal(total);

            //分页查询
            String pageSql = originSql + " limit " + pageQuery.getStartIndex() + "," + pageQuery.getPageSize();
            invocation.getArgs()[2] = new RowBounds(RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);
            BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), pageSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
            MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));
            invocation.getArgs()[0] = newMs;
            invocation.getArgs()[1] = pageQuery.getQueryParams();
        }
        return invocation.proceed();
    }

    //用当前这个拦截器生成对目标target的代理,把目标target和拦截器this传给了包装函数
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    //用于设置额外的参数,参数配置在拦截器的Properties节点里
    @Override
    public void setProperties(Properties properties) {}

    private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(),
                ms.getId(), newSqlSource, ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        if (ms.getKeyProperties() != null) {
            for (String keyProperty : ms.getKeyProperties()) {
                builder.keyProperty(keyProperty);
            }
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.cache(ms.getCache());
        return builder.build();
    }

    public static class BoundSqlSqlSource implements SqlSource {
        private BoundSql boundSql;
        public BoundSqlSqlSource(BoundSql boundSql) {
            this.boundSql = boundSql;
        }
        public BoundSql getBoundSql(Object parameterObject) {
            return boundSql;
        }
    }
}

说明:需要增加 Spring 注解,以便让 Spring 容器进行管理,否则拦截器无效。我们这里增加了通用的注解:@Component

 

SQLHelper 类完整代码:

package com.movie.config.mybatis;

import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-11-24 下午 9:57
 */
public class SQLHelper {

    /**
     * 查询总纪录数
     * @param sql             SQL语句
     * @param mappedStatement mapped
     * @param parameterObject 参数
     * @param boundSql        boundSql
     * @return 总记录数
     * @throws SQLException sql查询错误
     */
    public static int getCount(String sql, MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) throws SQLException {
        String countSql = "select count(*) from (" + sql + ") as tmp_count";
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        int count = 0;
        try {
            //获取数据库连接
            connection = mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();
            //预处理
            ps = connection.prepareStatement(countSql);
            //将值赋值给预处理的对应参数位置
            BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject);
            SQLHelper.setParameters(ps, mappedStatement, countBS, parameterObject);
            rs = ps.executeQuery();//执行查询
            if (rs.next()) {
                count = rs.getInt(1);//返回的第一条记录就是总数量
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            if (connection != null) connection.close();
        }
        return count;
    }

    /**
     * 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler
     *
     * @param ps              表示预编译的 SQL 语句的对象。
     * @param mappedStatement MappedStatement
     * @param boundSql        SQL
     * @param parameterObject 参数对象
     * @throws java.sql.SQLException 数据库异常
     */
    @SuppressWarnings("unchecked")
    public static void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException {
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings != null) {
            Configuration configuration = mappedStatement.getConfiguration();
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
            MetaObject metaObject = parameterObject == null ? null :
                    configuration.newMetaObject(parameterObject);
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                if (parameterMapping.getMode() != ParameterMode.OUT) {
                    Object value;
                    String propertyName = parameterMapping.getProperty();
                    PropertyTokenizer prop = new PropertyTokenizer(propertyName);
                    if (parameterObject == null) {
                        value = null;
                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                        value = parameterObject;
                    } else if (boundSql.hasAdditionalParameter(propertyName)) {
                        value = boundSql.getAdditionalParameter(propertyName);
                    } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) {
                        value = boundSql.getAdditionalParameter(prop.getName());
                        if (value != null) {
                            value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));
                        }
                    } else {
                        value = metaObject == null ? null : metaObject.getValue(propertyName);
                    }
                    @SuppressWarnings("rawtypes")
                    TypeHandler typeHandler = parameterMapping.getTypeHandler();
                    if (typeHandler == null) {
                        throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId());
                    }
                    typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());
                }
            }
        }
    }
}

OK,分页的编码工作基本完成,我们来开发 url="/admin/movieDynamic/list" 这个接口。

在 MovieDynamicController 编写前端请求接口:

package com.movie.controller.admin;

import com.movie.config.mybatis.SearchInfo;
import com.movie.entity.MovieDynamicEntity;
import com.movie.manage.MovieDynamicManage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-11-22 下午 11:46
 */
@RestController
@RequestMapping(value = "/admin/movieDynamic")
public class MovieDynamicController {

    @Autowired
    private MovieDynamicManage movieDynamicManage;

    //保存电影动态信息
    @ResponseBody
    @RequestMapping("/save")
    public Map<String, Object> save(MovieDynamicEntity entity) {
        Map<String, Object> map = new HashMap<>();
        boolean flag = movieDynamicManage.save(entity);
        map.put("flag", flag);
        return map;
    }

    //分页查询电影动态信息
    @ResponseBody
    @RequestMapping("/list")
    public Map<String, Object> list(SearchInfo info, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "rows", required = false) Integer rows) {
        Map<String, Object> map = movieDynamicManage.getList(info, page, rows);
        return map;
    }
}

说明:

我们主要研究的是 list 这个函数,是用来做分页查询的。SearchInfo 对象主要用来获取 queryParams 查询参数的,而 page、rows 则是通过 url 的参数来获取。

MovieDynamicManage 接口增加 getList 方法(代码可以参考前一篇博客):

    //分页查询电影动态信息
    Map<String,Object> getList(SearchInfo info,int page,int rows);

MovieDynamicManageImpl 实现类增加  getList 方法实现:

    //分页查询电影动态信息
    @Override
    public Map<String,Object> getList(SearchInfo info,int page,int rows){
        Map<String,Object> map = new HashMap<>();
        try{
            PageQuery pageQuery = SearchInfoUtil.getPageQuery(info,page,rows);
            List<MovieDynamicEntity> list = movieDynamicService.findBy(pageQuery);
            map = SearchInfoUtil.getResult(pageQuery,list);//封装结果
        }catch (Exception e){
            e.printStackTrace();
        }
        return map;
    }

MovieDynamicService 类增加 findBy 函数:

    //分页查询
    @Transactional(readOnly = true)
    public List<MovieDynamicEntity> findBy(PageQuery pageQuery){
        return movieDynamicDao.findBy(pageQuery);
    }

MovieDynamicDao 接口增加 findBy 函数:

    //分页查询
    List<MovieDynamicEntity> findBy(PageQuery pageQuery);

最后,MovieDynamicEntityMapper.xml 文件增加 findBy 的查询语句,完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.movie.database.dao.MovieDynamicDao">
  <resultMap id="BaseResultMap" type="com.movie.entity.MovieDynamicEntity">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="movie_id" jdbcType="INTEGER" property="movieId" />
    <result column="dynamic" jdbcType="VARCHAR" property="dynamic" />
    <result column="movie_url" jdbcType="VARCHAR" property="movieUrl" />
    <result column="create_time" jdbcType="DATE" property="createTime" />
    <result column="movie_name" jdbcType="VARCHAR" property="movieName" />
  </resultMap>

    <!-- 根据主键 id 删除 -->
  <delete id="delete" parameterType="java.lang.Integer">
    delete from movie_dynamic
    where id = #{id,jdbcType=INTEGER}
  </delete>

    <!-- 新增,发布时间直接使用 mysql 的 now() 函数 -->
  <insert id="insert" parameterType="com.movie.entity.MovieDynamicEntity">
    insert into movie_dynamic
    (movie_id, dynamic,movie_url,create_time)
    values
    (#{movieId,jdbcType=INTEGER},
      #{dynamic,jdbcType=VARCHAR},
      #{movieUrl,jdbcType=VARCHAR},
      now())
  </insert>

  <!-- 分页电影动态信息查询 -->
  <select id="findBy" resultMap="BaseResultMap">
    select d.*,i.movie_name
    from movie_dynamic as d
    LEFT JOIN movie_info as i
    ON d.movie_id = i.id
    <where>
      <if test=" dynamic != null and dynamic != '' ">
        and dynamic like CONCAT('%',#{dynamic,jdbcType=VARCHAR}, '%')
      </if>
    </where>
  </select>

</mapper>

说明:

我们对 movie_info 表进行了左关联查询,就是为了查询电影 id 对应的电影名称,所以需要在返回的结果集里增加电影名称字段:

同样的,在 MovieDynamicEntity 实体类,增加 movieName 属性,并提供 get、set 方法。这里不再赘述。

万事具备,我们来测试一下。我们先在数据库里增加一些测试数据。

INSERT INTO `movie_dynamic` VALUES (2, 1, '动态1', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (3, 1, '动态2', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (4, 1, '动态3', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (5, 1, '动态4', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (6, 1, '动态5', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (7, 1, '动态6', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (8, 1, '动态7', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (9, 1, '动态8', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (10, 1, '动态9', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (11, 1, '动态10', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (12, 1, '动态11', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (13, 1, '动态12', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (14, 1, '动态13', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (15, 1, '动态14', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (16, 1, '动态15', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (17, 1, '动态16', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (18, 1, '动态17', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (19, 1, '动态18', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (20, 1, '动态19', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (21, 1, '动态20', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');
INSERT INTO `movie_dynamic` VALUES (22, 1, '动态21', 'http://player.youku.com/embed/XNDQxNTU1MzM4MA==', '2019-11-24');

 

OK,测试通过。

我们再编写我们的删除 API 接口,注意返回的 key 是 flag

 

我们在 MovieDynamicController 类里增加 delete 请求方法:

//删除电影动态信息
    @ResponseBody
    @RequestMapping("/delete")
    public Map<String,Object> delete(@RequestParam(value="ids")String ids){
        Map<String, Object> map = new HashMap<>();
        boolean flag = movieDynamicManage.delete(ids);
        map.put("flag", flag);
        return map;
    }

MovieDynamicManage 接口增加 delete 方法:

    //删除电影动态信息
    boolean delete(String ids);

 MovieDynamicManageImpl 接口实现类增加 delete 的实现方法:

    //删除电影动态信息
    @Override
    public boolean delete(String ids) {
        boolean flag = false;
        try {
            //用逗号分隔前端传递的 id 集合
            String[] idsArr = ids.split(",");
            for(String id : idsArr){
                movieDynamicService.delete(Integer.parseInt(id));
            }
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

MovieDynamicService 类增加 delete 方法: 

    //删除电影动态信息
    @Transactional(readOnly = false)
    public int delete(Integer id){
        return movieDynamicDao.delete(id);
    }

MovieDynamicDao 接口增加 delete 方法:

    //删除电影动态信息
    int delete(Integer id);

最后,在 MovieDynamicEntityMapper.xml 增加 delete 方法(之前的博客已经有这个代码):

    <!-- 根据主键 id 删除 -->
  <delete id="delete" parameterType="java.lang.Integer">
    delete from movie_dynamic
    where id = #{id,jdbcType=INTEGER}
  </delete>

重启服务,测试:

勾选几条数据,点击删除:

删除动态后,EasyUI 的 DataGrid 有个 reload 方法,重新加载了数据。

  

 

 OK,EasyUI 的 DataGrid 网格数据和 Pagination 分页讲解到这。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值