Java单体应用 - 项目实战(后台) - 03.后台账户管理 - 17.重构搜索功能

原文地址:http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-rebuild-search.html
更多教程:光束云 - 免费课程

重构搜索功能

序号 文内章节 视频
1 概述 -
2 重构BaseSearcher及ManagerSearcher搜索器 -
3 重构AuthManagerMapper.xml映射文件 -
4 重构BaseDao接口 -
5 重构BaseService接口及AbstractBaseServiceImpl实现 -
6 重构AuthManagerService接口及AuthManagerServiceImpl实现 -
7 重构ManagerController控制器 -
8 实例源码 -

请参照如上章节导航进行阅读

1.概述

通过分析我们的搜索功能代码,可见代码还是未实现复用,接下来我就来改造搜索功能以实现代码复用。

实现思路

  • 查询条件参数统一为 Searcher
  • 改造动态 SQL
  • 提取 DaoServiceServiceImpl 中的通用方法

2.重构BaseSearcher及ManagerSearcher搜索器

修改 iot-cloud-commons 项目下的 BaseSearcher 抽象类,代码如下:

package net.work100.training.stage2.iot.cloud.commons.dto;

import lombok.Data;

import java.io.Serializable;

/**
 * <p>Title: Searcher</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-03-08 16:45
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-08   liuxiaojun     初始创建
 * -----------------------------------------------
 */
@Data
public abstract class BaseSearcher implements Serializable {
    private boolean advanced;
    private String keyword;

    private int start;
    private int length;
}

修改 iot-cloud-web-admin 项目下的 ManagerSearcher 类,代码如下:

package net.work100.training.stage2.iot.cloud.web.admin.dto.auth;

import lombok.Data;
import net.work100.training.stage2.iot.cloud.commons.dto.BaseSearcher;

/**
 * <p>Title: ManagerSearcher</p>
 * <p>Description: </p>
 * <p>Url: http://www.work100.net/training/monolithic-project-iot-cloud-admin.html</p>
 *
 * @author liuxiaojun
 * @date 2020-03-08 17:02
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-08   liuxiaojun     初始创建
 * -----------------------------------------------
 */
@Data
public class ManagerSearcher extends BaseSearcher {
    private String userName;
    private String roles;
    private int status;
}

3.重构AuthManagerMapper.xml映射文件

修改 AuthManagerMapper.xml 映射文件中与搜索相关的语句定义,代码如下:

