spring|springboot简单小项目练习之增删改查-exercisePro01


文章目录

  • 一、项目介绍
  • 二、项目分析
    • 1、技术分析
    • 2、数据库设计
  • 三、前端
    • 1、目录结构
    • 2、页面
    • 3、增删改查前台代码及解析
    • 4、base.js和css
  • 四、后端
    • 1、搭建后台框架及构建配置文件
      • 1)目录结构及介绍
      • 2)构建配置文件——yml
      • 3)使用jpa创建表
        • 1、原理
        • 2、步骤
    • 2、后台代码编写
      • 1)数据访问层(repository)
      • 2)数据业务层(service)
      • 3)前台控制器(controller)

(第一版:仅做了学生的增删改查)
一、项目介绍
  • 项目名称:希望小学学生管理系统
  • 项目需求:
1、学生信息的添加,删除,修改和编辑
2、需要管理的信息:
学生:学生学号,姓名,性别,班级,住址,出生日期
成绩:课程编号,学生学号,成绩
课程:课程编号,课程名称
教师:教师编号,姓名,性别,住址,出生日期
二、项目分析 1、技术分析 前端:html+css+js
后端:mysql+后台系统(springboot)
2、数据库设计 主表:
学生表——stu
名称 字段名 类型和长度
id id int(11)
学号 stu_no varchar(255)
姓名 stu_name varchar(255)
性别 gender int(11)
班级 stu_class varchar(255)
住址 stu_address varchar(255)
出生日期 stu_birthday datetime(0)
成绩表——grade
名称 字段名 类型和长度
id id int(11)
课程id cou_id int(11)
学生id stu_id int(11)
分数 score int(11)
课程表——course
名称 字段名 类型和长度
id id int(11)
课程编号 course_no varchar(255)
课程名称 course_name varchar(255)
教师表——teacher
名称 字段名 类型和长度
id id int(11)
教师编号 tea_no varchar(255)
姓名 tea_name varchar(255)
性别 gender int(11)
住址 tea_address varchar(255)
出生日期 tea_birthday datetime(0)
关联表:
学生课程关联表
名称 字段名 类型和长度
id id int(11)
学生id stu_id int(11)
课程id cou_id int(11)
教师课程关联表
名称 字段名 类型和长度
id id int(11)
教师id tea_id int(11)
课程id cou_id int(11)
三、前端 1、目录结构 spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

【spring|springboot简单小项目练习之增删改查-exercisePro01】目录介绍:
css:样式修饰文件
js:这个也不知道咋个介绍法,大名叫javaScript
static:放静态资源的文件夹,图片啥的
view:放页面的文件夹
2、页面 很丑,不过不慌,以后慢慢修饰呗,功能先整上去
首页
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

添加/编辑页面
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

3、增删改查前台代码及解析 index.html
学生管理系统 - 锐客网 src="https://www.it610.com/js/base.js">src="https://www.it610.com/js/jquery.js">src="https://www.it610.com/js/index.js">
序号 学号 姓名 性别 班级 住址 生日 操作

add.html
src="https://www.it610.com/js/base.js"> src="https://www.it610.com/js/jquery.js"> src="https://www.it610.com/js/add.js"> 添加 - 锐客网
  • >学号:
  • >姓名:
  • >性别:
    >男 >女
  • >班级:
  • >地址:
  • >生日:

index.js
addLoadEvent(goAdd)//这个方法再base.js,相当于jq的$(document).ready(function(){ your code }) //跳转添加页面(古董方法,留着做个纪念) function goAdd(){ //getElementByXpath()也在base.js中,用的是xpath定位方法(花里胡哨) getElementByXpath("/html/body/div[2]/button").onclick = function(){ window.location.href = "https://www.it610.com/article/add.html" } } //显示首页数据 /* 思路: 将后台数据用ajax请求到,让后js动态生成tr,将data迭代到页面上 */ $(document).ready(function(){//页面加载完后执行 //jq的ajax方法,开始想着自己封装Ajax了,最后发现自己菜的一批,还是jq香 $.ajax({ url:"http://127.0.0.1:8081/stu/findAllStu",//后台请求路径 type:"GET",//请求方法,具体看自己后台写的是GetMapping还是PostMapping dataType:'json',//数据类型是json contentType:"application/json",//内容类型,传json就得写这个 success:function(data){//成功时候的回调函数,凡间的话就是请求成功了,你前台要干的活儿 data = https://www.it610.com/article/dataChange(data); //将后台的数据处理一下(有些格式是不对的) var table = getElementByXpath("/html/body/div[1]/table"); //获取table var newTr = document.createElement("tr"); //创建一个tr元素 for(var i = 0; i'+ ''+data[i].stuNo+''+ ''+data[i].stuName+''+ ''+data[i].gender+''+ ''+data[i].stuClass+''+ ''+data[i].stuAddress+''+ ''+data[i].stuBirthday+''+ '+data[i].id+')">删除    +data[i].id+')">编辑'; table.appendChild(newTr); //把这个tr添加到table中 newTr = document.createElement("tr"); //重新赋值 } }, //异常处理 error:function(e){ console.log(e); } }); }); // 数据转换(将后台数据转换一哈) function dataChange(data){ //创建一个新的模板 var newData = https://www.it610.com/article/[]; for(var i = 0; i

