自搭建ssm crud的项目技术总结

ssm crud项目spring +springmvc+mybatis +maven
项目源码提取地址
链接: https://pan.baidu.com/s/1bkBet6AwDcUObD9bGcPsQA 提取码: 9a8h

Eclispe快捷键查询网址:http://my.oschina.net/u/590763/blog/70166

CRM(客户关系映射)
CRUD:
C:creare 增 r: retrieve 查 u:update 改 d: delete删

项目功能:

  1. 分页
  2. 数据校验
    前端校验:jquery
    后端校验:jsr303
  3. Ajax
  4. Rest风格的URI:
    使用http协议的请求方式的动词来表达对资源的操作
    即:使用 get(查询)post(新增) put(修改) delete(删除)请求资源的方式来实现增删改查
    项目技术点:
  5. ssm框架
  6. 数据库:mysql
  7. 页面:使用bootstrap开发
  8. Maven作为项目的jar管理
  9. 使用mybatis的工具pagehelp实现分页
  10. 使用mybatis genatator 生成逆向工程

项目搭建步骤:
一、 创建maven工程
二、 在pom.xml中引入jar包
在mvnrepository官网下寻找要使用的jar包的坐标

  1. spring webmvc
  2. spring jdbc
  3. spring面向切面编程 :spring aspect ----找到spring aop
    1.2.3.是对应的spring的包(3个jar包要版本一致吗?)
    4. mybatis
    5. spring 和 mybatis的结合包
    Mybatis spring
    4.5. 对应的是mybatis的包
  4. 数据库连接池 c3p0
  5. mysql 驱动 mysql
  6. 其他jar包
    Jstl
    Servlet api
    注:引入servlet api对应的jar 包时,因为在servlet在服务器端已经存在,但若不引入则会报错
    可以使用provied标签来加载
    指定使用自引入的servlet api的jar包,当加载到服务器时,会自动移除服务器的servlet api

Junt

三、 引入bootstrap前端框架
下载bootstrap中文文档
将解压后的帮助文档放在webapp下的一个新建的static文件夹中
在jsp页面中使用路径引用的方式引入js,和css
使用:参考官方文档中的 全局样式,找到对应的class的值
标签中class的命名与官方文档的class命名相同即可
四、 写配置文件

  1. 配置web.xml
    -1- 启动spring容器,配置中央控制器
    -2- 字符编码过滤器
    -3- Restful请求,配置hiddenHttpMethodFilter过滤器可以将POST请求 转化为DELETE,PUT请求

  2. Spring的配置
    在.properties上配置四大天王,引入外部的配置文件,使用el表达式来获取值
    Spring-db.xml

<context:property-placeholderlocation="classpath:jdbc.properties" />

配置.Properties文件

引入外部的properties文件,使用el表达式获取值

使用将.xml与
.java文件分开

使用mybatis generator的逆向生成:
步骤:

  1. 导入逆向生成的jar包
    mybatis-generator-core-1.3.2
  2. 生成代码配置文件
    配置文件的模板代码,在mybatis generator 的github工程上有
    Xml configuration reference
    Generatorconfig.xml
    配置自动生成的Java位置,映射文件位置,dao位置,配置数据库对应的table
    注:在官网上copy逆向生成文件时,一定要将改行代码删除,否则,无法逆向生成
  3. 新建一个java类,通过代码的形式来生成逆向工程
    类的模板代码,在mybatis generator 的github工程上有
    Running mybatis generator ------》with java----》Running MBG from Java with an XML Configuration File

解决mysql数据库中文乱码问题
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/restfulorm?useUnicode=true&characterEncodin吧g=UTF-8

注意:如果外键列对应的
值为空,通过该外键获取外键对应的表的信息会发生空指针异常
测试数据库完成 .
请求步骤
Index.jsp-----发送查询请求–处理器controller接收请求—返回员工数据-将员工数据带到–list.jsp页面

Index.jsp如何发送查询请求?
在index.jsp页面中加入标签
<jsp:forward page=“跳转路径”></jsp:forward>
<jsp:forward page=”/emps”></jsp:forward>
从index.jsp中发送请求到emps这个处理器

如何使用mybatis的分页组件呢?

  1. 引入pagehelper插件
  2. 在mybatis.xml中配置注册信息,配置plugin标签
    注:plugin标签一定要放在typeAlians标签的下面

