Java基础,JavaWeb开发基础,Spring基础(没有Spring的基础也能够,接触过Spring最好),ajax,Jquery,Mybatis。 html
下面开始实现一个简单的学生的添加 前端
在crud-sys子项目中建立entity文件夹并建立和数据库相对应的Student类及其get,set函数。 java
public class Student { /** 学生id */ private String Name; /** 学生英语成绩 */ private Integer English; /** 学生数学成绩 */ private Integer Math; /** 学生计算机成绩 */ private Integer Computer; public String getName () { return Name; } public void setId(String Name) { this.Name = Name; } public Integer getEnglish() { return English; } public void setEnglish(Integer english) { English = english; } public Integer getMath() { return Math; } public void setMath(Integer math) { Math = math; } public Integer getComputer() { return Computer; } public void setComputer(Integer computer) { Computer = computer; } }
这个项目中继承了Mybatis,因此在进行数据库操做以前咱们须要进行Mybatis的相关配置以及数据库的链接操做。 mysql
进入https://mvnrepository.com/网站,输入mybatis查询mybatis依赖包: jquery
这里选择org.mybatis.spring.boot里的mybatis-spring-boot-starter: web
点击以后选择版本,这里我不习惯选择太新的也不喜欢太旧的版本,因此通常会在稍微新的版本中选择用户数最多的那一个,好比mybatis我选择2.0.1 ajax
点击进去以后复制依赖: spring
第一步以后,将文本复制到crud-web子项目的pom.xml文件中,在<dependencies>标签中加入刚才复制的文本。sql
此时右下角出现Import changes和Enable auto import,这里能够选择后者,之后修改pom.xml文件后,项目会自动导入jar包。 数据库
首先仍是要经过上面的方法添加mysql的依赖到pom.xml文件中
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency>
在crud-web的resource文件夹下的application.properties文件中配置链接信息:
这些和普通的web开发中的DBUtil的写法大同小异。
一样在application.properties文件配置mybatis的映射文件路径
mybatis.mapper-locations=classpath:/mapping/*.xml
这句话的意思是mybatis的映射文件存在于classpath(classpath就是生成target目录后classes文件所在目录)的mapping目录下以.xml结尾的文件。
在crud-sys子项目下新建mapper文件夹,其下新建StudentMapper接口:
Mapper类中主要写对实体的操做函数的定义,这里咱们先定义一个添加函数。
添加代码:public void add(Student student);
在resource文件夹下建立mapping文件夹,在其下建立StudentMapping.xml文件。
在xml文件中写入mybatis映射文件须要的头,能够在网上搜索mybatis映射文件头文件,也可进入官网去找
<?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">
设置这个xml文件对应的是哪一个接口类中的函数。
添加<mapper>标签,在标签中配置namespace为接口类所在的路径
Mybatis提供了insert、update、delete和select分别对应添加、更改、删除和查询操做,这里咱们用到的是insert标签。
<insert id="add" parameterType="com.dingcheng365.crudsys.entity.Student ">
</insert>
id:id的值为所对应的Mapper接口中的函数的名称,必须彻底一致。
parameterType:参数类型,若是没有参数或两个以上参数,可不写改属性,若是是一个参数,须要写上参数的类型,最好将包名加上,如String类型写java.lang.String,Map类型写java.util.Map
resultType:这个在这个例子中没有体现。表示的是函数的返回值类型,若是为void可不写该属性。这里须要注意的是:resultType表示每个元素的值,例如咱们要进行查询,返回值是List<Student>,由于查询结果不必定是一个学生知足条件,可是这时候resultType须要填写的是Student类而非List。
若是字段多的话添加语句会很长很难写,这里介绍一个快速且简单的办法:
在Navicat中随便选中一行,右键复制为insert语句:
粘贴后效果:
INSERT INTO `test`.`student` (`Name`, `English`, `Math`, `Computer`) VALUES ('zhangsan', '69', '86', '77');
这时候只须要修改后面的参数便可。
将语句粘贴到insert标签中,同时修改参数,使用#{}中间加上参数的名称:
在crud-sys下建立service文件夹,在其下建立StudentService接口类,里面写入函数,通常会和Mapper类中的函数类似,可能会返回值不一样。
在service文件夹下建立impl文件夹,在其下建立StudentServiceImpl类实现StudentSerivce接口。
这里须要注意的是:Service实现类上面须要加入@Service注解。在这个类中须要使用@Autowired注解注入studentMapper对象。
@Autowired:自动导入依赖的bean
@Service:通常用于修饰service层的组件
而后编写代码,调用studentMapper的添加函数,添加成功后返回1,若是失败则返回0;
@Autowired private StudentMapper studentMapper; @Override public int add(Student student) { try { studentMapper.add(student); return 1; } catch (Exception e) { return 0; } }
至此,crud-sys子项目中所须要实现的功能已经编写完毕,接下来就是和网页的交互了。
SpringBoot能够识别出resources文件夹下的static及其子文件夹下的文件,若是须要自定义文件夹,则须要在配置文件中配置。
在curd-web子目录的templates文件夹下建立addstudent.html并写入表单元素。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学生添加</title> </head> <body> <form id="studentinfo"> <table> <tr> <td>姓名:</td> <td><input type="text" name="name" id="name"></td> </tr> <tr> <td>英语成绩:</td> <td><input type="text" name="English" id="English"></td> </tr> <tr> <td>数学成绩:</td> <td><input type="text" name="Math" id="Math"></td> </tr> <tr> <td>计算机成绩:</td> <td><input type="text" name="Computer" id="Computer"></td> </tr> <tr> <td colspan="2"> <button id="add-student-btn" type="button">提交</button> </td> </tr> </table> </form> </body> </html>
使用jquery-validate对表单输入的值进行验证,导入jquery.min.js和jquery-validate.min.js后进行编写。
// 表单验证 userInfoValidate = $('#userInfo').validate({ rules: { name: { required: true }, English: { required: true }, Math: { required: true }, Computer: { required: true } }, messages: { name: { required: '姓名不能为空' }, English: { required: '英语成绩不能为空' }, Math: { required: '数学成绩不能为空' }, Computer: { required: '计算机成绩不能为空' } }, errorElement: 'small', errorPlacement: function(error, element) { // 在error 上添加 `invalid-feedback` class error.addClass('invalid-feedback'); element.parent().append(error); }, highlight: function(element) { $(element) .addClass('is-invalid') .removeClass('is-valid'); }, unhighlight: function(element, errorClass, validClass) { var $valid = $(element); if (!validClass) { $valid.removeClass('is-invalid is-valid'); } else { $valid.addClass('is-valid').removeClass('is-invalid'); } }, submitHandler: function (form) { // 确认登陆时删除存储标签页对象 // TODO: KEY值请参考`site-configs.js`文件中配置的`tabSittings`的值 window.sessionStorage.removeItem('admui.contentTabs'); } });
经过id调用validate函数,示例中的$('#userinfo').validate({..})
rules:表示表单验证的规则,rules中的第一层的子元素对应的是input标签的name而非id值。
子元素验证,在子元素中写入须要进行的验证,经常使用的有required:true表示不可为空,false表示可为空;minlength:设置输入的最短长度;maxlength:输入的最长长度;email:true表示必须输入正确的电子邮件;digtis:true表示必须输入整数等。
message:自定义提示信息,与rules中一一对应,表示不知足规则时提示的信息。
errorElement:用什么标签标记错误,默认是label
errorPlacement:自定义错误放置的位置
highlight:能够给未经过验证的元素加效果、闪烁等。
submitHandler:全部验证经过后执行的函数
效果图:
3)Ajax实现和Controller的交互
$("#add-student-btn").on('click', function () { $.ajax({ url: '/student/addstudent',//请求的地址 type: 'post',//请求类型:GET、POST、DELETE、PUT data: { //向请求传递的数据 "name": $("#name").val(), "English": $("#English").val(), "Math": $("#Math").val(), "Computer": $("#Computer").val() }, async: true, //是否异步,默认为true success: function (e) { //请求成功的回调函数,e为后台传递过来的信息 console.log(e) }, error: function (e) { //请求失败的回调函数 console.log("ajax请求失败"); } }); });
经过提交按钮的点击事件,向student/addstudent发送POST请求,传递的数据为用户输入的信息,请求后将后台返回的信息打印到控制台。
Controller是与前台进行直接交互的模块,因此在crud-web子项目中建立包controller,在其下建立StudentController类。
Controller类都须要加入注解@Controller,表示这是一个控制类
Controller类上面的@RequestMapping中的参数表示这个Controller中的全部映射路径都是以这个参数开头
若是Controller中一个函数须要返回json数据类型,则须要加入@ResponseBody注解,一般用来返回JSON数据或者是XML,通常咱们返回字符串类型时也须要使用这个注解
慎用@RestController,@RestController是@ResponseBody和@Controller的结合,当你返回的类型不是json等的时候,使用这个会将你返回的数据自动转换成json类型返回。好比你须要返回一个页面的时候就不能使用这个。
Controller返回页面也是一个很重要的点,能够参考个人博客:http://www.javashuo.com/article/p-fepgwgfh-cb.html
这里会发现一个错误:service没法进行注入。缘由是service所在的路径必须是启动类所在的路径的子目录。修改目录结构后问题获得解决。
@Controller @RequestMapping("/student") public class StudentController { @Autowired private StudentService studentService; @RequestMapping("/addstudent") public String addstudent(Student student) { return String.valueOf(studentService.add(student)); } }
因为前台传递数据的时候所传递的json对象与Student对象的属性一一对应,因此在Controller接收的时候能够直接在参数中书写Student对象,系统会进行自动转换。
咱们须要编写IndexController来实现默认页面的显示,在controller文件夹下建立IndexController文件,写入根路径的映射:
@RequestMapping("/") public ModelAndView index() { return new ModelAndView("addstudent.html"); }
若是发现设置完毕后启动项目显示404的问题,能够参考博客:http://www.javashuo.com/article/p-fepgwgfh-cb.html里面详细阐述了SpringBoot如何返回页面的问题
在CrudWebApplication.java下右键Run CrudWebApplication,发现启动错误:
这个问题产生的缘由是虽然咱们在Mapper类上面都加入了@Compent注解,可是项目并不知道有Mapper,不知道须要去加载Mapper,因此咱们须要在启动类上方加入@MapperScan注解,参数为basePackages = {"com.dingcheng365.crud.sys.mapper"},加入以后在项目启动的时候就会自动扫描这个包中的全部Mapper类。
@MapperScan(basePackages = {"com.dingcheng365.crud.sys.mapper"})
从新启动项目:
出现这个提示表示项目启动成功,端口号为8080,若是想修改项目的端口号,能够修改application.properties文件加入 server.port=端口号 配置项。
启动后输入localhost:8080,因为咱们以前配置了根路径映射的函数,是返回addstudent.html页面,因此会出现这个页面。
输入信息后点击提交,发现添加失败,查看控制台报错:
这个问题的解决办法可参考博客:http://www.javashuo.com/article/p-uvfubnzt-bm.html
最简单的解决办法就是在链接语句中加入serverTimezone=GMT
加入以后从新启动并输入信息后点击提交,发现数据库中存在新添加的信息,至此学生信息添加的功能实现完毕。
实现了这个功能以后,删除、修改、查询之类的功能基本大同小异,这里我只说几点须要注意的地方。
十二、其余问题
1)删除时删除单个信息
若是删除单个信息咱们通常会使用/delete/id这样的路径,也就是直接将id值传递到路径中,而且不使用?id=1这种格式,这样在Controller类中接收的时候有所不一样,下面是实例:
@RequestMapping("/deletestudent/{id}") @ResponseBody public String deleteUser(@PathVariable("id") String id) { return studentService.delete(id); }
能够看到,须要加入@PathVariable注解,参数为须要读取的值的名称,并且在RequestMapping中写的路径id值不肯定须要加上大括号。
2)删除时删除多个信息(批量删除)
批量删除的时候,咱们在前台传递的确定是一个数组,里面包含要删除的多个id值,这个在Controller接受的时候也有所不一样,因为是数组的问题。下面是实例:
前台:
$.ajax({ url: "/user/deleteUsers", type: "post", data: { ids": ids }, success: function (e) { if (e == "success") { toastr.success("删除成功"); } else { toastr.error("删除失败,请稍后重试"); } }, error: function (e) { console.log(e); } });
后台接收:
@RequestMapping(value = "/deleteUsers") @ResponseBody public String deleteUsers(@RequestParam("ids[]") List<String> ids,) { …… }
在进行数组接受的时候,须要在@RequestParam注解中加入名称加上[]的参数才能正确接收。
3)前台传递过来的对象并无和后台相对应
这个实例中,咱们从前台接收的对象的参数正好和后台存在的Student类相对应,因此咱们在后台直接用Student对象接受,那若是不一致的时候该怎么办?有两种状况:
当参数个数比较少,2-4个左右时,咱们能够直接在接收的函数中一个一个罗列出来,对应关系使用@RequestParam来进行区分。
当参数个数比较多时,我我的推荐一个类型——Map类,这个类真的是百用不爽,因为他和json结构上的类似性,致使这个类的用途很是之大。在进行数据查询的时候若是咱们要查询的结果并非某一个类的集合,这个时候用Map对象也能够很完美的解决问题。