add.js
//提交学生 $(document).ready(function(){//页面加载完后执行 $("#submit").click(function(){ //获取学生信息 var stuNo,stuName,stuClass,stuAddress,stuBirthday,gender; var id = window.location.href.split("?")[1]; //截取链接中的id值 stuNo = document.getElementById("stuNo").value; //获取学号 stuName = document.getElementById("stuName").value; //获取名字 stuClass = document.getElementById("stuClass").value; //获取班级 stuAddress = document.getElementById("stuAddress").value; //获取地址 stuBirthday = document.getElementById("stuBirthday").value; //获取生日 gender = getElementByXpath("/html/body/div[1]/ul[1]/li[3]/div/input[1]").checked?0:1; //获取单选框值 //组装json var data = https://www.it610.com/article/{}; data["id"] = id; data["stuNo"] = stuNo; data["stuName"] = stuName; data["stuClass"] = stuClass; data["stuAddress"] = stuAddress; data["stuBirthday"] = stuBirthday; data["gender"] = gender; console.log(JSON.stringify(data)) //ajax上传学生信息 $.ajax({ url:"http://127.0.0.1:8081/stu/saveStu",//请求地址 type:"POST",//请求方法 data:JSON.stringify(data),//将数据转换成json格式 dataType:'json',//数据类型:json contentType:"application/json",//内容:json success:function(data){ //不知道是什么鬼,也不报错,但是就是不走success }, error:function(e){ if(id == "undefined"){//如果没有id说明时添加 console.log("添加成功") }else{//有id说明时编辑 console.log("编辑成功") } } }) }); }); //显示编辑页面学生信息 $(document).ready(function(){ //获取学生id var id = window.location.href.split("?")[1]; //显示学生 $.ajax({ url:"http://127.0.0.1:8081/stu/findStu",//不说了,看上面 type:"get", data:{id:id}, dataType:'json', contentType:"application/json", success:function(data){ //为页面赋值 $("#stuNo").val(data.stuNo) $("#stuName").val(data.stuName) $("#stuClass").val(data.stuClass) $("#stuAddress").val(data.stuAddress) $("#stuBirthday").val((data.stuBirthday).substring(0,10)) if(data.gender == 0){//这里用了”高级“一点的选择器,字面意思可以读懂,就不比比了 $("input[name = 'gender'][value=https://www.it610.com/article/0]").attr("checked",true); }else{ $("input[name = 'gender'][value=https://www.it610.com/article/1]").attr("checked",true); } }, error:function(e){ console.log(e); } }); //提交 })//跳转首页页面 $(document).ready(function(){ $("#back").click(function(){ window.location.href = "https://www.it610.com/article/index.html"; }); });

4、base.js和css 这部分就不解释了,和咱项目关系比较远了,都是些前端知识,可以看看
base.js
//文档加载函数 function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } } //封装xpath function getElementByXpath(xpath){ var element = document.evaluate(xpath,document).iterateNext(); return element; }//追加元素 function insertAfter(newElement,targetElement){ var parent = targetElement.parentNode; //获取目标元素的父节点 if(parent.lastChild == targetElement){ parent.appendChid(newElement); }else{ parent.insertBefore(newElement,targetElement.nextSibling); //nextSibling是表示下一个兄弟元素节点 } } //追加新的class function addClass(element,value){ if(!element.className){ element.className = value; }else{ newClassName = element.className; newClassName += " "; newClassName += value; element.className += newClassName; } }