<sql id="authManagerSearch">
    <if test="!advanced">
        <if test="keyword != null and keyword != ''">
            AND a.user_name LIKE CONCAT('%', #{keyword}, '%')
        </if>
    </if>
    <if test="advanced">
        <if test="userName != null and userName != ''">
            AND a.user_name LIKE CONCAT('%', #{userName}, '%')
        </if>
        <if test="roles != null and roles != ''">
            AND a.roles LIKE CONCAT('%', #{roles}, '%')
        </if>
        <if test="status != -1">
            AND a.status = #{status}
        </if>
    </if>
</sql>

<select id="search" resultType="AuthManager">
    SELECT
      <include refid="authManagerColumns" />
    FROM
      auth_manager AS a
    <where>
        <include refid="authManagerSearch" />
    </where>
    ORDER BY a.id DESC
</select>

<select id="pageSearch" resultType="AuthManager">
    SELECT
      <include refid="authManagerColumns" />
    FROM
      auth_manager AS a
    <where>
        <include refid="authManagerSearch" />
    </where>
    ORDER BY a.id DESC
    LIMIT #{start}, #{length}
</select>

<select id="count" resultType="int">
    SELECT
      COUNT(*)
    FROM
      auth_manager AS a
    <where>
        <include refid="authManagerSearch" />
    </where>
</select>

4.重构BaseDao接口

修改 BaseDao 接口,将搜索的参数改为 Searcher,代码如下:

package net.work100.training.stage2.iot.cloud.commons.dao;

import net.work100.training.stage2.iot.cloud.commons.dto.AbstractBaseDomain;
import net.work100.training.stage2.iot.cloud.commons.dto.BaseSearcher;

import java.util.List;

/**
 * <p>Title: BaseDao</p>
 * <p>Description: 通用 DAO 接口</p>
 *
 * @author liuxiaojun
 * @date 2020-03-18 09:11
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-18   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public interface BaseDao<T extends AbstractBaseDomain, Searcher extends BaseSearcher> {

    /**
     * 查询全部表记录
     *
     * @return
     */
    List<T> selectAll();


    /**
     * 新增
     *
     * @param entity
     */
    void insert(T entity);

    /**
     * 更新
     *
     * @param entity
     */
    void update(T entity);

    /**
     * 删除
     *
     * @param entityKey
     */
    void delete(String entityKey);

    /**
     * 批量删除
     *
     * @param entityKeys
     */
    void multiDelete(String[] entityKeys);

    /**
     * 获取单个对象
     *
     * @param id
     * @return
     */
    T getById(Long id);

    /**
     * 获取单个对象
     *
     * @param entityKey 实体对象Key
     * @return
     */
    T getByKey(String entityKey);

    /**
     * 搜索
     *
     * @param searcher 搜索器
     * @return
     */
    List<T> search(Searcher searcher);

    /**
     * 分页查询
     *
     * @param searcher 搜索器
     * @return
     */
    List<T> pageSearch(Searcher searcher);

    /**
     * 计数统计
     *
     * @param searcher 搜索器
     * @return
     */
    int count(Searcher searcher);
}

5.重构BaseService接口及AbstractBaseServiceImpl实现

BaseService

package net.work100.training.stage2.iot.cloud.commons.service;

import net.work100.training.stage2.iot.cloud.commons.dto.AbstractBaseDomain;
import net.work100.training.stage2.iot.cloud.commons.dto.BaseResult;
import net.work100.training.stage2.iot.cloud.commons.dto.BaseSearcher;
import net.work100.training.stage2.iot.cloud.commons.dto.PageInfo;

import java.util.List;

/**
 * <p>Title: BaseService</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-03-18 09:47
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-18   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public interface BaseService<T extends AbstractBaseDomain, Searcher extends BaseSearcher> {

    /**
     * 查询全部表记录
     *
     * @return
     */
    List<T> selectAll();

    /**
     * 新增
     *
     * @param entity
     * @return
     */
    BaseResult insert(T entity);

    /**
     * 更新
     *
     * @param entity
     * @return
     */
    BaseResult update(T entity);

    /**
     * 删除
     *
     * @param entityKey
     */
    void delete(String entityKey);

    /**
     * 批量删除
     *
     * @param entityKeys
     */
    void multiDelete(String[] entityKeys);

    /**
     * 获取单个对象
     *
     * @param id
     * @return
     */
    T getById(Long id);

    /**
     * 获取对象
     *
     * @param entityKey
     * @return
     */
    T getByKey(String entityKey);

    /**
     * 搜索
     *
     * @param searcher 搜索器
     * @return
     */
    List<T> search(Searcher searcher);

    /**
     * 分页搜索
     *
     * @param draw
     * @param searcher 搜索器
     * @return
     */
    PageInfo<T> pageSearch(int draw, Searcher searcher);
}

AbstractBaseServiceImpl

将搜索的实现提取为 AbstractBaseServiceImpl 中的通用方法,代码如下:

package net.work100.training.stage2.iot.cloud.commons.service.impl;

import net.work100.training.stage2.iot.cloud.commons.dao.BaseDao;
import net.work100.training.stage2.iot.cloud.commons.dto.AbstractBaseDomain;
import net.work100.training.stage2.iot.cloud.commons.dto.BaseSearcher;
import net.work100.training.stage2.iot.cloud.commons.dto.PageInfo;
import net.work100.training.stage2.iot.cloud.commons.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * <p>Title: BaseServiceImpl</p>
 * <p>Description: 通用的抽象Service实现</p>
 *
 * @author liuxiaojun
 * @date 2020-03-18 10:53
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-18   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public abstract class AbstractBaseServiceImpl<T extends AbstractBaseDomain, Searcher extends BaseSearcher, D extends BaseDao<T, Searcher>> implements BaseService<T, Searcher> {

    @Autowired
    private D dao;

    @Override
    public List<T> selectAll() {
        return dao.selectAll();
    }


    @Override
    public T getById(Long id) {
        return dao.getById(id);
    }

    @Override
    public T getByKey(String entityKey) {
        return dao.getByKey(entityKey);
    }


    @Override
    public void delete(String entityKey) {
        dao.delete(entityKey);
    }

    @Override
    public void multiDelete(String[] entityKeys) {
        dao.multiDelete(entityKeys);
    }

    @Override
    public List<T> search(Searcher searcher) {
        return dao.search(searcher);
    }

    @Override
    public PageInfo<T> pageSearch(int draw, Searcher searcher) {
        // 处理分页结果
        PageInfo<T> pageInfo = new PageInfo<>();
        pageInfo.setDraw(draw);

        // 获取记录数
        int recordsTotal = dao.count(searcher);
        pageInfo.setRecordsTotal(recordsTotal);
        pageInfo.setRecordsFiltered(recordsTotal);

        // 获取分页数据
        List<T> data = dao.pageSearch(searcher);
        pageInfo.setData(data);

        return pageInfo;
    }
}

6.重构AuthManagerService接口及AuthManagerServiceImpl实现

AuthManagerService

package net.work100.training.stage2.iot.cloud.web.admin.service;

import net.work100.training.stage2.iot.cloud.commons.service.BaseService;
import net.work100.training.stage2.iot.cloud.domain.AuthManager;
import net.work100.training.stage2.iot.cloud.web.admin.dto.auth.ManagerSearcher;

import java.util.List;

/**
 * <p>Title: AuthManagerService</p>
 * <p>Description: </p>
 * <p>Url: http://www.work100.net/training/monolithic-project-iot-cloud-admin.html</p>
 *
 * @author liuxiaojun
 * @date 2020-02-23 23:01
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-23   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public interface AuthManagerService extends BaseService<AuthManager, ManagerSearcher> {

    /**
     * 登录验证
     *
     * @param userName 用户名
     * @param password 密码
     * @return
     */
    AuthManager login(String userName, String password);

}