如何使用spring的单元测试模拟测试请求功能?

  1. 加入@RunWith(SpringJUnit4ClassRunner.class)
  2. 加入@ContextConfiguration(locations= {“classpath:spring.xml”,“classpath:springmvc.xml”})//需要加入spring和springmvc的配置文件所在路径
  3. 加入@WebAppConfiguration
    原因:在使用注解
    @Autowired
    private WebApplicationContext context;
    获取web的ioc容器就必须声明@webAppConfiguration

使用bootstrap快速生成页面:

  1. 引入bootstrap样式:
    引入方式:
    -1- 不以/开头的相对路径:从当前的路径为基准(这样易出现问题)
    -2- 以/开始的路径绝对路径: 找资源时以服务器的路径做为标准。

http://locallhost/:3306//crud//static:以服务器为路径找资源,当加上项目名时才能正确找到路径
http://locallhost/:3306: 服务器路径
crud/static: 项目路径

使用相对路径的好处:
不同目录下的页面调用资源的路径相同,都是从服务器http://locallhost/开始寻找

相对路径是从当前的路径开始找资源,绝对路径是从根目录寻找资源

如何在jsp页面中动态的获取当前项目的路径?
Bootstrap的栅格样式:

使用mybtis的插件pagehelp做分页总结:
后台代码:

  1. 创建一个pageHelp对象,设置其实页数和每页的数据条数
    PageHelper.startPage(pn,5);//设置分页信息: pn:当前页数 5:每页大小
  2. 从数据库中获取数据
    List employees = employeeService.getEmployees();
  3. 创建pageInfo对象,在pageInfo中放入获取到的数据库查询的数据,并设置导航栏显示的页数
    PageInfo pageInfo = new PageInfo(employees,5);//由pageinfo包装查询出来的数据,pageInfo后跟的参数5:表示每次连续显示的页数大小
  4. 使用Model将pageInfo带到数据库,pageInfo中含有所有的分页信息
    如:
    model.addAttribute(“pageInfo”, pageInfo);//将pageInfo传递给页面,pageInfo封装了所有的分页信息
    当前页:getPageNum();
    总条数:getTotal();
    总页数:getPages();
    获取导航到数据:getNavigatePageNum()……等等,在前台可以直接获取该分页信息
  5. 使用@RequestParame来获取前天页数pn
    @RequestParam(defaultValue = “1”, name = “pn”) Integer pn
    defaultValue:默认给pn赋值为1
    bootstrap来快速搭建页面
    使用bootstrap的栅格系统
    bootstrap相当于一个table,该table中一行占12列,在列中还可以嵌套行:
    使用一个大的div作为,在该table中进行布局。在bootstrap的官方文档中引入class

前台代码

  1. 使用${pgeInfo.list}来获取分页数据
    注:展示时用到一个点,关于el表达式的三元运算符问题。
    员工的性别gender在数据库存储时 男:m 女:w
    取出数据时在el表达式中使用三元运算符来判断
    ${emp.genser eq “m” ? “男”:”女”}

  2. 分页导航栏的展示
    首页 前进箭头<< 页数导航 后退箭头>> 尾页
    逻辑处理:
    -1- 当前页:
    跳转页数为1,设置跳转路径 ${APP_PATH}/emps?pn=1

-2- 前进箭头:
判断是否有上一页,如果没有则不开放前进按钮
p a g e I n f o . h a s P r e v i o u s P a g e &quot; {pageInfo.hasPreviousPage} &quot; pageInfo.hasPreviousPage"{pageInfo.hasPreviousPage }"

-3- 页数导航:
<c:forEach ${pageInfo.navigatePageNum}></c:forEach>循环 p a g e I n f o . n a v i g a t e P a g e N u m 获 取 导 航 栏 的 页 数 &lt; c : f o r E a c h i t e m s = &quot; {pageInfo.navigatePageNum}获取导航栏的页数 &lt;c:forEach items=&quot; pageInfo.navigatePageNum<c:forEachitems="{pageInfo.navigatepageNums }" var=“pagenum”>

-4- 尾页:
跳转页数为 A P P P A T H / e m p s ? p n = {APP_PATH}/emps?pn= APPPATH/emps?pn={pageInfo.pages}
pageInfo.pages:获取总页数
${pageInfo.pages}"

使用<c:forEach></c:forEach>和el表达式来展示数据的弊端
弊端:不具有平台的扩展性
通过请求获取的数据储存在请求域中,请求域中request中的数据只能通过<c:forEach>和el表达式中取出,而<c:forEach>和el表达式应用于jsp中,jsp由浏览器进行解析。
但更换其他客户端 例如:安卓 和Ios时解析服务器的传送的数据就比较麻烦
因此<c:forEach>和el表达式的数据展示只适用于 服务器 - 浏览器这一交互模式

