在SpringBoot 中使用 Mybatis ,并完成以下操作:
◼ 创建 一个SpringBoot 项目,项目名 ” week11_
学号 ” ;
◼ 使用 Mybatis 框架 ,也可以用MyBatisPlus 框架 ;
◼ 访问 myschool 数据库;
◼ 对student 表进行操作,向 student 插入自己的一条记录, 自行设计完成CRUD操作;
◼ 创建相应的Pojo层、Mapper层、Service 层、 Controller层;
◼ 在各层中,创建针对student 表操作的类或接口;
◼对studentController 设置一级和二级对外访问虚拟路径;
◼ 启动服务器, 测试控制器中的方法,直接将CRUD操作结果在后台打印出来;
◼ 将运行结果截图,保存在word 文档中
该注解加在类成员变量上,表示让 Spring 完成 Bean 自动装配(对象注入)的工作。

该注解用于service实现类上,标记当前类是一个Service类,同时该类会被Spring框架管理
@Controller+@ResponseBody 的组合注解
作用:修饰类,一个类被它修饰,就成了控制器类(@Controller),只返回给用户数据,默认将返回的对象数据转换为 json 格式(@ResponseBody);
@GetMapping,@PostMapping 等,来代替 @RequestMapping 注解
如@PostMapping(value = "/updateStudentByDynam")相当于
@RequestMapping(value = "/updateStudentByDynam",method =RequestMethod.POST)
该注解主要用来接收前端传递给后端的 json 字符串中的数据(请求体中的数据的)。一般用来处理“application/json”“application/xml”等类型的数据,使用@RequestBody 接收数据时,一般都用 POST 方式进行提交。
作用:处理动态URL,URL的值可以作为控制器中处理方法的参数,主要用于RestFul风格中