AuthManagerServiceImpl

package net.work100.training.stage2.iot.cloud.web.admin.service.impl;

import net.work100.training.stage2.iot.cloud.commons.dto.BaseResult;
import net.work100.training.stage2.iot.cloud.commons.service.impl.AbstractBaseServiceImpl;
import net.work100.training.stage2.iot.cloud.commons.utils.EncryptionUtils;
import net.work100.training.stage2.iot.cloud.domain.AuthManager;
import net.work100.training.stage2.iot.cloud.web.admin.dao.AuthManagerDao;
import net.work100.training.stage2.iot.cloud.web.admin.dto.auth.ManagerSearcher;
import net.work100.training.stage2.iot.cloud.web.admin.service.AuthManagerService;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>Title: AuthManagerServiceImpl</p>
 * <p>Description: </p>
 * <p>Url: http://www.work100.net/training/monolithic-project-iot-cloud-admin.html</p>
 *
 * @author liuxiaojun
 * @date 2020-02-23 23:06
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-23   liuxiaojun     初始创建
 * -----------------------------------------------
 */
@Service
public class AuthManagerServiceImpl extends AbstractBaseServiceImpl<AuthManager, ManagerSearcher, AuthManagerDao> implements AuthManagerService {

    @Autowired
    private AuthManagerDao authManagerDao;