如何解决数据解析问题?
使用json字符串的形式:
使用发送请求时获取数据的逻辑思路
在index.jsp时发送emps请求—将数据放在pageInfo中,并将pageInfo这个对象传到list.jsp中------使用和el表达式来展示数据

使用ajax的形式来获取数据的逻辑思路
在展示页面中直接发送ajax请求到服务器(emps)中-----服务器(emps)以字符串的形式将pageInfo的信息返回给浏览器-----在前台浏览器通过js解析来获取数据—并通过dom来实现增删改查数据

使用ajax来获取数据,返回pageInfo的弊端:
不具有通用性。
原因:执行删除,修改,添加请求后,服务器需要将是否执行成功的结果返回给服务器
因此:需要一个通用类,来返回处理结果信息
类的属性:
Private int code: //状态码,用于判断请求是否成功
Private String msg: //提示信息
Private Map<String,object> extend : //存储从数据库查出的返回给浏览器的数据

返回到浏览器的json字符串

Json字符串dom解析树
取出json结果字符串中emps员工信息
使用dom解析
var emps = result.data.pageInfo.list;

给页码添加点击事件
点击一次发送一次ajax请求
发送多次ajax时页面数据刷新问题,上一次ajax请求页面添加了行,下一次ajax时又添加行,如何解决这一问题
使用.empty()来清空指定标签中的数据

当点击上下页时会出现这样一个问题:
虽然设置了禁用按钮,但是点击下一页的按钮仍然会发送ajax请求到服务器
按钮禁用不绑定点击事件
写一个if else判断语句,当按钮不被禁用时则启动点击事件,发送ajax请求

如何设置当前页码<0,只查第一页?当前页码超出总页数,只查最后一页?
在.xml的配置文件中注册分页插件的标签中配置
方法一:

将value设置为true,默认为false
设置value为true时,若页数<0,只查第一页,页数超过总页数,只查最后一页
方法二:
在点击事件的页数传递时可以使用三元运算符
第一页:判断当前页是否为第一页 是跳到1,否则当前页-1
最后一页:判断当前页是否为最后一个,是跳转到最后一页,不是跳转到当前页+1

回调函数success:function(result){
//里边要完成的功能
}
Success:function(result){

  1. 解析并显示员工数据
    build_emps_table(result)
  2. 解析并显示分页信息
    build_page_info(result)
  3. 解析并显示分页条信息
    build_page_nav(result)
    }

使用ajax返回json字符串到浏览器做页面展示的总结

后台代码:
返回数据:返回的是一个通用类,类中含有处理转态码是处理信息,已经从数据库中拿到的数据
通用类Message:
属性:private int code:状态码 200 成功 404 失败
Private String msg :执行的结果信息
Private HashMap<String,Object> data:String :data的键名 object:数据库查询出来的数据对象
方法:静态的 返回一个Message对象
Public static Message success(){//成功时调用
Message message = new Message();
message.setCode(200);
message.setMsg(执行成功);
}
Public static Message fail(){//失败时调用
Message message = new Message();
message.setCode(404);
message.setMsg(执行失败);
}
Public Message add(String key,Object value){//将前台封装的pageInfo对象添加到Message对象中去
This.setData().put(key,value);
}

在控制器中返回值为
1.则返回值为:return Message .success.add(“pageInfo”,pageInfo) //date为键值

2 控制器的返回值得加上@ResponseBosy,这样返回值Message才能以json字符串的形式传给浏览器

前台代码:
在页面使用ajax的形式请求服务器:
(如果不了解ajax可以参考jquery的帮助文档)
$.ajax({
url:”跳转路径”,
data:”传到后台的参数值”,
type:”请求的方式 get/post”,
success: function(result){
//回调函数,result为请求成功后后台传给浏览器的json字符串
接收的json字符串参数名可以任意命名,result的命名不是特定的。可以任意命名
}
});
例:
KaTeX parse error: Expected '}', got 'EOF' at end of input: .ajax({ url: ”{APP_PATH}/emps”,
data: “pn=1”, //参数名为pn,参数值为1
type: “get”, //提交方式为get
success: function(result){
//result为返回的json字符串
}
});
解析传给传给浏览器的json字符串:
后台传给浏览器的数据的json字符串形式如图

