后台管理系统中的CRUD【以用户维护为例】

1、前端页面展示

后台管理主要具有三大功能,分别为权限管理、业务审核和业务管理,其中权限管理又分为用户维护、角色维护和菜单维护,这三个维护功能在后端实现上来说,大同小异,都是CRUD,因此这边以用户维护为例进行介绍。下图是用户维护页面,页面所具备功能已在图中标注:
在这里插入图片描述

2、后端代码逻辑

后端代码遵循MVC模式,分别为handler,service,mapper三层,handler层负责业务逻辑,mapper层负责与数据库交互,service层连接这两层,提供接口供handler层调用。

i、数据库结构

create table t_admin(
	id int not null auto_increment, # 主键
	login_acct varchar(255) not null, # 登录账号
	user_pswd varchar(255) not null, # 登录密码
	user_name varchar(255) not null, # 昵称
	email varchar(255) not null, # 邮件地址
	create_time char(19), # 创建时间
	primary key (id)
);

ii、用户检索

a、handler层

handler 层调用了 service 层的 getAdminPage 接口来获取查询到的用户,接着将其存入 modelMap 的属性中带入 admin-page 页面进行展示,其中 PageInfo 是 MyBatis 的一个分页插件。

@RequestMapping("/get/page.html")
public String getAdminPage(
        @RequestParam(value = "keyword", defaultValue = "") String keyword,
        @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
        @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
        ModelMap modelMap){
    PageInfo<Admin> pageInfo = adminService.getAdminPage(keyword,pageNum,pageSize);
    modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);
    return "admin-page";
}

b、service层

其对应的 service 层接口通过 mapper 层提供的 selectAdminListByKeyword 接口获取数据,其中 PageHelper 为分页插件。

@Override
public PageInfo<Admin> getAdminPage(String keyword, Integer pageNum, Integer pageSize) {
    if(pageNum > 0 && pageSize > 0) {
        PageHelper.startPage(pageNum, pageSize);
    }
    List<Admin> list = adminMapper.selectAdminListByKeyword(keyword);
    return new PageInfo<>(list);
}

c、mapper层

mapper 层用来编写 SQL 语句,下述 SQL 语句通过三个由 or 连接的模糊查询对 t_admin 表进行查询