index.css
*{margin: 0; padding: 0; list-style: none; } .add{ padding: 50px 40px 0 40px; background-color: #FAEBD7; width: 300px; height: 300px; position: absolute; left: 40%; top: 25%; } //清除父元素浮动 .add ul li:after{ margin: 0 0 10px 0; content:""; display:block; clear:both; } .add ul li:nth-child(1) input,li:nth-child(2) input,li:nth-child(4) input,li:nth-child(5) input,li:nth-child(6) input{ position: absolute; right: 10%; } .add ul li:nth-child(3) div{ margin: 0; padding: 0; width: 160px; float: right; //使rdio和input对齐 } .add ul li span{ } .add ul:nth-child(2) li button{ width: 100px; background-color: cornflowerblue; position: absolute; right: 10%; } .backIndex button{ width: 100px; height: 50px; background-color: #eee; position: absolute; top: 25%; right: 25%; }

add.css
*{margin: 0; padding: 0; } /* 首页 */ .main{ background-color: antiquewhite; position: absolute; left: 30%; top: 20%; } .table{ width: 600px; } .tr td,th{ text-align: center; width: 200px; height: 50px; } .goAdd button{ width: 100px; height: 50px; background-color: #eee; position: absolute; top: 20%; right: 20%; }

四、后端 1、搭建后台框架及构建配置文件 1)目录结构及介绍
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

  • config:配置类,放置一些配置类,例如c3p0连接池配置,跨域请求配置等
  • constant:常量类,通常放置枚举类型常量,供其他类使用
  • controller:前端控制器,作用相当于xml,为前台提供接口
  • dto:将实体类entity包装,避免数据库的接口直接暴露出来
  • entity:实体类,相当于vo,存放数据库对应的实体对象
  • repository:数据访问层,相当于dao,sql语句一般在这里写
  • service:数据服务层:业务逻辑的实现层
  • util:工具类
  • BigproductApplication:启动类,springboot的启动器
  • pom.xml:依赖配置,在这里配置需要的依赖
2)构建配置文件——yml
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

配置文件位于resources中,这里创建的了三个配置文件
  • application-yml:主配置类,主要配置类可以激活其他的一些配置
  • application-dev.yml:开发环境配置
  • application-pro.yml:生产环境(项目发布后)配置
源码及解析(以下有些配置可能前期开发阶段不需要)
application.yml
#配置spring spring: profiles: active: dev #激活开发模式配置文件 #配置服务server server: #配置tomcat服务 tomcat: uri-encoding: utf-8#使tomcat在解析参数的时候采用utf-8编码格式,如果未指定则采用ISO-8859-1编码解析 max-connections: 3000 #最大连接数 max-http-form-post-size: 1048576 #(1Mb)最大的post请求数,tomcat7之后,-1代表不限制请求,7之前0代表不限制请求 max-http-header-size: 1048576 #请求头部最大值(1Mb) c3p0: jdbcUrl: jdbc:mysql://127.0.0.1:3306/stumanger?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8 user: root password: 123456 driverClass: com.mysql.jdbc.Driver #数据库连接驱动类 minPoolSize: 2 #最小连接数 maxPoolSize: 100 #最大的连接数 maxIdleTime: 1800000 #创建过的链接并使用后闲置下来的闲置时间,如果超过这个时间就会自动断开这个连接 acquireIncrement: 3 #当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 maxStatements: 1000 #JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭 initialPoolSize: 3 #初始化时获取连接数 idleConnectionTestPeriod: 60 #每60秒检查所有连接池中的空闲连接 acquireRetryAttempts: 30 #定义在从数据库获取新连接失败后重复尝试的次数 acquireRetryDelay: 1000 #两次连接中间隔时间,单位毫秒 breakAfterAcquireFailure: false #获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。Default: false testConnectionOnCheckout: false #因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable等方法来提升连接测试的性能

application-dev.yml
server: port: 8081 #服务端口为8081 servlet: session: timeout: -1 #设置session用不过期 spring: jpa: hibernate: ddl-auto: update #如果启动时表格式不一致则更新表,原有数据保留 show-sql: true #是否打印生成的sql语句

application-pro.yml
server: port: 8081 servlet: session: timeout: 2h #session保存两个小时 spring: jpa: hibernate: ddl-auto: none show-sql: false

3)使用jpa创建表
1、原理 ? 在写配置文件的时候,我们写过如下一段代码
spring: jpa: hibernate: ddl-auto: update #如果启动时表格式不一致则更新表,原有数据保留 show-sql: true #是否打印生成的sql语句