    @Override
    public BaseResult insert(AuthManager authManager) {
        if (authManagerDao.getByUserName(authManager.getUserName()) != null) {
            return BaseResult.fail("用户名已经存在");
        }
        try {
            // 生成 userKey
            authManager.setUserKey(generateUserKey(authManager.getUserName()));

            // 密码加密
            authManager.setPassword(EncryptionUtils.encryptPassword(EncryptionUtils.EncryptionType.MD5, authManager.getPassword()));
            authManager.setCreated(new Date());
            authManager.setUpdated(new Date());

            authManagerDao.insert(authManager);
            return BaseResult.success("新增账户成功");
        } catch (Exception ex) {
            return BaseResult.fail("未知错误");
        }
    }

    @Override
    public BaseResult update(AuthManager authManager) {
        if (authManagerDao.getByKey(authManager.getUserKey()) == null) {
            return BaseResult.fail("用户不存在");
        }
        try {
            authManager.setUpdated(new Date());

            authManagerDao.update(authManager);
            return BaseResult.success("账户更新成功");
        } catch (Exception ex) {
            return BaseResult.fail("未知错误");
        }
    }

    @Override
    public AuthManager login(String userName, String password) {
        AuthManager authManager = authManagerDao.getByUserName(userName);
        if (authManager != null && authManager.getStatus() == 1) {
            // 验证密码,如果验证通过,则返回用户信息
            if (EncryptionUtils.validateEncryptPassword(password, authManager.getPassword())) {
                return authManager;
            }
        }
        return null;
    }

    /**
     * 生成 userKey
     *
     * @param userName 用户名
     * @return
     */
    private String generateUserKey(String userName) {
        String strDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        String sourceUserKey = String.format("%s%s", userName.toLowerCase(), strDate);
        return EncryptionUtils.encryptText(EncryptionUtils.EncryptionType.MD5, sourceUserKey);
    }

}

7.重构ManagerController控制器

修改 ManagerController 控制器中的 分页搜索 方法,代码如下:

@ResponseBody
@RequestMapping(value = "page-search", method = RequestMethod.POST)
public PageInfo<AuthManager> page(HttpServletRequest request) {
    String strDraw = request.getParameter("draw");
    String strStart = request.getParameter("start");
    String strLength = request.getParameter("length");
    String strAdvanced = request.getParameter("advanced");
    String keyword = request.getParameter("keyword");
    String userName = request.getParameter("userName");
    String roles = request.getParameter("roles");
    String strStatus = request.getParameter("status");

    int draw = StringUtils.isBlank(strDraw) ? 0 : Integer.parseInt(strDraw);
    int start = StringUtils.isBlank(strStart) ? 0 : Integer.parseInt(strStart);
    int length = StringUtils.isBlank(strLength) ? 0 : Integer.parseInt(strLength);
    boolean advanced = StringUtils.isBlank(strAdvanced) ? false : Boolean.parseBoolean(strAdvanced);
    int status = StringUtils.isBlank(strStatus) ? -1 : Integer.parseInt(strStatus);

    ManagerSearcher managerSearcher = new ManagerSearcher();
    if (!advanced) {
        managerSearcher.setAdvanced(advanced);
        managerSearcher.setKeyword(keyword);

    } else {
        managerSearcher.setAdvanced(advanced);
        managerSearcher.setUserName(userName);
        managerSearcher.setRoles(roles);
        managerSearcher.setStatus(status);
    }

    managerSearcher.setStart(start);
    managerSearcher.setLength(length);

    return authManagerService.pageSearch(draw, managerSearcher);
}

与此同时,将不再使用的代码删除

8.实例源码

实例源码已经托管到如下地址:


上一篇:重构Service实现


如果对课程内容感兴趣,可以扫码关注我们的 公众号QQ群,及时关注我们的课程更新

posted @ 2020-04-01 15:42  光束云  阅读(192)  评论(0编辑  收藏  举报