<select id="selectAdminListByKeyword" resultMap="BaseResultMap">
	select
	<include refid="Base_Column_List"/>
	from
	t_admin
	where
	login_acct like CONCAT("%",#{keyword, jdbcType=VARCHAR}, "%")
	or user_name like CONCAT("%",#{keyword, jdbcType=VARCHAR}, "%")
	or email like CONCAT("%",#{keyword, jdbcType=VARCHAR}, "%")
</select>

iii、用户新增

看 t_admin 表的结构可以发现,该表的 id 是自增的,而 create_time 是后端赋值,因此用户新增只需要前端上传剩下的四个参数即可。

a、handler层

handler 层的 save 方法通过与 t_admin 表对应的实体类 Admin 对象来接受参数,首先判断四个参数是否为空,接着生成参数 create_time 的值,并对上传的参数 user_pswd 进行加密,此处加密方法为 Spring Security 自带的加密方法,如果没有可以使用其他加密方法如 MD5 进行替代。Admin对象的参数都设置完毕后,就通过 service 层的 saveAdmin 方法新增用户。

@RequestMapping("/do/add.html")
public String save(Admin admin){
    if("".equals(admin.getLoginAcct())
            ||"".equals(admin.getUserPswd())
            ||"".equals(admin.getUserName())
            ||"".equals(admin.getEmail())){
        throw new AdminAddFailedException(CrowdConstant.MESSAGE_FORM_NOT_FULL);
    }
    Date date = new Date();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String createTime = simpleDateFormat.format(date);
    admin.setCreateTime(createTime);
    //String userPswd = CrowdUtil.encryptMd5(admin.getUserPswd());
    String userPswd = bCryptPasswordEncoder.encode(admin.getUserPswd());
    admin.setUserPswd(userPswd);
    logger.info(admin.toString());
    try{
        adminService.saveAdmin(admin);
    } catch (Exception e){
        e.printStackTrace();
        if(e instanceof DuplicateKeyException){
            throw new AdminAddFailedException(CrowdConstant.MESSAGE_LOGINACCT_DUPLICATE);
        }
        throw e;
    }
    return "redirect:/admin/get/page.html?pageNum=" + Integer.MAX_VALUE;
}

b、service层

此处 service 层直接调用了 mapper 层的 insert 方法进行数据插入。

@Override
public void saveAdmin(Admin admin) {
    adminMapper.insert(admin);
}

c、mapper层

数据插入操作在 mapper 层的 SQL 代码也很是循规蹈矩。

<insert id="insert" parameterType="com.alageek.crowd.entity.Admin">
  insert into t_admin (id, login_acct, user_pswd,
    user_name, email, create_time
    )
  values (#{id,jdbcType=INTEGER}, #{loginAcct,jdbcType=VARCHAR}, #{userPswd,jdbcType=CHAR},
    #{userName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{createTime,jdbcType=CHAR}
    )
</insert>

iv、用户修改

a、handler层

用户修改与用户新增很是相似, edit 方法接受参数也是用了一个Admin对象,不过比起用户新增多接收了两个参数, pageNum 为分页页码, keyword 为用户检索的关键字,这俩参数的作用是为了执行用户修改后返回到原页面原位置。

@RequestMapping("/do/edit.html")
public String edit(Admin admin, Integer pageNum, String keyword){
    if("".equals(admin.getLoginAcct())
            ||"".equals(admin.getUserName())
            ||"".equals(admin.getEmail())){
        throw new AdminEditFailedException(CrowdConstant.MESSAGE_FORM_NOT_FULL);
    }
    logger.info(admin.toString());
    try{
        adminService.update(admin);
    } catch (Exception e){
        e.printStackTrace();
        throw new AdminEditFailedException(CrowdConstant.MESSAGE_UPDATE_ERROR);
    }
    return "redirect:/admin/get/page.html?pageNum=" + pageNum + "&keyword=" + keyword;
}

b、service层

此处 service 层直接调用了 mapper 层的 update 方法进行数据更新。

@Override
public void update(Admin admin) {
    adminMapper.updateByPrimaryKeySelective(admin);
}

c、mapper层

mapper 层选用 updateByPrimaryKeySelective 方法,是为了方便只更新一个参数的时候能够执行成功,不过显然 handler 层的对参数的非空判断,使得这个考虑并没有什么必要。

<update id="updateByPrimaryKeySelective" parameterType="com.alageek.crowd.entity.Admin">
  update t_admin
  <set>
    <if test="loginAcct != null">
      login_acct = #{loginAcct,jdbcType=VARCHAR},
    </if>
    <if test="userPswd != null">
      user_pswd = #{userPswd,jdbcType=CHAR},
    </if>
    <if test="userName != null">
      user_name = #{userName,jdbcType=VARCHAR},
    </if>
    <if test="email != null">
      email = #{email,jdbcType=VARCHAR},
    </if>
    <if test="createTime != null">
      create_time = #{createTime,jdbcType=CHAR},
    </if>
  </set>
  where id = #{id,jdbcType=INTEGER}
</update>

v、用户删除

a、handler层

删除操作不需要除了 adminId 以外的其他参数,因为主键是唯一的, pageNum 与 keyword 是为了删除用户后可以回到原页面原位置。

@RequestMapping("/remove/{adminId}.html")
public String remove(
        @PathVariable("adminId") Integer adminId,
        @RequestParam("pageNum") Integer pageNum,
        @RequestParam("keyword") String keyword){
    adminService.remove(adminId);
    return "redirect:/admin/get/page.html?pageNum=" + pageNum + "&keyword=" + keyword;
}

b、service层

此处 service 层直接调用了 mapper 层的 remove 方法进行数据删除。

@Override
public void remove(Integer adminId) {
    adminMapper.deleteByPrimaryKey(adminId);
}

c、mapper层

数据删除操作在 mapper 层的 SQL 代码也很是循规蹈矩。

<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
  delete from t_admin
  where id = #{id,jdbcType=INTEGER}
</delete>

3、注意事项

CRUD 很简单,没啥好注意,唯一要注意的就是程序员职业生涯中,万万不可一直做 CRUD 工作,要尝试着接触新技术,将其融入工作中,只有这样,才能步步高升!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值