解析Message的json字符串
完成三个功能,,构造三个函数

  1. 展示员工的数据信息
    function build_emps_table(result){}
    根据json字符串的dom树解析来获取所要的信息
    如员工的信息都存在list中,如何逐层解析?
    1 拿到回调函数的result,根据上图的json字符串的dom树解析
    result.data.pageInfo.list -------》得到了员工的数据
    2 遍历数据
    使用jquery的.each(result.data.pageInfo.list,function(index,item){
    //遍历的到的数据
    // result.data.pageInfo.list相当于要遍历的对象
    //item对应的遍历的数据
    })

3 根据拿到的数据使用jquey构造函数页面
使用jquer构造元素注意的点
Var empIdTd = ( “ &lt; t d &gt; &lt; / t d &gt; ” ) . a p p e n d ( i t e m . e m p I d ) / / (“&lt;td&gt;&lt;/td&gt;”).append(item.empId) // (<td></td>).append(item.empId)//(“”)构造一个元素
//.append()在当前的名为empIdTd中添加值,也可以添加其它元素
empIdTd.appendTo(“#emps_table”)
//将empIdTd这个元素添加到id名为emps_table的元素中去

  1. 展示分页信息(如:当前页,共多少页,总页数)
    function build_page_info(result){}
    获取要展示数据的div的id,采用上述中的方法解析数据,的到相应的信息
  2. 展示分页条信息
    function build_page_nav(result) {}
    构造分页条
    使用bootstrap样式 通过jquery添加元素的形式构造分页条
    使用.each()函数取出json字符串中的分页条数信息
    展示分页条信息需要解决的逻辑问题
    点击时跳转,点击时调用click函数
    click(function(){
    toPage(“跳转的页数”)
    //点击时调用toPage(“跳转的页数”)
    })
    toPage(pn)的逻辑处理
    function toPage(pn){//接收要跳转的页数,做ajax请求
    KaTeX parse error: Expected '}', got 'EOF' at end of input: …jax({ url: ”{APP_PATH}/emps”,
    data: “pn=”+pn,
    type: “get”,
    success: function(result){
    //在回调函数中对返回的数据进行处理,将数据展示到页面中
    // 1.展示员工信息
    build_emps_table(result);
    // 2.展示分页信息
    build_page_info(result);
    // 3.展示分页条信息
    build_page_nav(result);
    }
    });

}

  1. 首页
    click.toPage(“条转页数”)
  2. 上一页
    判断是否有上一页,若没有则将按钮设为禁用,添加class=”disabled”
    否则添加点击事件,调用toPage()将跳转的页数传入进去
  3. 下一页
    下一页逻辑与上一页相同
  4. 尾页
    Click.toPage(“跳转的页数”)
  5. 分页条数据
    -1- 判断是否为当前页,若是高亮显示,class=”active”
    -2- 获取分页条页码数调用toPage(“页码数”)

构建分页条注意的点:
若传递要查询的页数为负数时,虽让查出的数据仍是第一页内容,但当前页pageNum展示时就变为了负数,查询页数超过总页数易然,所以,如何解决这一问题
在注册插件的xml文件的的标签下配置

将reasonable属性的值设为true
当属性为true时,若当前页数<0时只查第一页,若当前页数超过总数时只查最一页,默认为false

新增员工信息

模态框构建:
当点击新增按钮,出现新增员工的模态框
使用bootstrap构建模态框:
进入bootstrap的官网-----找到中文帮助文档----Javascript插件-模态框
1.点击点开模态框的按钮
2.

模态框的div

在中有两个属性是按钮和模态框的桥梁
data_toggle=”modal” //打开模态框
data_target=”#myModal” //打开id名为#myModal的模块框
若是在设置了这两个属性,在点击按钮时自动打开模态框
中构建表单


//到bootstrap全局css样式中找到需要的表单展示形式
Copy代码

    	 如何通过js的方式来打开模态框?
			$(“#myModal”).modal(options)

//获取当前模态框的控件,调用modal()方法,并设置options的值,options的值对应着模态框的属性

逻辑:

保存员工数据
使用rest风格处理请求
请求路径相同,请求方式不同,跳转处理的方法也不同
如请求路径
URI 请求类型
./emps/{id} get 查询
./emps post 添加
./emps/{id} put 修改
./delete/{id} delete 删除
例:当请求路径为./emps/{id},判断其请求的类型,根据路径和请求类型跳转到处理请求的方法

需要解决的问题
如何获取前台表单的数据,通过ajax带到页面并封装对象带给后端呢?
两个方法:
方法一:
通过js的形式获取表单中的控件值,进行参数的拼接(过于麻烦)
方法二:
jquery提供了Serialize()方法,取出表单中控件的值,并拼接成字符串,方便于ajax的传参

使用serializse方法将表单中的控件以name为参数名,控件中的值作为参数值拼接成参数字符串
后端根据参数名封住成对应的对象来接收ajax传来的数据(springmvc来接收表单控件值的方法:根据表单的name属性来封装对象,接收控件数据时使用封装的对象来接收)

数据保存成功的逻辑处理

  1. 数据保存成功关闭模态框
    Bootstrap的Javascript插件提供了关闭模态框的方法
    $(“#myModal”).modal(“hide”) //关闭模态框
    $(“#myModal”).modal(“show”) //启动模态框
  2. 当前页跳到最后一页,展示保存的数据
    toPage(“跳转页数”)
    如何解决跳转到最后一页页数传参问题
    解决:
    方法一:toPage()可以传入一个足够大的数
    因为在标签中已经设置了resonable的属性为true
    当跳转页数超过总页数时,只查最后一页
    方法二:设置一个全局变量totalRecord,totalRecord=总条数

前端校验:
在点击保存按钮前使用正则表达式判断输入的用户名和邮箱的格式是否正确
正则表达式如何书写?
在jquery中有正则表达式的的格式
/1{3,16} / / [ a − z A − Z 0 − 9 − ] 3 , 16 / /^[a-zA-Z0-9_-]{3,16} //[azAZ09]3,16/
A- Z:允许大写的A-2
{3,16} 3-16位
拼接正则表达式
/2{3,16}KaTeX parse error: Can't use function '\u' in math mode at position 28: …de编码中的汉字范围: /^[\̲u̲2E80-\u9FFF]+/
拼接:var name = /(3{3,16}$)|( /4{2,5})/
注:

  1. 正则表达式以/开头以/结尾,第一个表达式结尾的/去掉,第二个表达式开头的/去掉,两个正则表达式拼接以()扩起来,+$要去掉
  2. 前台规定正则表达式还不能用””引号引起来

数据的前端校验失败后弹框提示信息太过于low,使用bootstrap
全局css样式—表单----校验状态-找到对应的校验示例
显示提示信息:
将校验实例的标签放在标签下,用于显示提示信息
输入框边框变色提示:
在的父类元素上添加class属性,包含在该父类元素的.control-label、.form-control 和 .help-block 元素都将接受这些校验状态的样式。

相同用户名校验:
当用户在输入框输入用户名,鼠标一离开输入框的时候应该在服务器中判断数据库中是否有该用户名
给用户名的输入框绑定onchange事件
在onchange的事件中发送ajax请求

判断用户是否可用,清空模态框数据
因为我们发送的是ajax请求,页面不刷新,添加一个用户后模态框关闭再点击新增按钮模态框的数据仍然存在,用户可以直接点击保存按钮,因为用户没有再次填写用户名,并没有激发change事件,此时按钮的ajax_val属性的状态仍然是success状态,因此可以直接执行下边的ajax操作,这样就提交了重复的用户名

清空表单的数据
方法一:
通过form表单的dom对象的reset方法来进行清空
$(“form”)[0].reset();
$("#empAddModal form")[0].reset();//使用form中的dom对象的reset方法
方法二:
在form表单中设置一个隐藏的reset属性

$(“button[type=’reset’]”).trigger(“click”) //触发reset按钮
使用上诉的重置方法,只能重置表单的内容,如何重置表单的样式?
表单的完整重置

  1. 重置表单的数据以及样式
    2.找到表单元素
    function reset_form(){
    //1.重置表单内容
    $(“form”).[0].reset();
    //2.重置表单的样式
    找到当前表单find(“”)查询当前表单的所有元素,移除元素的has-error 和has-success class值
    $(“form”).find(“
    ”).removeClass(“has-error has-success”);
    //重置表单的提示框内容
    //find(“.help-block”)找到表单下class为help-block的元素设置文本内容为” ”
    $(“form”).find(“.help-block”).text(“ ”);
    };

后台正则表达式校验:
前端输入用户名判断用户名是否可用时,若是用户名不存在,则提示用户名可用,但是
用户的命名不规范,当点击保存按钮,进行前端校验时又会提示用户名不符合规则,因此有必要将 该提示统一起来,当后端进行用户名判断的同时,也进行表达式的判断
解法:
在后端中定义用户名的正则表达式
判断用户名是否匹配该表达式,若是不匹配则传递提示的信息

Java和jquey匹配表达式的形式不一样:
如:正则表达式变量:regx
要匹配的变量 : pipei_name
Java:使用匹配变量去调用matches()方法
pipei_name.matches(regx)
jquery:使用正则表达式调用test()方法
regx.test(pipei_name)

校验集中于前端校验
张三-----ajax请求判断用户名是否可用----不可用,提示不可用信息—
email前端校验—点击保存,样式不符合----提示邮箱格式不正确,此次用户名提示框
显示为正确状态
原因:前端校验后判端用户名是否符合正则表达式,若是符合则取出原来的样式
清空提示信息,设置新的样式has-success

浏览器端校验是通过js代码实现的用户可以通过浏览器的检查元素,修改校验的js代码,进行非法请求
要在浏览器端实现校验都是写的js代码,当用户发送请求时通过检查元素恶意的绕过js代码,修改js代码,或用户选择性的禁用某些状态,用户就可以完成非法请求

完整的数据安全性的检查机制
前端校验+后台校验+数据库的约束
员工保存方法employe 应该校验数据的正确性
新增:
Jquery前端校验
用户名重复校验 -----用户可以修改js代码,修改标识状态提交非法数据
后端校验:
Springmvc提供的基于jsr303校验
使用:
-1- 导入jsr303所需的jar包 hibernate-validata.jar
注:tomcat7及以上服务器直接导包
由于tomcat 7以下服务器el表达式不是新版本得个服务器lib包增加新的el
-2- 在employe对象上每一个要校验的字段加上规则

-3- 在controller员工保存对象员工对象传参上使用注解
@Valid: 代表封住数据时对数据进行校验
使用BindingResult:来封装校验结果
模拟没有前端校验
2018.11-2019.1 学校校医院挂号系统 主程序员(前端页面开发+后台代码)
 核心功能
自助拿药 自助挂号 个人中心 在线客服
 核心技术
Javawweb技术
使用svn整合
 主要职责
前端
完成登陆录注册的页面的设计
完成个人中心部分页面的设置
完成病例页面的设置
后台
完成登录注册的数据库查询和信息校验

后短校验:

员工添加的总结

模态框构造
构造模态框,点击编辑按钮,弹出模态框,模态框的使用可以参考bootstrap的官方文档
Bootstrap-------》javascript插件-----》模态框-------》找到动态实例-------》复制代码
注:模态框的html代码只有点击触发模态框的按钮才起作用即只有点击启动模态框的按钮才在页面展示模态框
模态框开启的两种方式

  1. 通过data属性调用
    在开启模态框的按钮中设置两个属性
    data-toggle=”modal” : 通知启动模态框
    data-target=”构造模态框
    的id” :打开对应的id的模态框
    2.通过javascript调用
    去除示例的data-toggle 和data-target属性
    $(“模态框的id”).modal(options)
    Options可以设置模态框的属性,具体的使用方法参照bootstrap官方文档
    例:
    打开模态框
    $(“模态框id”).modal({
    backgrop: ’static’ //打开模态框,且设置点击模态框空白区域不关闭
    }
    )
    关闭模态框
    $(“模态框的id”).modal(‘hide’)

展示模态框
点击编辑逻辑处理
点击编辑-----弹出模态框,模态框中部门选择下拉下表要展示所有的现部门的信息-----》在展示模态框之前要先执行getDepts()方法,查询部门的信息,通过ajax请求返回查询数据,添加到部门的下拉列表------打开模态框
点击编辑按钮-------》执行getDepts()方法-------》展示模态框
getDepts()函数功能:
发送ajax请求,查询所有部门信,返回部门信息,将部门名字添加到中
注:接收返回数据,构造添加到可以抽取出来构建一
个独立的函数bildDepts(),最后在success的function中调用
buildDepts()功能:
使用.each()遍历结果集
-1- 创建-
var optionEle = $("")
-2- 给option添加部门名
var optionEle = $("").append(this.deptName)
-3- 给option的value属性添加部门id
.attr():给属性添加值
attr(“value”,this.DeptId)//给value属性添加值this.DeptId

         var optionEle = $("<option></option>").append(
				this.deptName).attr(//attr("value",this.deptId) 给<option>元素的value属性赋值
				"value", this.deptId)
				//添加到一个已有的元素使用appendTo
				.appendTo("#empAddModal select")	

填写员工信息数据校验
用户名校验:
前端校验:
后台校验:
构造校验数据错误后页面提示显示
参考bootstrap—全局css样式----表单----校验状态----实例
-1- 输入框变色提示显示
添加class
has-error: 错误,红色框
has-success: 成功,绿色框
has-warning:警告
如何使用?
给要校验的控件的父类元素添加上对应的class
例:$(“当前添加校验的控件id”).parent().addClass(“has-success”)
.parent(): 拿到父元素
-2- 错误信息提示显示
参考bootstrap的校验转态的元素,将元素代码放在要校验的控件同级位置下
若校验不成功
使用
例: $(“校验控件的id”).next(“span”).text(“提示的错误信息”);
.next(“span”):拿到当前控件标签为span的相邻元素

前端校验
一般用户输入数据存储时,对输入的数据都规定的数据的格式,当用户输入的数据不符合规范时,应不予与添加
如:对用户名输入根据不同的要求有不同的规范,如字母个数,或中文个数
对于邮箱也有特定的正则表达式

假若在添加员工注册时,规定了用户名和邮箱的正则表达式,在添加员工数据时
需要进行前端校验通过js获取添加数据的控件的值,通过js判断输入数据格式是否正确
前端校验函数
    Validata_add_form()
    功能:
  1. 定义用户名的正则表达式,定义邮箱的正则表达式
  2. 获取用户名值/获取邮箱的的值
  3. 使用test()方法判断用户值是否符合规范,若不符合规范
    构建校验错误提示信息
    输入框变色+控件下方提示错误原因
    该功能可以独立的抽取一个函数
    show_validata_msg(ele,status,msg);
    ele:当前控件的id
    status:校验状态,用来控制控件的样式
    msg:校验的提示信息

完成员工的修改功能
逻辑处理:
打开模态框:
绑定事件先于创建按钮执行 不能使用click()使用on()
给编辑按钮绑定事件点击编辑按钮,弹出模态框
假设给编辑按钮增加class,edit_btn,点击编辑打开模态框
$(“.edit_btn”).click(function(){
$(“,模态框id”).modal({
backdrop:’static’
}
)

)
})
此时,出现了一个问题,点击编辑按钮,模态框并没有弹出来,因为编辑按钮是在发送ajax后请求构造的,$(“.edit_btn”).click(function()的事件先于创建按钮元素执行,因此未给编辑按钮绑上点击事件
解决:
为后来添加元素绑定事件

  1. live()
    该方法不能使用,因为在jquery新版本中已经将该方法去除了,使用on方法
  2. on()
    在被选元素及子元素添加一个或多个事件处理程序,适用于当前或未来元素
    使用:
    传入给定选择器的后代元素,为选择器的后代元素添加事件
    $(selector).on(event,childSelector,data,function)
    Select:选择器
    Event:绑定的事件
    ChindSelector:绑定事件的选择器的子元素
    Data:参数
    Function:绑定事件后的的调用函数

$(document).on(“click”,”.edit_btn”,function(){
alert(“haha”);
})
在整个文档中,为class为edit_btn的元素添加click事件,并弹出haha

前端展示:
模态框展示注意事项

  1. 员工的姓名应该不能被改变
    Bootstrap—全局css样式----表单----静态控件
  2. 查询所有的部门信息,展示到多选框的下拉列表
    查询当前要编辑的员工信息:
    需要解决的问题:
    员工的id如何获取
    创建元素时自定义一个属性,给属性添加值为员工的id
    如:创建的编辑按钮为editBtn,给该按钮自定义属性
    editBtn.attr(“edit_id”,empId) //自定义属性edit_id,属性值empId
    $(this).attr(“edit_id”) //取值

如何让单选框和下拉选择框被选中默认值?:
使用val()方法

val()方法一般都用于input框的取值和赋值
给单选框赋值
$(“#empEditModal input[name=gender]”).val([employee.gender]);
给下拉框赋值
$(“#empEditModal select”).val([employee.dId])

注:val()赋值的值使用 [] 中括号括起来

更改员工信息:

  1. 邮箱验证
  2. 更新时如何传入员工id
    在构建模态框的员信息时,给更新按钮自定义一个属性,属性值为员工的id
    如何使用rest风格发送put请求

上述发送的ajax请求,控制台会报错,原因是,服务器只接收post和get请求
如何将put请求转为post请求呢?

在序列化后加上”&_method=PUT”
在serialize()加上&_method=put能够将post请求转为put请求的原因是
&_method=put会走在web.xml配置的HiddenHttpMethodFilter过滤器,该过滤器会将post或get请求自动转为put或delete请求

此时,出现了一个问题,员工的id没有传进来
因为empName为p标签保持不变,所有empName=null

原因是:路径中挂的参数名称应与对象的属性相同

将请求类型改为put,如何使用rest风格发送请求
直接将请求类型设为put,控制台会报语法异常

原因:

在后台接收员工更改信息时,只接收到了员工的id,而在拼装员工更改的sql语句时,是有选择的更新,为null不更新
只有id不为null,其他为null,则拼装语句如下
Update employee where empId=108 :因为其它值都为null就没有set语句,此时,出现看sql语句错误

一个奇怪的现象:
我们发现,虽然后台只能接收对象的id值,但请求体却将所有数据带过去了,即然请求体都将数据带过去了,那为什么没有将请求体中的数据封装对象呢?
都是tomcat的错:
Tomcat的作用:

  1. 将请求体的数据封装成一个map对象
  2. 通过Request.getParameter(“参数名”)从map中获取值
  3. Springmvc通过pojo封装对象,springmvc会通过getParameter()获取pojo
    属性的值,进而封装成对象
    Tomcat默认只将post请求体中的数据封成map对象
    遗憾的是,tomcat默认识别post请求,当put发送请求时,tomcat不识别,就不会把请求体中的数据封装成map对象,springmvc就不能通过getParameter方法获取pojo值,进而封装对象。因此取出的对象的值为null

如何让tomcat封装put请求的请求体数据
Springmvc提供了一个解决的办法
在web.xml中加入过滤器HttpPutFormContentFilter,

HttpPutFormContentFilter
org.springframework.web.filter.HttpPutFormContentFilter

HttpPutFormContentFilter /* HttpPutFormContextFilter的原理: HttpPutFormContextFilter有一个doFilterInternal()方法,该方法会将请求体的数据拿过来,封装成inpu3tMessage再调用formCounter,将数据读取成一个map对象,相当于将put请求的数据装换成了map,然后重新封装request对象,再通过getParameter中获取数据。 总之就是,将请求体的数据解析成一个map,重新包装request对象,再通过request从map中获取数据

删除员工
单个删除
批量删除
删除应该有提示信息
弹框 删除xxx用户
单个删除
点击删除按钮进行删除操作
url: /emps/{id} 请求方式:delete
删除逻辑:
点击删除按钮,弹框提示是否删除,若用户点击确认按钮,则进行删除操作
使用confirm实现确认弹框的操作
confirm(message)语法:
confirm(message): 弹出一个带有指定信息以及ok和取消按钮的对话框
message:在弹出的对话框中显示的纯文本内容
confirm具有返回值:
用户点击确认按钮返回true,点击取消按钮返回false
批量删除
需要处理的逻辑:
多选框按钮选中,下面的的子按钮全部被选中
一页中的所有子按钮都被选中时,控制多选的按钮自动被选中
判断选择框的状态:
使用checked属性
例:$(“#checkAll”).attr(“checked”)
出现了问题:attr()判断是否选中时总是undefined
原因:
获取dom的原生的属性值使用prop()方法
选中状态为true,为选中为false
获取自定义的属性值使用attr()方法
复选框与全选框同步
复选框class: check_item 多选框id: checkAll
默认当前被选中的为多选框
( “ . c h e c k i t e m ” ) . p r o p ( “ c h e c k ” , (“.check_item”).prop(“check”, (.checkitem).prop(check,(this).prop(“checked”))
当复选框都被选中时,全选框也被默认选中

        :checked选择器
		$(“.check_item:checked”) //匹配复选框是否被选中,返回一个数组对象
        使用:checked选择器,匹配所有被选中的元素(如:radio,checkbox,select)
        返回是一个数组:Array<Elements>: 数组是被选中框的信息
        可以通过length获取数组的长度
           例:有多个复选框,复选框的id为check_item,判断被选中的复选框个数
               $(“.check_item:checked”).length

实现批量删除的操作:
给控制批量删除按钮添加一个id,点击该按钮时进行批量删除操作
批量删除出现了一个问题,如何将要删除的多个id传入到后台呢?
通过复选框的状态,使用:checked选择器,找到对应的复选框,再进而找到对应的将id拼装成字符串,将该字符串传到后台中去
:checked判断被选中的复选框,找到对应的id,将id拼装成字符串

@RequestMaping可以用@PutMaping替代, 不用在后边指定method

项目截图:
在这里插入图片描述
在这里插入图片描述


  1. a-z0-9_- ↩︎

  2. a-zA-Z0-9_- ↩︎

  3. a-zA-Z0-9_- ↩︎

  4. \u2E80-\u9FFF ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值