(二)springboot+shiro+iview实现用户登录以及基本的增删改查

  • 前言
    • 后台管理页面
      • index.html
      • myHotel.html
      • controller层
      • 数据库表
      • entity层
      • mapper层
      • mapper的映射文件
      • service层
        • 接口
        • 实现
    • 写在最后

前言

上一篇文章我们已经把基本的框架搭好,这一篇文章重点来说说业务代码的实现,大家一起进步!

后台管理页面

index.html

在非template模式下,需要使用vue.js的原生写法如下图所示,具体参考vue.js官网vue.js.

这里需要说明一点的是,因为一开始没经验所以没乱清iview1.x和2.x以上的版本,这里的布局Menu使用的是1.x里的布局,其余的页面使用的组件均为2.x以上的组件,css和js的引用文件也是2.x以上的但是这不影响最后的效果好像也没有出现什么不兼容的报错(我也不知道原理),iview1.x中的布局样式图如下

主体的内容是直接嵌套了一个标签,在iframe中进行页面的跳转

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登录页面</title><!-- 引入样式 --><link rel="stylesheet" href="//unpkg.com/iview/dist/styles/iview.css"><!-- 引入Vue --><script src="//v1.vuejs.org/js/vue.min.js"></script><!-- 引入组件库 --><script src="//unpkg.com/iview@1.0.1/dist/iview.min.js"></script>
</head>
<body>
<div id="app"><div><div class="layout"><Row type="flex" style="height: 1000px"><i-col span="5" class="layout-menu-left"><Menu active-key="1-2" theme="dark" width="auto" :open-keys="['1']"><div class="layout-logo-left">xx酒店管理后台系统</div><Submenu key="1"><div slot="title"><Icon type="ios-navigate"></Icon>酒店管理</div><Menu-item key="1-1">我的酒店</Menu-item></Submenu><Submenu key="2"><div slot="title"><Icon type="ios-keypad"></Icon>仪表盘</div><Menu-item key="2-1" >工作台</Menu-item></Submenu><Submenu key="3"><div slot="title"><Icon type="ios-analytics"></Icon>个人设置</div><Menu-item key="3-1">昵称设置</Menu-item></Submenu><Submenu key="4"><div slot="title"><Icon type="ios-analytics"></Icon>订单管理</div><Menu-item key="4-1">订单设置</Menu-item></Submenu><Submenu key="5"><div slot="title"><Icon type="ios-analytics"></Icon>账户管理</div><Menu-item key="5-1">账号信息</Menu-item></Submenu></Menu></i-col><i-col span="19"><div class="layout-header">欢迎来到xx酒店管理中心</div><div class="layout-breadcrumb"><Breadcrumb><Breadcrumb-item href="#">首页</Breadcrumb-item><Breadcrumb-item href="#">应用中心</Breadcrumb-item></Breadcrumb></div><div class="layout-content">               <iframe src="/hotel" style="height: 1000px;width: 100%" frameborder="0"></iframe></div><div class="layout-copy">2020 &copy; xxxxx科技有限公司</div></i-col></Row></div></div>
</div><script>
new Vue({el: '#app',
})
</script>
</body>
<style scoped>.layout{border: 1px solid #d7dde4;background: #f5f7f9;position: relative;}.layout-breadcrumb{padding: 10px 15px 0;}.layout-content{min-height: 1000px;margin: 15px;overflow: hidden;background: #fff;border-radius: 4px;}.layout-content-main{padding: 10px;}.layout-copy{text-align: center;padding: 10px 0 20px;color: #9ea7b4;}.layout-menu-left{background: #464c5b;width: 16%;}.layout-header{height: 60px;padding: 20px;font-size: 20px;background: #fff;box-shadow: 0 1px 1px rgba(0,0,0,.1);}.layout-logo-left{width: auto;height: 50px;background: cornflowerblue;border-radius: 3px;margin: 15px auto;display:flex;/*垂直居中*/align-items: center;/*水平居中*/justify-content: center;font-size: 20px;}
</style>
</html>

效果图如下所示:

截止目前我们已经完成了后台页面的基本搭建,接下来就是我们的重点myHotel.html

myHotel.html

直接上代码了,关于代码的解释我大部分都写了注释,这部分的代码揉在一起看起来比较臃肿,奈何新手只能是先让自己看明白了,优化的事后面再来吧

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>我的酒店</title><!-- 引入样式 --><link rel="stylesheet" href="/plugins/iview/styles/iview.css"><!-- 引入Vue --><script src="/plugins/vue/vue.js"></script><!-- 引入组件库 --><script src="/plugins/iview/iview.js"></script><script src="/plugins/vue/axios.js"></script>
</head>
<body>
<div id="app"><div><i-input v-model="queryFrom.hotelname" placeholder="请输入内容" style="width: 200px;margin:20px"></i-input><i-button style="margin:6px" type="primary" @click="queryTable">查询</i-button></div><div style="margin: 15px"><col span="12"><i-button style="margin:6px" type="primary" @click="openModal1">新增</i-button><i-button style="margin:6px" type="primary" @click="editor">修改</i-button><Modal:mask-closable="false"v-model="myModal":title="modalTitle"@on-ok="saveFrom"@on-cancel="cancelFrom"><i-form :model="formItem" :label-width="80" ref="formFilter" ><form-item label="酒店名称" prop="hotelname"><i-input v-model="formItem.hotelname" placeholder="请输入内容" style="width: 400px"></i-input></form-item><form-item label="主题" prop="theme"><i-input v-model="formItem.theme" placeholder="请输入内容" style="width: 400px"></i-input></form-item><form-item label="星级"  prop="star"><i-select  v-model="formItem.star" clearable style="width: 400px" ><i-Option v-for="item in starList" :value="item.value" :key="item.value">{{ item.label }}</i-Option></i-select></form-item><form-item label="城市" prop="city"><i-select  v-model="formItem.city" clearable style="width: 400px" size="large"><i-Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-Option></i-select></form-item><form-item label="地址" prop="address"><i-input  v-model="formItem.address" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入地址"></i-input></form-item></i-form></Modal><i-button type="error" style="margin:6px"  @click="remove">删除</i-button></col></div><div><i-table ref="selection"  border :columns="columns1" :data="data1"></i-table><!--<i-Button @click="handleSelectAll(true)" style="margin: 15px">全选</i-Button>--><!--<i-Button @click="handleSelectAll(false)" style="margin: 15,3px">取消全选</i-Button>--></div>
</div><script>
new Vue({el: '#app',data: {//表格标题columns1:[{type: 'selection',width: 50,align: 'center'},{title: '酒店名称',key: 'hotelname'},{title: '主题',key: 'theme'},{title: '星级',key: 'star'},{title: '城市',key: 'city'},{title: '地址',key: 'address'},],//行数据data1:[{hotelname: '',theme: '',star:'',address: '',city:'',},],myModal: false,method:'',modalTitle:'新增',formItem: {hotelname: '',theme:'',star:'',city:'',address:'',id:'',deleteFlag:'0'},cityList: [{value: '北京',label: '北京'},{value: '上海 ',label: '上海'},{value: '广州',label: '广州'},{value: '深圳',label: '深圳'},{value: '杭州',label: '杭州'},{value: '昆明',label: '昆明'}],starList:[{value:'一星',label:'一星'},{value:'二星',label:'二星'},{value:'三星',label:'三星'},{value:'四星',label:'四星'},{value:'五星',label:'五星'}],queryFrom: {hotelname:""}},//页面初始化加载数据created:function () {this.getTableData();},methods:{//查询方法queryTable:function(){this.getTableData();},//table获取数据库数据getTableData:function () {var that=this;axios.post('/list',this.queryFrom).then(function (response) {that.data1=response.data;}).catch(function (error) {console.log(error);});}  ,openModal1: function () {this.myModal = true;this.method = 'addSave';this.modalTitle = '新增页'this.handleReset();},//    修改方法editor : function () {//拿到当前选中的数据var row1 = this.$refs.selection.getSelection()//判断选中的不是一条的数据的情况弹出提示框if(row1.length!=1){this.$Notice.info({title: '提示',desc: '只能选一条数据'});return ;}//弹出myModal框,即调用了myModal中的方法(确定和取消按钮)this.myModal = true;//设置提交数据的方法this.method = 'updateSave';//设置弹出框的表头this.modalTitle = '修改页'//将选中的当前行数据绑定到formItem中,即弹出框中this.formItem = row1[0];},//新增按钮的提交saveFrom:function () {var that=this;//公共的提交url拼接var url = "/"+that.method;axios.post(url,this.formItem).then(function (response) {console.log('返回结果', response)if(response.data == '保存成功') {that.getTableData();} else {that.$Message.error(response);}}).catch(function (error) {console.log(error);});},cancelFrom :function () {return true;},//form数据初始化(点击新增时将form数据全部清空)handleReset :function() {this.$refs["formFilter"].resetFields();},//全选部方法handleSelectAll  :function (status) {this.$refs.selection.selectAll(status);},//删除方法remove :function () {var that=this;//使用this.$refs.selection.getSelection()来获取行数据,row接收的是一个对象类似于row[{},{},{]]var row = this.$refs.selection.getSelection()// console.log(JSON.stringify(row))//判断选取的是否是一条数据,如果选取的是多条数据则返回‘kkkkkk’,选取的是一条数据才会进入axios方法if(row.length!=1){// console.log("shhhhhjhjh")return "kkkkkkkk"}// console.log(JSON.stringify(row[0]))//row[0]代表的是选取的是row对象中的下标为0的数组 ,类似于row[{0},{1},{2}]选取的是{0}这个数组中的数据axios.post('/remove',row[0]).then(function (response) {//用于刷新table列表that.getTableData();}).catch(function (error) {console.log(error);});}}
})
</script>
</body>
</html>

myHotel.html中对应方法的后端代码我也一并贴出来了

controller层

结合着前一篇的controller看,这里就贴对应方法的代码

@ResponseBody@RequestMapping("/addSave")public String addSave(@RequestBody Hotel entity) {
/*
* 验证:
* 判断实体类是否为空,为空的话直接返回错误
* 实体的id必须为空,才能说明是一个新的实体
* 校验必填字段,校验失败返回错误
* */
//    提交到数据库if(entity == null) {return "对象不能为空";}if(!StringUtils.isEmpty(entity.getId())) {return "新增对象id必须为空";}
//
//    处理空字符串if (entity.getHotelname() == null || StringUtils.isEmpty(entity.getHotelname().trim())){return "酒店名称不能为空";} else {entity.setHotelname(entity.getHotelname().trim());}try {
//      entity.setHotelname(null);iHotelService.save(entity);} catch (Exception e) {e.printStackTrace();return "新增失败,数据库错误";}return "保存成功";}//  修改方法@ResponseBody@RequestMapping("/updateSave")public String updateSave(@RequestBody Hotel entity) {if (StringUtils.isEmpty(entity.getId()) ) {return "保存失败";}
//    提交到数据库iHotelService.saveOrUpdate(entity);return "保存成功";}@ResponseBody@RequestMapping("/remove")
/*
* 当前方法的删除原理:在数据库中有一个字段为delete_flag,int型,0代表正常数据,1代表已经删除的数据;
* */public String remove(@RequestBody Hotel entity) {UpdateWrapper<Hotel> tiaojian = new UpdateWrapper<>();
//    删除条件相当于sql语句中的(update hotel set delete_flag = 1 where id = ‘前端传回来的id值’),意思
//    就是把数据库中id的delete_flag标识改为1,即被标识为已经删除的数据,前端不展示但是数据库中依然存在tiaojian.set("delete_flag",1);
//    查询条件,找到id,前端传回来的id值tiaojian.eq("id",entity.getId());iHotelService.update(tiaojian);return "保存成功";}//  数据展示在前端table页面@ResponseBody@RequestMapping("/list")public List<Hotel> list(@RequestBody Hotel entity) {
//    条件构造器QueryWrapper<Hotel> tiaojian = new QueryWrapper<>();if (!StringUtils.isEmpty(entity.getHotelname()) ) {
//      根据酒店名来模糊查询tiaojian.like("hotelname",entity.getHotelname());}
//    设置查询条件,只有delete_flag为0的才会在前端页面上展示,为1的不展示即被认为是已经删除的数据tiaojian.eq("delete_flag",0);
//    只展示经过条件构造器处理的list数据List<Hotel> list = iHotelService.list(tiaojian);return list;}

数据库表

数据库中新建两张表,hotel、user表,字段如下图所示:
hotel表:

user:

entity层

新建两个类User和Hotel
Hotel:

package com.wande.wande_yxy_test02.entity;import lombok.Data;@Data
public class Hotel {private String id;private String hotelname;private String address;private String city;private String star;private String theme;private Integer deleteFlag;
}

User:

package com.wande.wande_yxy_test02.entity;import java.io.Serializable;/***  user*/
public class User implements Serializable {private static final long serialVersionUID = 1L;/*** id*/private Integer id;/*** username*/private String username;/*** password*/private String password;public User() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

mapper层

新建两个接口文件,HotelMapper、UserMapper
HotelMapper:

package com.wande.wande_yxy_test02.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wande.wande_yxy_test02.entity.Hotel;public interface HotelMapper extends BaseMapper<Hotel> {
}

UserMapper:

package com.wande.wande_yxy_test02.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wande.wande_yxy_test02.entity.User;
import org.springframework.stereotype.Repository;/***  user*/
@Repository
public interface UserMapper extends BaseMapper<User> {}

mapper的映射文件

注意:映射文件的命名需要和mapper中的接口名保持一致
新建两个映射文件HotelMapper.xml、UserMapper.xml,namespace的名称要和完整的项目名称一致不然会报错
HotelMapper.xml:

<?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.wande.wande_yxy_test02.mapper.HotelMapper">
</mapper>

UserMapper.xml:

<?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.wande.wande_yxy_test02.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.wande.wande_yxy_test02.entity.User" ><result column="id" property="id" /><result column="username" property="username" /><result column="password" property="password" /></resultMap><sql id="Base_Column_List">id,username,password</sql></mapper>

新增完映射文件后需要去Application文件中添加包扫描的路径,使用@MapperScan注解

package com.wande.wande_yxy_test02;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.wande.wande_yxy_test02.mapper")
public class WandeYxyTest02Application {public static void main(String[] args) {SpringApplication.run(WandeYxyTest02Application.class, args);}}

service层

接口

新建两个类IHotelService和IUserService,注意在接口名前面一般加上大写的I代表接口(这个是命名规范)
IHotelService:

package com.wande.wande_yxy_test02.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.wande.wande_yxy_test02.entity.Hotel;public interface IHotelService extends IService<Hotel> {
}

IUserService:

package com.wande.wande_yxy_test02.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.wande.wande_yxy_test02.entity.User;public interface IUserService  extends IService<User> {User findUserByName(String username);}

实现

在service下面的impl文件夹中新建两个类HotelServiceImpl和UserServiceImpl(实现类需要在加后缀Impl)
HotelServiceImpl:

package com.wande.wande_yxy_test02.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wande.wande_yxy_test02.entity.Hotel;
import com.wande.wande_yxy_test02.mapper.HotelMapper;
import com.wande.wande_yxy_test02.service.IHotelService;
import org.springframework.stereotype.Service;@Service
public class HotelServiceImpl extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
}

UserServiceImpl:

package com.wande.wande_yxy_test02.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wande.wande_yxy_test02.entity.User;
import com.wande.wande_yxy_test02.mapper.UserMapper;
import com.wande.wande_yxy_test02.service.IUserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper , User> implements IUserService {@Overridepublic User findUserByName(String username) {QueryWrapper<User> qw = new QueryWrapper<User>();qw.eq("username",username);return baseMapper.selectOne(qw);}}

最后我们只需要在数据库的user表中写好用户名和密码就可以启动项目实现功能,效果图如下:

前一篇文章链接前一篇

写在最后

这个项目还存在很多的问题,但是对于一个新手来说能跑起来真的很不容易了,希望能帮到和我一样艰难起步的新手,原创不易请勿抄袭。

springboot++thymeleaf+shiro+iview实现用户登录以及基本的增删改查(二)相关推荐

  1. salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)...

    此篇请参看:https://resources.docs.salesforce.com/202/latest/en-us/sfdc/pdf/salesforce_developer_environme ...

  2. 使用Maven开发用户模块的CRUD(增删改查)

    使用Maven开发用户模块的CRUD(增删改查) < 使用Maven开发Web应用Archiva服务器的搭建步骤 > C语言中文网推出辅导班啦,包括「C语言辅导班.C++辅导班.算法/数据 ...

  3. 使用SpringBoot一小时快速搭建一个简单后台管理(增删改查)(超详细教程)

    最近也是临近期末了,各种的期末大作业,后台管理也是很多地方需要用到的,为了方便大家能快速上手,快速搭建一个简单的后台管理,我花了两天时间整理了一下 我会从0开始介绍,从数据库的设计到前端页面的引入最后 ...

  4. Vue+Mock.js模拟登录和表格的增删改查

    有三类人不适合此篇文章: "喜欢站在道德制高点的圣母婊" -- 适合去教堂 "无理取闹的键盘侠" -- 国际新闻版块欢迎你去 "有一定基础但又喜欢逼逼 ...

  5. SpringBoot实战系列1:Spring Boot+Mybatis+MySql实现增删改查

    前言 Spring boot项目目前是Java Web开发领域最受市场欢迎的Spring框架之一,也是构建分布式项目.微服务项目重要基础之一,Spring Boot免去了配置繁杂的依赖和配置,使得开发 ...

  6. springboot集合MySQL删除_SpringBoot集成Spring JdbcTemplate并完成增删改查操作

    JdbcTemplate是Spring用来简化JDBC操作的核心类,有助于与Spring集成,并且避免了过多冗长的JDBC代码.不过在实际使用中,我们通常使用NamedParameterJdbcTem ...

  7. jsp登录注册代码(增删改查+网页+数据库)

    目录 一·登录注册代码以及效果 doregister.jsp:注册信息弹框 login.jsp:登录 dologin.jsp:与数据库相连.存放登陆的用户 index.jsp:主界面 update.j ...

  8. MVC使用EF实现后台登录首页以及列表增删改查

    数据库设计 CREATE DATABASE [InfoManagerSystem] GO USE [InfoManagerSystem] GO /****** Object: Table [dbo]. ...

  9. jsp mysql简单登录_简单的登录页面,实现增删改查运用jsp/servlet和mysql数据库免费分享...

    属性            大小     日期    时间   名称 ----------- ---------  ---------- -----  ---- 文件        455  2012 ...

最新文章

  1. 三星s6 android 5.1.1,谷歌亲儿子们痛哭:三星S6都升级安卓5.1.1了!
  2. 二叉查找树的C语言实现(二)
  3. oracle gather trace,Oracle 11g新SQL Trace 10046方法
  4. CSS图片水平垂直居中
  5. InstallShield For .Net制作.Net项目安装包之完整代码
  6. 科幻照进现实!2020年这个最新编程技术,将完全颠覆软件开发习惯
  7. Spring事务嵌套
  8. Ubuntu 14.04 安装 JDK 8,ubuntu14.04
  9. 手眼标定(eye in hand)-步骤
  10. 机器学习文本特征提取
  11. 微分中值定理——(罗尔定理、拉格朗日定理、导数极限定理、达布定理、柯西定理)
  12. 视频教程 | 与程序员进行高效沟通,三分钟带你掌握Zeplin
  13. WPS office根目录在哪?_wps和office的区别是什么
  14. 把QQ聊天记录插入数据库中
  15. 轮播图、焦点图代码案例
  16. 微信定向流量_我和我的小伙伴都玩微信定向流量了
  17. oracle中表数据更新提交后自动被还原的原因查找
  18. Hexo博客开发之——Github绑定Netlify改动代码后自动部署
  19. 【演示文稿制作软件】Focusky教程 | 正文页的排版小技巧 - 留白与距离
  20. Android N BlockedNumberContract原生黑名单(一)

热门文章

  1. Zabbix报警 More than 100 items having missing data for more than 10 minutes
  2. 你的心情最想向谁诉说,你的日志为谁而写
  3. 贝叶斯公式和机器人的恩怨情仇
  4. SDUTOJ 团战可以输,提莫必须死
  5. HTML5期末大作业:汽车主题网页设计——21 汽车租赁(47页) HTML+CSS+JavaScript web前端期末大作业 html+css+javascript网页设计实例 企业网站制作
  6. React路由 简单实现一个导航
  7. outline使用方法,outline与border的区别
  8. 阿里如何实现海量数据实时分析技术-AnalyticDB
  9. 微服务架构具体实现工具框架:Spring Boot概览与核心原理
  10. 在虚拟机中安装Linux系统 (附上每一步操作截图及说明)【一看就懂】