SpringMVC 中,页面可以向控制器传递以下多种类型的参数:
Spring MVC 中,控制器可以向页面:
接口调试工具有很多种,功能上基本相同,具体的选择看个人喜好
我在测试时用的是Apipost(官网链接:https://www.apipost.cn/)在官网下载解压安装后就可直接使用
对于一个API来说,输入的请求(Request)包括 URL、method、Request Cookies、Request Headers和Request Body;收到请求后,API会回复响应(Response),包括Response Headers和Response Body。接口测试工具可以很好的 模拟浏览器并向API发送Request请求,同时可以接收API发回的Response响应。接口测试工具能覆盖绝大多数HTTP接口测试场景,方便开发人员在开发过程中去调试接口。
测试接口时,需要选择请求方法,填入URL地址等,具体见下图:






具体的接口测试设计及运行结果在运行结果
如果没有安装过Lombok插件的话需要现在IDEA中安装该插件:

Lombok 是一种 Java 常用工具,可以使它来简化实体类的代码。它通过注解来自动生成属性的get,set和构造方法,具体如下图所示。

打开File–New–Project
如图进行对应设置:

注意这里的Server URL默认为start.spring.io,如果这个用不了的话可以尝试点击右边的齿轮修改为https://start.springboot.io
点击next后在该页面选择如图所示的依赖进行添加:


关于mapper文件的配置上如果有问题的话,在项目运行时可能会报类似Invalid bound statement (not found): com.example.mapper.....的错误
解决方法:
1、检查springboot的…application.java中是否有加@MapperScan(basePackages = "com.example.mapper")注解

2、检查…Mapper.java文件是否有@Mapper注解

3、检查配置文件(application.yml)中是否有
mybatis:
mapper-locations: classpath:com/exmaple/mapper/*.xml #指定sql配置文件的位置

4、检查pom.xml文件中
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**.*include>
includes>
resource>
resources>

如:

可使用这两种方法:
1、在url中直接传参:localhost:8080/student/getStudentById?id=3

2、url为localhost:8080/student/getStudentById,在form-data中设置id ,3

如:

使用json格式数据传参:
如:
{
"sname": "test0",
"dept": "test666",
"age":0
}

如:

也是使用json格式数据传参

如:

要使用如下格式:

注意最外边是中括号[ ]
[
{
"sname": "testBatch1",
"dept": "testBatch1",
"age":6
},
{
"sname": "testBatch2",
"dept": "testBatch2",
"age":7
}
]
如:

1、若不加@RequestBody的话需要使用form-data提交

2、若加上@RequestBody的话需要使用raw中写数字提交(啥括号都不用,只用一个数字)

如:

使用如下格式:


实现User相关的类和接口和Student相关的类和接口类似就不贴了
使用了lombok插件简化代码
package com.example.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @projectName: week11_xxx
* @package: com.example.pojo
* @className: Student
* @author: GCT
* @description: TODO
* @date: 2022/11/8 21:02
* @version: 1.0
*/
@Data /*自动生成 set get toString方法*/
@NoArgsConstructor //自动生成无参构造函数
@AllArgsConstructor
public class Student {
Long id;
String sname;
String dept;
int age;
}
interface类型文件
package com.example.mapper;
import com.example.pojo.Student;
import com.example.pojo.User;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;
/**
* @projectName: week11_20201003016
* @package: com.example.mapper
* @className: StudentMapper
* @author: GCT
* @description: TODO
* @date: 2022/11/8 21:03
* @version: 1.0
*/
@Mapper
public interface StudentMapper {
// 直接使用@Select()注解
// @Select("SELECT * FROM users")
// public List getAllUserMap();
// 使用SQL配置文件
public List<Student> getAllStudentMap();
public Student getStudentById(Long id);
@MapKey("id") //这个不加也行 虽然IDEA可能会标红线,但运行时不会出错
public Map<Object,Object> getStudentByMulCondition(Map<Object,Object> mp);
@MapKey("id") //这个不加也行 虽然IDEA可能会标红线,但运行时不会出错
public Map<Object,Object> getStudentByDynam(Map<Object,Object> mp);
// 该方法插入一条记录,带参数,更新操作一定要提交事务
public int addStudent(Student student);
public int addStudentBatch(List<Student> student);
public int updateStudentByDynam(Map<Object,Object> mp);
// 根据id删除记录
public int deleteStudentById(Long id);
// 根据多个id删除多条记录
public int deleteStudentByIds(Long[] ids);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.StudentMapper">
<select id="getAllStudentMap" resultType="Student">
SELECT * FROM student
select>
<select id="getStudentById" resultType="Student" parameterType="Long">
SELECT * FROM student WHERE id=#{0}
select>
<select id="getStudentByMulCondition" resultType="map" parameterType="Map">
SELECT * FROM student WHERE sname='${sname}' AND dept='${dept}' AND age='${age}'
select>
<select id="getStudentByDynam" resultType="Map" parameterType="Map">
SELECT * FROM student
<where>
<if test="sname!=null">
sname=#{sname}
if>
<if test="dept!=null">
and dept=#{dept}
if>
<if test="age!=null">
and age=#{age}
if>
where>
select>
<insert id="addStudent" parameterType="Student">
INSERT INTO student SET sname=#{sname},dept=#{dept},age=#{age}
insert>
<insert id="addStudentBatch" parameterType="Student">
insert into
student(sname,dept,age)
values
<foreach collection="list" item="student" separator=",">
(#{student.sname},#{student.dept},#{student.age})
foreach>
insert>
<update id="updateStudentByDynam" parameterType="Map">
update student
<set>
<if test="sname!=null">
sname=#{sname},
if>
<if test="dept!=null">
dept=#{dept},
if>
<if test="age!=null">
age=#{age},
if>
id=#{id}
set>
where id=#{id}
update>
<delete id="deleteStudentById" parameterType="Long">
DELETE FROM student WHERE id=#{id}
delete>
<delete id="deleteStudentByIds" parameterType="Long[]" >
DELETE FROM student WHERE id IN
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
foreach>
delete>
mapper>
interface类型文件
package com.example.service;
import com.example.pojo.Student;
import org.apache.ibatis.annotations.MapKey;
import java.util.List;
import java.util.Map;
public interface StudentService {
public List<Student> getAllStudentMap();
public Student getStudentById(Long id);
public Map<Object,Object> getStudentByMulCondition(Map<Object,Object> mp);
public Map<Object,Object> getStudentByDynam(Map<Object,Object> mp);
// 该方法插入一条记录,带参数,更新操作一定要提交事务
public int addStudent(Student student);
public int addStudentBatch(List<Student> sudent);
public int updateStudentByDynam(Map<Object,Object> mp);
// 根据id删除记录
public int deleteStudentById(Long id);
// 根据多个id删除多条记录
public int deleteStudentByIds(Long[] ids);
}
package com.example.service.impl;
import com.example.mapper.StudentMapper;
import com.example.pojo.Student;
import com.example.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @projectName: week11_xxx
* @package: com.example.service.impl
* @className: StudentServiceImpl
* @author: GCT
* @description: TODO
* @date: 2022/11/8 21:03
* @version: 1.0
*/
@Service //注意记得加@Service注解 :把这个类交给sping框架管理(bean),不然在controller中@Autowire会找不到该类!
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> getAllStudentMap() {
return studentMapper.getAllStudentMap();
}
@Override
public Student getStudentById(Long id) {
return studentMapper.getStudentById(id);
}
@Override
public Map<Object, Object> getStudentByMulCondition(Map<Object, Object> mp) {
return studentMapper.getStudentByMulCondition(mp);
}
@Override
public Map<Object, Object> getStudentByDynam(Map<Object, Object> mp) {
return studentMapper.getStudentByDynam(mp);
}
@Override
public int addStudent(Student student) {
return studentMapper.addStudent(student);
}
@Override
public int addStudentBatch(List<Student> student) {
return studentMapper.addStudentBatch(student);
}
@Override
public int updateStudentByDynam(Map<Object, Object> mp) {
return studentMapper.updateStudentByDynam(mp);
}
@Override
public int deleteStudentById(Long id) {
return studentMapper.deleteStudentById(id);
}
@Override
public int deleteStudentByIds(Long[] ids) {
return studentMapper.deleteStudentByIds(ids);
}
}
package com.example.controller;
import com.example.pojo.Student;
import com.example.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @projectName: week11_xxx
* @package: com.example.controller
* @className: StudentController
* @author: GCT
* @description: TODO
* @date: 2022/11/8 21:02
* @version: 1.0
*/
@RestController //=@ResponseBody+@Controller
@RequestMapping(value = "/student")
public class StudentController {
@Autowired
private StudentService studentService;
//1.Get请求,直接向页面返回json数据
// 查找所有学生信息
@RequestMapping(value = "/getAllStudent",method = RequestMethod.GET)
public List<Student> getAllStudent(){
// localhost:8080/student/getAllStudent
List<Student> studentList = studentService.getAllStudentMap();
System.out.println("test");
return studentList;
}
//根据学生id查找对应学生信息
@RequestMapping(value = "/getStudentById",method =RequestMethod.GET)
public Student getStudentById(Long id){
// localhost:8080/student/getStudentById?id=3
// 或者localhost:8080/student/getStudentById 在form-data中设置id 3
Student studentById = studentService.getStudentById(id);
System.out.println(studentById);
return studentById;
}
//根据传入参数返回符合对应条件的学生信息
@RequestMapping(value = "/getStudentByMulCondition",method =RequestMethod.POST)
@ResponseBody
public Map<Object,Object> getStudentByMulCondition(@RequestBody Map<Object,Object> mp){
// 需要在传入的参数前面加上@RequestBody将传入的json数据封装成对应的Map类型数据
// @RequestBody 用在方法参数上面,用来将请求参数绑定到request body中,
// 通过HttpMessageConverter封装为具体的JavaBean。
// 通俗点讲就是你在一个参数上加上该注解,spring就会将request body中的json/xml对象解析成该参数类型的Javabean对象。
System.out.println("mp:");
System.out.println(mp);
Map<Object, Object> studentByMulCondition = studentService.getStudentByMulCondition(mp);
System.out.println(studentByMulCondition);
// Could not write JSON: java.lang.Long cannot be cast to java.lang.String; nested exception is com...报错解决:
// 原来使用的是Map,但id为long类型,所以会报错,解决方法:将String类型改为Object类型!!!
return studentByMulCondition;
}
// 根据传入的不定数量的数个参数返回符合条件的学生信息
@RequestMapping(value = "/getStudentByDynam",method =RequestMethod.POST)
public Map<Object,Object> getStudentByDynam(@RequestBody Map<Object,Object> mp){
// 注意这里也要加@RequestBody来将传入的json数据封装成Map类型
// 注意sql语句中and的处理
System.out.println("mp: ");
System.out.println(mp);
Map<Object, Object> studentByDynam = studentService.getStudentByDynam(mp);
System.out.println(studentByDynam);
return studentByDynam;
}
// 往数据库中新增学生信息(处理页面表单中提交的数据)
//2.POST请求,处理页面表单中提交的数据,向数据库增加数据
@RequestMapping(value = "/addStudent_1",method = RequestMethod.POST)
public int addStudent_1(Student student) {
//将页面表单传过来的参数自动封装成student对象,然后存入数据库
// localhost:8080/student/addStudent_1
// {
// "sname":"tsetJson",
// "dept":"testJson",
// "age":2
// }
// 或者使用form-data模拟表单提交
System.out.print(student);
int num=studentService.addStudent(student);
// Long id = student.getId();
// System.out.println(id);
System.out.println(num);
return num;
}
//往数据库中新增学生信息(处理页面使用ajax提交的json数据)
//3.使用@RequestBody,处理页面使用ajax提交的json数据,向数据库增加数据
// 这种方法在接口测试时需要使用原始json格式数据进行测试,使用表单形式数据会报错
@RequestMapping(value = "/addStudent_2")
public int addStudent_2(@RequestBody Student student) {
//将页面传过来的参数自动封装成student对象,然后存入数据库
System.out.print(student);
int num=studentService.addStudent(student);
// Long id = student.getId();
// System.out.println(id);
System.out.println(num);
return num;
}
//批量向数据库中新增学生信息
@RequestMapping(value = "/addStudentBatch",method =RequestMethod.POST)
public int addStudentBatch(@RequestBody List<Student> student){
// 注意要传入list类型的json数据:
// [
// {
// },
// {
// }
// ]
// 传入后会自动封装为List类型
System.out.println("student: ");
System.out.println(student);
int row = studentService.addStudentBatch(student);
System.out.println(row);
return row;
}
//根据传入不定数量的参数更新对应学生的对应信息
@RequestMapping(value = "/updateStudentByDynam",method =RequestMethod.POST)
public int updateStudentByDynam(@RequestBody Map<Object,Object> mp){
// 注意这里也要加@RequestBody来将传入的json数据封装成Map类型
System.out.println("mp: ");
System.out.println(mp);
int row = studentService.updateStudentByDynam(mp);
System.out.println(row);
return row;
}
// 根据id删除学生记录
@RequestMapping(value = "/deleteStudentById",method =RequestMethod.POST)
// public int deleteStudentById(@RequestBody Long id){
public int deleteStudentById(Long id){
// 不加@RequestBody的话需要使用form-data提交
// 加上@RequestBody的话需要使用raw中写数字提交(啥括号都不用,只用一个数字)
System.out.println("id: "+id);
return studentService.deleteStudentById(id);
}
// 根据多个id删除多条学生记录
@RequestMapping(value = "/deleteStudentByIds",method =RequestMethod.POST)
public int deleteStudentByIds(@RequestBody Long[] ids){
// 这里也要加@RequestBody将传入的数据封装成Long[]类型
// []
System.out.println(Arrays.toString(ids));
return studentService.deleteStudentByIds(ids);
}
}
package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//别忘了加这个注解扫描mapper层中的所有类,不然会找不到对应的mapper文件
@MapperScan(basePackages = "com.example.mapper")
public class Week1120201003016Application {
public static void main(String[] args) {
SpringApplication.run(Week1120201003016Application.class, args);
}
}
这里面只用到了application.yml这一个配置文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/myschool?serverTimezone=Hongkong?characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: 你的密码
mybatis:
mapper-locations: classpath:com/exmaple/mapper/*.xml #指定sql配置文件的位置
type-aliases-package: com.example.pojo #指定实体类所在的包名
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #输出SQL命令
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.5version>
<relativePath/>
parent>
<groupId>com.examplegroupId>
<artifactId>week11_xxxartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>week11_xxxname>
<description>week11_xxxdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.2.2version>
dependency>
<dependency>
<groupId>com.mysqlgroupId>
<artifactId>mysql-connector-jartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**.*include>
includes>
resource>
resources>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
project>
查找所有学生信息


根据学生id查找对应学生信息


根据传入参数返回符合对应条件的学生信息


== 根据传入的不定数量的数个参数返回符合条件的学生信息==


往数据库中新增学生信息(处理页面表单中提交的数据)



往数据库中新增学生信息(处理页面使用ajax提交的json数据)



批量向数据库中新增学生信息



据传入不定数量的参数更新对应学生的对应信息


更新前:

更新后:

根据id删除学生记录


删除前:

删除后:

根据多个id删除多条学生记录


删除前:

删除后:
