1.前言
这段日子一直在学习Spring和SpringMVC的相关知识,看了不少的视频和文章之后,想着动手实操一下。同时也记录一下学习的过程和成果。
由于刚刚接触不久,属于新手,有错的话,可以指正,俺的态度就是:立马改!
2.项目配置说明
1.首先我使用的工具:
开发工具
版本
jdk
1.8
IDEA
2019.2
Tomcat
8.0.53
MySQL
8.0.13
Maven
3.5.4
2.建立数据库表:说明:这里我只建立了一张单表student,如果说需要多表查询,可以自己在此基础上自由扩展。
```
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`sex` varchar(4) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`birth` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`department` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`address` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 939 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (904, '张三', '男', '1990', '英语系', '辽宁省阜新市');
INSERT INTO `student` VALUES (905, '李四', '女', '1991', '英语系', '福建省厦门市');
INSERT INTO `student` VALUES (906, '王五', '男', '1988', '计算机系', '湖南省衡阳市');
INSERT INTO `student` VALUES (915, '陈六', '男', '1997', '计算机系', '河南省郑州市');
INSERT INTO `student` VALUES (936, '候七', '男', 'sda', '撒大声地', '北京市');
INSERT INTO `student` VALUES (938, '钟八', '女', '1999-05-18', '园艺园林', '上海市');
INSERT INTO `student` VALUES (939, '赵九', '男', 'sda', '撒大声地', '深圳市');
SET FOREIGN_KEY_CHECKS = 1;
```
3.搭建springMVC项目框架,使用Maven做jar包管理。
1.依次点击IDEA 的File --> NeW --> Project...,选择左边栏的Maven菜单,之后选中 Create from archetype以及 选中下面的maven-archetype-webapp,选中
之后你可以看到下面出现了一行英文:A simple Java web application. 如下图:
2.填写完项目名相关信息之后,就是maven本地仓库的设置,将下图的选为你的本地仓库,User settings file 文件为本地仓库的conf文件夹下的settings.xml。
3.经过maven项目创建完成后生成的项目文件夹骨架为:
4.我们在此基础上创建出完整的SpringMVC常见的项目文件骨架:
1. 在main文件夹下创建 java 文件夹和resources文件夹。之后在java文件夹下创建包。一般我们创建包都是域名的反写,比如baidu.com,我们创建文件夹就是
com.baidu。(注意:不是文件夹的名字是com.baidu,而是com文件夹里有个baidu文件夹.)
2.这里我用com.itheima吧。在itheima文件夹下创建controller(控制层),service(业务层),dao(数据访问层),entity(实体层)mapper(SQL映射文件
层),再加上一个utils(工具层)(可创建可不创建,自由选择)
3.resources 文件夹创建一个spring文件夹和jdbc.properties文件。webapp下创建static和views两个文件夹,views文件夹下创建student文件夹。最后在student
文件夹下创建list.jsp文件.
4.将java文件夹设为sources文件(做法是选中java文件夹,右键选择Make Directory as --> Sources Root),同理 sources 设为 Resources Root.
5.添加框架支持(Add Frameworks Support),选中项目文件夹,右键点击Add Frameworks Support,然后选择spring下的SpringMVC。静待资源下载完成。下载完成后将生成的dispatch-servlet.xml和
applicationContext.ml移到resources/spring文件夹下,并重新命名为:spring-mvc.xml和spring-mybatis.xml。让我们再看一遍项目结构。
3.项目xml配置(开始贴代码了)
1.pox.xml文件中添加项目依赖和插件.
```
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
com.demo
SSMProDemo
war
0.0.1-SNAPSHOT
SSMProDemo Maven Webapp
http://maven.apache.org
UTF-8
4.3.0.RELEASE
org.springframework
spring-context
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.aspectj
aspectjweaver
1.8.9
org.mybatis
mybatis-spring
1.3.0
org.springframework
spring-jdbc
${spring.version}
mysql
mysql-connector-java
8.0.11
org.apache.logging.log4j
log4j-core
2.6.1
org.mybatis
mybatis
3.4.1
junit
junit
4.10
c3p0
c3p0
0.9.1.2
javax.servlet
jstl
1.2
javax.servlet
javax.servlet-api
3.0.1
provided
javax.servlet.jsp
jsp-api
2.1
provided
com.fasterxml.jackson.core
jackson-core
2.5.2
com.fasterxml.jackson.core
jackson-databind
2.5.2
org.hibernate
hibernate-validator
5.2.2.Final
commons-io
commons-io
2.4
commons-fileupload
commons-fileupload
1.3.1
com.alibaba
fastjson
1.2.47
src/main/java
**/*.properties
**/*.xml
false
maven-compiler-plugin
3.1
1.8
1.8
```
-----------------------------------------------------------------------------------------
说明:标签中的resource必须要写,这关乎着mapper文件夹下的xml文件经编译后能不能在target文件夹下生成的问题。如果无法生成,后面xml配置就会找不到路径文件。
2.web.xml文件配置:
```
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
contextConfigLocation
classpath:spring/spring-mybatis.xml
Spring容器加载监听器
org.springframework.web.context.ContextLoaderListener
SpringMVC
org.springframework.web.servlet.DispatcherServlet
springMVC
contextConfigLocation
classpath:spring/spring-mvc.xml
1
SpringMVC
/
字符集过滤器
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
字符集编码
encoding
UTF-8
encodingFilter
/*
index.jsp
```
3.spring-mvc.xml
```
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd" >
```
4.spring-mybatis.xml配置
```
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
destroy-method="close">
```
4.实现业务逻辑
首先我们先从控制层写起。一般来说,客户端发来的请求,从控制层开始处理,控制层调用service层的逻辑代码,而service层实际上是接口层,我们在serviceImpl包
下会实现这些接口,也就是间接调用了实现层的方法。而实现层会调用数据访问层(dao)的接口。最终会和mapper文件中的SQL映射连接起来。
1.首先我们在entity 创建Student 实体类,此类是数据库student表的对应类,添加对应的get/set方法,千万记住,务必要添加无参构造方法。不然项目后面运行的时候
可能出现让你摸不到头脑的错误。其次,再创建一个Message类,此类数据库不做映射,其用途只是封装返回消息的类。
```
package com.itheima.entry;
/**
* @Author:Duanzhenbiao
* @Date:2020/11/17
* @Description:
*/
public class Student {
private Integer id; // 学生ID
private String name ; // 学生姓名
private String sex ; // 学生性别
private String birth; // 学生生日
private String department; // 学生所属部门.
private String address ; // 学生所在地址
// 无参构造
public Student() { }
public Student(String name, String sex, String birth, String department, String address) {
this.name = name;
this.sex = sex;
this.birth = birth;
this.department = department;
this.address = address;
}
public Student(Integer id, String name, String sex, String birth, String department, String address) {
this.id = id;
this.name = name;
this.sex = sex;
this.birth = birth;
this.department = department;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirth() {
return birth;
}
public void setBirth(String birth) {
this.birth = birth;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", birth='" + birth + '\'' +
", department='" + department + '\'' +
", address='" + address + '\'' +
'}';
}
}
```
Message消息类
public class Message {
// 封装的消息类 : 给前端返回json数据时用的消息类. (注:该类,数据库表不做映射.)
//状态码 200-成功 100-失败
private int code;
//提示信息
private String msg;
public Message() { }
public Message(int code, String msg) {
this.code = code;
this.msg = msg;
}
public Message(int code, String msg, Map data) {
this.code = code;
this.msg = msg;
this.data = data;
}
//用户要返回给浏览器的数据
private Map data = new HashMap();
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map getData() {
return data;
}
public void setData(Map data) {
this.data = data;
}
@Override
public String toString() {
return "Message{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
2.我们首先在controller层中创建studentController类 ,service层创建studentService接口,dao层创建studentDao接口,mapper创建studentMapper.xml文件。service文件夹下的Impl文件夹中创建studentServiceImpl类并继承studentService,重写service接口方法。
3.增删改查我也不细说了,直接贴代码,运行吧。
studentController层:
package com.itheima.controller;
import com.itheima.entry.Message;
import com.itheima.entry.Student;
import com.itheima.service.StudentService;
import com.itheima.util.Util;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* @Author:Duanzhenbiao
* @Date:2020/11/17
* @Description: 学生表的增删改查.
*/
@Controller
@RequestMapping("/student")
public class StudentController {
@Autowired
private StudentService studentService;
// 获取所有数据
@RequestMapping("/list")
public String selectAllStudents(Model model, @RequestParam(required=false,defaultValue="1") int page){
// 每页的条数
int count = 5;
// 每页的数据
List ls = studentService.selectAllStudents(page,count);
// 该学生表的总学生人数.
Integer total = studentService.getStudentTotal();
model.addAttribute("current_page",page);//当前页
model.addAttribute("total",total); // 总数量
model.addAttribute("count",count);// 每页的数量
model.addAttribute("students",ls);// 每页的学生数据.
return "student/list";
}
/**
* 添加学生对象
* @param student
* @return
*/
//添加数据
@RequestMapping(value ="/add",produces="text/plain;charset=UTF-8") // 设置UTF-8 是为了返回时网页能正常显示中文.
@ResponseBody
public String insertOneStudent(Student student){
System.out.println( student);
int result = studentService.insertOneStudent(student);
String res = result == 1 ? "{'status':200,'response':'添加成功'}":"{'status':100,'response':'添加失败'}";
System.out.println(res);
return res;
}
/**
* 编辑学生对象
* @param student
* @return
*/
// 编辑数据,限定访问方法.
@RequestMapping(value = "/edit",method = RequestMethod.POST)
@ResponseBody
public Message updateStudent(Student student){
// 消息实例,备用.
Message msg = new Message();
// 检测传进来的参数是否为空值。
System.out.println(student);
boolean flag = Util.checkStudentNull(student);
if (!flag){
msg.setCode(100);
msg.setMsg("fail");
return msg;
}
// 简单限制之后,更新数据库
int result = studentService.updateStudent(student);
if(result == 1){
msg.setCode(200);
msg.setMsg("success");
}
return msg;
}
/**
* 删除 student
* @param id
* @return
*/
@RequestMapping("/delete")
@ResponseBody
public Message deleteStudent(@RequestParam(value = "id" ,required = true) int id){
// 消息实例,备用.
Message msg = new Message();
// 数据库删除数据
int result = studentService.deleteStudent(id);
if(result == 1){
msg.setCode(200);
msg.setMsg("success");
}else{
msg.setCode(100);
msg.setMsg("fail");
}
return msg;
}
@RequestMapping(value = "/getStudentById")
@ResponseBody
public Message selectStudentById(@RequestParam(value = "editID" ,required = true) int editID){
// 实例化消息实例
Message msg = new Message();
// 查询对应的student数据
Student student = studentService.selectStudentById(editID);
if(student == null) {
msg.setCode(100);
msg.setMsg("fail");
return msg;
}else{
msg.setCode(200);
msg.setMsg("success");
msg.getData().put("data",student);
}
System.out.println(msg);
return msg;
}
}
studentService层:
package com.itheima.service;
import com.itheima.entry.Student;
import java.util.List;
public interface StudentService {
// 查询所有学生
List selectAllStudents(int page,int count);
// 添加一位学生
int insertOneStudent(Student stu);
// 查询该表总共有多少条数据
int getStudentTotal();
// 更新数据库的某条数据
int updateStudent(Student student);
// 通过ID查询student
Student selectStudentById(int editID);
// 通过ID删除对象
int deleteStudent(int id);
}
studentServiceImpl层:
package com.itheima.service.Impl;
import com.itheima.dao.StudentDao;
import com.itheima.entry.Student;
import com.itheima.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Author:Duanzhenbiao
* @Date:2020/11/17
* @Description:
*/
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public List selectAllStudents(int page, int count) {
int skip = (page-1)*count;
return studentDao.selectAllStudents(skip,count);
}
// 添加一个学生
@Override
public int insertOneStudent(Student stu) {
return studentDao.insertOneStudent(stu);
}
// 查询学生表总共有多少位学生.
@Override
public int getStudentTotal() {
return studentDao.getStudentTotal();
}
// 更新数据库某条数据
@Override
public int updateStudent(Student student) {
return studentDao.updateStudent(student);
}
// 通过ID查询student
@Override
public Student selectStudentById(int editID) {
return studentDao.selectStudentById(editID);
}
@Override
public int deleteStudent(int id) {
return studentDao.deleteStudent(id);
}
}
studentDao 层
package com.itheima.dao;
import com.itheima.entry.Student;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Author:Duanzhenbiao
* @Date:2020/11/17
* @Description:
*/
public interface StudentDao {
// 查询所有学生接口
List selectAllStudents(@Param("skip") int skip, @Param("count") int count);
// 添加一位学生.
int insertOneStudent(Student stu);
// 获取学生总共有多少条数据.
int getStudentTotal();
// 更新数据库中某条数据
int updateStudent(Student student);
// 通过ID查询相应对象数据
Student selectStudentById(int id);
// 通过 id删除相应的对象数据
int deleteStudent(int id);
}
还剩最重要的mapper文件:studentMapper.xml
select * from student limit #{skip},#{count}
insert into student(name,sex,birth,department,address) value(#{name},#{sex},#{birth},#{department},#{address})
select count(*) from student
update student set name = #{name},sex = #{sex},birth = #{birth},department = #{department},address = #{address} where id = #{id}
select * from student where id = #{id}
delete from student where id = #{id}
原本我是想增、删、改、查叙述的,结果贴的代码看起来很多,所以临时改变了方式。上面的代码实现了后端的事情,可以用postman测试一下接口,接着就是前端的事了。
前端从index.jsp 页面开始,跳转到list.jsp页面,在此页面进行增删改查,看看实际效果再贴代码吧。
添加窗口