? 其中用springboot创建表的核心就是jpa,jpa中的ddl-auto:update就可以在程序运行启动的时候,将实体类映射到数据库中,将数据库中表跟新为当前实体类的格式类型,当然ddl-auto还有其他参数,如下:
  • create 启动时删数据库中的表,然后创建,退出时不删除数据表
  • create-drop 启动时删数据库中的表,然后创建,退出时删除数据表 如果表不存在报错
  • validate 项目启动表结构进行校验 如果不一致则报错
2、步骤 1)用Navicat创建一个数据库 stumanger
2)在entity中构建自己的实体类
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

? 用其中学生表 Stu 举例:
package com.fjh.bigproduct.model.entity; import javax.persistence.*; import java.util.Date; /** *@autho antg *@date 2020-08-05 20:48 */ @Entity @Table(name = "stu") class Stu { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private int id; //学号 @Column(name="stu_no",columnDefinition = "varchar(255) comment'学号:2020+年级+班级 例如:20200101代表一年级一班,前4位表示入学年份'") private String stuNo; //学生姓名 @Column(name="stu_name",columnDefinition="varchar(255) comment'学生姓名'") private String stuName; //性别 @Column(name = "gender",columnDefinition = "int(11) comment'0:男,1:女'") private int gender; //班级 @Column(name = "stu_class",columnDefinition = "varchar(255) comment'班级'") private String stuClass; //住址 @Column(name = "stu_address",columnDefinition = "varchar(255) comment'住址'") private String stuAddress; //出生日期 @Column(name = "stu_birthday",columnDefinition = "datetime comment'出生年月日'") private Date stuBirthday; }

? 指定表名
? @Entity
? @Table(name=“表名”)
? 指定字段及属性
? @Column(name=“字段名”,columnDefinition = “类型(长度) comment’注释’”)
3)启动springboot生成表
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

2、后台代码编写 1)数据访问层(repository)
数据访问层相当于ssh项目中的dao,写操作数据库数据的方法
由于之前搭建的时候引入了jpa,所以在编写该层的时候可以继承数据访问的超级接口JpaRepository,然后就可以调用这个接口里面的方法就可以实现对数据库数据的crud。
先上代码,再逐个解释
package com.fjh.bigproduct.repository; import com.fjh.bigproduct.model.entity.Stu; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import javax.transaction.Transactional; import java.util.List; /** *@autho antg *@Description 操作学生增删改查 *@date 2020-08-17 17:16 */@Repository public interface StuRepository extends JpaRepository,Integer> { //查询出所有未删除的学生 @Query("from Stu where delState = 0") List> findAll(); //根据id查询学生 Stu findStuById(int id); //保存编辑一个学生信息 //直接使用jpa封装好的save方法就行}

1、注解:@Repository
这个注解用来标识这是一个数据访问层的类或者接口,并且在spring扫描的时候会将其加入到bean中
2、public interface StuRepository extends JpaRepository
这个StuRepository接口继承了jpa提供的超级数据访问接口JpaRepository,(这里的接口用到了自定义泛型,可以理解为“参数”,不过这个参数有些特殊,这俩参数是用来限定JpaRepository中方法的泛型的,下面来一部分源码解释一下)
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

那么StuRepository就可以使用jpa提供的所有数据访问方法。(这里的JpaRepository接口无法使用jpa的高级属性,如果要使用高级属性的话,需要继承JpaSpecificationExecutor,这个我也没用过(手动狗头))
3、查询出所有未删除的学生
这里使用了一个注解@Query,这个注解可以让我们使用自己定义的方法就例如下面这一段代码
@Query("from Stu where delState = 0") List> findAll();

我想要找到数据库中所有删除标志为0的数据,那么使用jpa自带的几个方法可能就不够用了,那就需要自己定义方法。
里面的语句可能写习惯sql语句的同学会看不懂,这里其实使用的叫HQL语句,是一种面向对象的查询语句,可以百度一下,语法比较简单,但是如果有同学就想写sql语句这么办呢?不慌,可以使用下面的写法
@Query("select * from stu where del_state = 0",nativeQuery = true) List> findAll();

nativeQuery属性默认是false的,若变为true就可以使用原生的sql语句
4、根据id查询学生
Stu findStuById(int id);

这里使用的是jpa提供的接口,么的说,直接写就行
5、保存编辑一个学生信息
一般像4中那些方法都不写的,能简单就简单,除非要自定义写sql语句,否则不在这一层写那么重复的代码
2)数据业务层(service)
目录结构:
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

根据面向接口编程的原则,我们这里写了一个接口和一个实现类
这一层我们主要用来写主要的业务逻辑代码,相当于action
1、接口StuService
package com.fjh.bigproduct.service; import com.fjh.bigproduct.model.dto.StuDto; import com.fjh.bigproduct.model.entity.Stu; import java.util.List; /** *@autho antg *@Description 学生管理 *@date 2020-08-17 17:30 */public interface StuService { //查找所有未删除学生 List> findAllStu(); //删除某一学生 void delStu(int id); //保存或者编辑一个学生(id不为空则编辑,id为空则新增) void saveStu(StuDto stuDto); //根据学生id查找学生 Stu findStu(int id); }

规定了接口后,我们可以更加直观来展现实现类,也方便了编程
2、实现类StuServiceImpl
package com.fjh.bigproduct.service; import com.fjh.bigproduct.model.dto.StuDto; import com.fjh.bigproduct.model.entity.Stu; import com.fjh.bigproduct.repository.StuRepository; import com.fjh.bigproduct.util.DateUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.ArrayList; import java.util.Date; import java.util.List; /** *@autho antg *@Description 学生管理实现类 *@date 2020-08-17 17:44 */@Service //标注这是一个服务层,并在spring扫描的时候加入到bean中 public class StuServiceImpl implements StuService{ //引入数据访问层 @Autowired private StuRepository stuRepository; //查询所有未删除的学生 @Override public List> findAllStu(){ try{ return stuRepository.findAll(); }catch (Exception e){ e.printStackTrace(); return null; } }//根据id查找学生 @Override public Stu findStu(int id) { try { return stuRepository.findStuById(id); } catch (Exception e) { e.printStackTrace(); return null; } }//根据id删除某一个学生 @Override @Transactional //加上这个注解后不用保存就可以直接更新 public void delStu(int id) { try { Stu stu = stuRepository.findStuById(id); stu.setDelState(1); stu.setDelTime(new Date()); //这里没有保存,但是执行了方法后数据库就直接跟新了 } catch (Exception e) {e.printStackTrace(); } }//保存或者编辑一个学生(id不为空则编辑,id为空则新增) @Override public void saveStu(StuDto stuDto) { try { Stu stu = new Stu(); //新增 if(stuDto.getId() == 0){ stu.setStuName(stuDto.getStuName()); stu.setGender(stuDto.getGender()); stu.setStuNo(stuDto.getStuNo()); stu.setStuClass(stuDto.getStuClass()); stu.setStuAddress(stuDto.getStuAddress()); stu.setStuBirthday(DateUtil.parseString2Date(stuDto.getStuBirthday())); stu.setCreatTime(new Date()); stu.setDelState(0); stuRepository.save(stu); //下面可以加操作日志 //mycode //编辑 }else { stu.setId(stuDto.getId()); stu.setStuName(stuDto.getStuName()); stu.setGender(stuDto.getGender()); stu.setStuNo(stuDto.getStuNo()); stu.setStuClass(stuDto.getStuClass()); stu.setStuAddress(stuDto.getStuAddress()); stu.setStuBirthday(DateUtil.parseString2Date(stuDto.getStuBirthday())); stu.setCreatTime(new Date()); stu.setDelState(0); stuRepository.save(stu); } } catch (Exception e) { e.printStackTrace(); } } }

总结一下服务层实现的步骤
1、引入注解@Service
2、引入数据访问层并加上注解@Autowired,
//引入数据访问层 @Autowired private StuRepository stuRepository; //引入了之后就可以用stuRepository调用数据访问层的方法了

@Autowired注解可以对类成员变量、方法、构造函数进行标注,完成自动装配工作,通过@Autowried自动装配,可以实现从IoC容器中去查找bean中存储的对象,并返回。
3、实现接口的方法
里面使用了jpa提供的save方法,这个方法可以同时用在编辑和保存上,如果save的对象的id在数据库中存在,那么就更新,如果不存在就新增
这里的删除方法还使用了一个小技巧,@Transactional
这个注解可以实现不用save就可以自动更新
//根据id删除某一个学生 @Override @Transactional //加上这个注解后不用保存九可以直接更新 public void delStu(int id) { try { Stu stu = stuRepository.findStuById(id); stu.setDelState(1); stu.setDelTime(new Date()); //这里只用了set方法就可以直接将数据库中的值更新 } catch (Exception e) {e.printStackTrace(); } }

3)前台控制器(controller)
package com.fjh.bigproduct.controller; import com.fjh.bigproduct.model.dto.StuDto; import com.fjh.bigproduct.model.entity.Stu; import com.fjh.bigproduct.service.StuServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; /** *@autho antg *@Description 前台控制器 *@date 2020-08-19 10:16 */ @RestController @RequestMapping("/stu") @ResponseBody public class StuController { //这里加上final可以理解为单例模式,优化程序 private final StuServiceImpl stuService; //为stuService赋初始值 @Autowired public StuController(StuServiceImpl stuService) { this.stuService = stuService; }//显示学生列表 @GetMapping("/findAllStu") public List> findAllStu(){ try { List> list = stuService.findAllStu(); return list; } catch (Exception e) { e.printStackTrace(); return null; } }//根据id查询学生 @GetMapping("/findStu") public Stu findStu(int id){ try { return stuService.findStu(id); } catch (Exception e) { e.printStackTrace(); return null; } }//添加学生; 编辑学生 @PostMapping("/saveStu") public void addStu(@RequestBody StuDto stuDto){ stuService.saveStu(stuDto); }//删除学生 @GetMapping("/delStu") public void delStu(@RequestParam int id){ stuService.delStu(id); } }

这个前台控制器相当于以前的xml,主要为页面提供访问接口
1、注解
@RestController
这个controller注解可以返回一些对象,为前台提供数据,这个注解还有一个兄弟,叫做@Controller,这个注解返回值是一个页面路径,表示要展示的页面或者跳转到另外一个请求
@RequestMapping("/stu")
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径,这个注解可有可无,不过加在方法上的Mapping必须要有
地址/stu/方法Mapping

@ResponseBody
这个注解可以将后台返回的数据以json格式返回,否则返回的是一个Object对象,加在类上,该类的所有方法都会将数据以json格式返回
2、调用数据服务层StuServiceImpl
//这里加上final可以理解为单例模式,优化程序 private final StuServiceImpl stuService; //为stuService赋初始值 @Autowired public StuController(StuServiceImpl stuService) { this.stuService = stuService; }

3、向前台传值
//显示学生列表 @GetMapping("/findAllStu") public List> findAllStu(){ try { List> list = stuService.findAllStu(); return list; } catch (Exception e) { e.printStackTrace(); return null; } }

这是一个显示学生列表的方法,前台使用get方法调接口/stu/findAllStu就可以获取rturn的值,这个值将以json的数据格式发送到前台(因为在使用了注解@@ResponseBody)
4、获取参数
(1)获取get请求中的参数
//删除学生 @GetMapping("/delStu") public void delStu(@RequestParam int id){ stuService.delStu(id); }

这里使用了@RequestParam注解, 后面的参数类型名称要和前台传的要一致
(2)获取json对象
//添加学生; 编辑学生 @PostMapping("/saveStu") public void addStu(@RequestBody StuDto stuDto){ stuService.saveStu(stuDto); }

这里使用了@RequestBody来获取参数 后面跟上一个dto对象用来封装前台的json对象,一般前台提交json对象都用POST方法来响应
spring|springboot简单小项目练习之增删改查-exercisePro01
文章图片

这里的dto一般就是用来封装前台传来的json对象
dto源码:
package com.fjh.bigproduct.model.dto; import java.util.Date; /** *@autho antg *@Description 封装stu对象 *@date 2020-08-20 08:44 */public class StuDto {private int id; private String stuNo; private String stuBirthday; private String stuAddress; private String stuClass; private int gender; private String stuName; public int getId() { return id; }public void setId(int id) { this.id = id; }public String getStuNo() { return stuNo; }public void setStuNo(String stuNo) { this.stuNo = stuNo; }public String getStuBirthday() { return stuBirthday; }public void setStuBirthday(String stuBirthday) { this.stuBirthday = stuBirthday; }public String getStuAddress() { return stuAddress; }public void setStuAddress(String stuAddress) { this.stuAddress = stuAddress; }public String getStuClass() { return stuClass; }public void setStuClass(String stuClass) { this.stuClass = stuClass; }public int getGender() { return gender; }public void setGender(int gender) { this.gender = gender; }public String getStuName() { return stuName; }public void setStuName(String stuName) { this.stuName = stuName; } }

    推荐阅读