项目描述:用Vscode创建Spring Boot+mybatis项目,用maven进行管理。创建一个User表,对其内容进行表的基本操作(增删改查),显示在前端。
项目地址:戳我一键下载项目
运行效果如下:
项目目录:
核心代码讲解:
1.UserController.java
package improv1.improv1;
import improv1.improv1.MybatisConnect.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
// 新增用户
@PostMapping("/add")
public Map<String, Object> addUser(@RequestParam String name, @RequestParam String email) {
Map<String, Object> result = new HashMap<>();
if (name == null || email == null) {
result.put("error", "参数不足,需提供 name 和 email");
return result;
}
try (SqlSession session = MyBatisUtil.getSqlSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
Map<String, Object> params = new HashMap<>();
params.put("name", name);
params.put("email", email);
params.put("createTime", LocalDateTime.now());
int rows = mapper.insertUser(params);
session.commit();
result.put("message", "新增成功");
result.put("rows", rows);
result.put("id", params.get("id"));
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
// 查询所有用户
@GetMapping("/list")
public List<Map<String, Object>> getAllUsers() {
try (SqlSession session = MyBatisUtil.getSqlSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
return mapper.getAllUsers();
}
}
// 更新用户
@PostMapping("/update")
public Map<String, Object> updateUser(
@RequestParam Integer id,
@RequestParam String name,
@RequestParam String email) {
Map<String, Object> result = new HashMap<>();
if (id == null || name == null || email == null) {
result.put("error", "参数不足,需提供 id、name、email");
return result;
}
try (SqlSession session = MyBatisUtil.getSqlSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
Map<String, Object> params = new HashMap<>();
params.put("id", id);
params.put("name", name);
params.put("email", email);
int rows = mapper.updateUser(params);
session.commit();
result.put("message", "更新成功");
result.put("rows", rows);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
// 删除用户
@PostMapping("/delete")
public Map<String, Object> deleteUser(@RequestParam Integer id) {
Map<String, Object> result = new HashMap<>();
if (id == null) {
result.put("error", "请提供要删除的用户ID");
return result;
}
try (SqlSession session = MyBatisUtil.getSqlSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
int rows = mapper.deleteUser(id);
session.commit();
result.put("message", "删除成功");
result.put("rows", rows);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
}
解析:
操作数据库表一般把对一张表的操作写在一个文件里。
Spring Boot项目把文件写成controller,默认会部署到tomcat,可以通过htttp://localhost:8080/映射地址来访问。这里的映射地址是由前缀+映射子地址组成的,在这里若要查询表映射地址为/user/list。若要删除表,完整的地址是htttp://localhost:8080/user/delete剩下的以此类推。
2.mybatis框架应用部分
如果要在spring Boot项目里用mybatis框架管理表,首先,要在resources目录下建立mapper文件夹,在里面编写,数据库表对应的mapper.xml文件。可以在resouces根目录下编写mybatis-config.xml文件。
当然,最好不要编写mybatis-config文件,我这里因为用了MybatisUtil手动连接数据库了所以要写mybatis-config.xml文件。在application.properties里填写相关数据库信息进行统一管理比较好。接着,在pom.xml文件里加入Spring Boot和mybatis以及数据库相关依赖。
最后,在项目里编写mapper.xml对应的操作数据库表接口文件,对表进行操作。
一般要添加的pom.xml内容如下:
<!-- Spring boot配置mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
<!-- 配置mysql数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 配置spring boot-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
1)UserMapper.xml
<?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">
<mapper namespace="improv1.improv1.UserMapper">
<!-- 插入用户 -->
<insert id="insertUser" parameterType="map">
INSERT INTO user(name, email, create_time)
VALUES(#{name}, #{email}, #{createTime})
</insert>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
<!-- 更新用户 -->
<update id="updateUser" parameterType="map">
UPDATE user SET
name = #{name},
email = #{email}
WHERE id = #{id}
</update>
<!-- 查询所有用户 -->
<select id="getAllUsers" resultType="map">
SELECT id, name, email, create_time as createTime
FROM user
</select>
</mapper>
解析:
其中INSERT INTO user(name, email, create_time)
VALUES(#{name}, #{email}, #{createTime})这里的user(属性)和values(#{属性}),要保持一致。id与mapper.xml对应的操作类方法名对应一致
2)UserMapper.java
package improv1.improv1;
import java.util.List;
import java.util.Map;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.SpringBootApplication;
public interface UserMapper {
// 使用Map作为参数
int insertUser(Map<String, Object> params);
int deleteUser(int id);
int updateUser(Map<String, Object> params);
List<Map<String, Object>> getAllUsers();
}
解析:
1.这里的MapperScan的作用是用于自动扫描和注册 MyBatis 的 Mapper 接口。如果不配置,可能就会报错找不到mapper。
2.这里的getAllUsers返回的结果要进行接受显示,所以我们把返回类型用List数组来接收,每一个元素都是键值对的形式对应数据库表里的每一行数据。
3)application.properties
spring.application.name=improv1
# 数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/mybaitistest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis 配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=improv1.improv1 # 你的实体类包名
mybatis.configuration.log-impl=org.apache.ibatis.logging.slf4j.Slf4jImpl
解析:
mybatis.type-aliases-package=improv1.improv1 这里配置的就是操作数据库表的类所在包的位置。
3.CorsConfig.java
package improv1.improv1;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
}
解析:
这段代码是一个Spring Boot的CORS(跨域资源共享)配置类,用于全局配置跨域请求。主要功能包括:
- 允许所有路径(
/**
)的跨域请求- 允许所有来源(
allowedOriginPatterns("*")
)- 允许所有HTTP方法(
allowedMethods("*")
)- 允许所有请求头(
allowedHeaders("*")
)- 允许携带凭证(
allowCredentials(true)
)如果不写,就可能会引发浏览器访问受阻,访问失败报200错误。其实这些配置也可以写在application.properties里面,但是这样这种方式只适用于简单场景,且部分老版本 Spring Boot 可能不支持。如果你需要更细粒度的控制(如只允许部分接口、部分域名),还是建议使用 Java 配置类。
思考题
如果我要增加一张Admin管理员表(Account,Password,Name)怎么办?在原来上面的代码中应该怎么改?
我不手动连接数据库,采用SpringBoot自动连接数据库的方式实现一下,供大家参考学习。
下面是不手动连接数据库,采用SpringBoot自动注入的方式来加载操作数据库,其中关键是使用@Autowierd注解。
目录结构如下
删除手动连接的MyBatisUtil.java后,要修改controller.java,采用spring boot自动连接方式。这样也就不需要mybatis-config.xml文件了。
增改代码如下:
1.UserController.java
package improv1.improv1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
// 新增用户
@PostMapping("/add")
public Map<String, Object> addUser(@RequestParam String name, @RequestParam String email) {
Map<String, Object> result = new HashMap<>();
if (name == null || email == null) {
result.put("error", "参数不足,需提供 name 和 email");
return result;
}
try {
Map<String, Object> params = new HashMap<>();
params.put("name", name);
params.put("email", email);
params.put("createTime", LocalDateTime.now());
int rows = userMapper.insertUser(params);
result.put("message", "新增成功");
result.put("rows", rows);
result.put("id", params.get("id"));
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
// 查询所有用户
@GetMapping("/list")
public List<Map<String, Object>> getAllUsers() {
return userMapper.getAllUsers();
}
// 更新用户
@PostMapping("/update")
public Map<String, Object> updateUser(
@RequestParam Integer id,
@RequestParam String name,
@RequestParam String email) {
Map<String, Object> result = new HashMap<>();
if (id == null || name == null || email == null) {
result.put("error", "参数不足,需提供 id、name、email");
return result;
}
try {
Map<String, Object> params = new HashMap<>();
params.put("id", id);
params.put("name", name);
params.put("email", email);
int rows = userMapper.updateUser(params);
result.put("message", "更新成功");
result.put("rows", rows);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
// 删除用户
@PostMapping("/delete")
public Map<String, Object> deleteUser(@RequestParam Integer id) {
Map<String, Object> result = new HashMap<>();
if (id == null) {
result.put("error", "请提供要删除的用户ID");
return result;
}
try {
int rows = userMapper.deleteUser(id);
result.put("message", "删除成功");
result.put("rows", rows);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
}
解析:
采用@Autowierd注解来创建mapper对象,调用对象的方法。这样就可以避免自己写一个连接类手动连接数据库了。
2.AdminController.java
package improv1.improv1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin")
public class AdminController {
@Autowired
private AdminMapper adminMapper;
// 新增管理员
@PostMapping("/add")
public Map<String, Object> addUser(@RequestParam String Account, @RequestParam String PassWord,@RequestParam String Name) {
Map<String, Object> result = new HashMap<>();
if (Account== null || PassWord == null ||Name==null) {
result.put("error", "参数不足,需提供 account,password 和 name");
return result;
}
try{
Map<String, Object> params = new HashMap<>();
params.put("Account", Account);
params.put("PassWord", PassWord);
params.put("Name", Name);
int rows = adminMapper.insertAdmin(params);
result.put("message", "新增成功");
result.put("rows", rows);
result.put("id", params.get("id"));
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
// 查询所有管理员
@GetMapping("/list")
public List<Map<String, Object>> getAllAdmins() {
return adminMapper.getAllAdmins();
}
// 更新管理员
@PostMapping("/update")
public Map<String, Object> updateUser(
@RequestParam String Account,
@RequestParam String PassWord,
@RequestParam String Name) {
Map<String, Object> result = new HashMap<>();
if (Account== null || PassWord == null || Name== null) {
result.put("error", "参数不足,需提供 Account、Password、Name");
return result;
}
try{
Map<String, Object> params = new HashMap<>();
params.put("Account", Account);
params.put("PassWord", PassWord);
params.put("Name", Name);
int rows = adminMapper.updateAdmin(params);
result.put("message", "更新成功");
result.put("rows", rows);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
// 删除用户
@PostMapping("/delete")
public Map<String, Object> deleteUser(@RequestParam String Account) {
Map<String, Object> result = new HashMap<>();
if (Account == null) {
result.put("error", "请提供要删除的用户ID");
return result;
}
try {
int rows = adminMapper.deleteAdmin(Account);
result.put("message", "删除成功");
result.put("rows", rows);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
}
3.AdminMapper.java
package improv1.improv1;
import java.util.List;
import java.util.Map;
public interface AdminMapper{
// 使用Map作为参数
int insertAdmin(Map<String, Object> params);
int deleteAdmin(String Account);
int updateAdmin(Map<String, Object> params);
List<Map<String, Object>> getAllAdmins();
}
4.AdminMapper.xml
<?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">
<mapper namespace="improv1.improv1.AdminMapper">
<!-- 插入管理员 -->
<insert id="insertAdmin" parameterType="map">
INSERT INTO admin(Account, Password, Name)
VALUES(#{Account}, #{Password}, #{Name})
</insert>
<!-- 删除管理员 -->
<delete id="deleteAdmin" parameterType="String">
DELETE FROM admin WHERE Account = #{Account}
</delete>
<!-- 更新管理员 -->
<update id="updateAdmin" parameterType="map">
UPDATE admin SET
Name = #{Name},
Password = #{Password}
WHERE Account = #{Account}
</update>
<!-- 查询所有管理员 -->
<select id="getAllAdmins" resultType="map">
SELECT Account, Password, Name
FROM admin
</select>
</mapper>
扩展:
1.postMapper和getMapper的区别
定义与用途 postMapper通常指代处理HTTP POST请求的映射器,用于接收客户端提交的数据(如表单、JSON等),适用于数据修改或新增操作。getMapper则对应HTTP GET请求的映射器,用于获取资源,适合数据查询场景。
数据传递方式 postMapper通过请求体(body)传输数据,数据在HTTP包体中,适合传输大量或敏感信息。getMapper通过URL参数传递数据,数据附加在URL后,长度受限且可见。
安全性 postMapper相对更安全,数据不直接暴露在URL中,适合密码等敏感信息。getMapper参数明文显示在URL,可能被日志或浏览器历史记录留存。
幂等性 getMapper具有幂等性,多次执行同一请求不会改变资源状态。postMapper通常是非幂等的,重复提交可能导致多次资源变更。
2.@RequestMapping("/user")是什么怎么用
@RequestMapping("/user")是什么怎么用
作用与含义
- 路径映射:将特定 URL 路径(如
/user
)与控制器(Controller)类或方法绑定。 - 请求处理:当客户端请求匹配该路径时,Spring 会调用对应的控制器方法处理请求。
使用方法
类级别注解
标注在控制器类上,定义该控制器所有方法的公共路径前缀:
@Controller
@RequestMapping("/user")
public class UserController {
// 方法实际路径为 /user/profile
@RequestMapping("/profile")
public String profile() {
return "profile";
}
}
方法级别注解
标注在具体方法上,定义独立路径:
@Controller
public class UserController {
// 直接响应 /login 路径
@RequestMapping("/login")
public String login() {
return "login";
}
}
组合使用
类注解定义前缀,方法注解补充子路径:
@RestController
@RequestMapping("/api/user")
public class UserApiController {
// 完整路径为 /api/user/info
@GetMapping("/info")
public UserInfo getInfo() {
return userService.getInfo();
}
}
支持的属性
可通过额外属性进一步定义请求匹配规则:
@RequestMapping(
value = "/create",
method = RequestMethod.POST,
consumes = "application/json",
produces = "application/json"
)
常见派生注解
@GetMapping
:等价于@RequestMapping(method = RequestMethod.GET)
@PostMapping
:等价于@RequestMapping(method = RequestMethod.POST)
@PutMapping
/@DeleteMapping
等同理
该注解是 Spring Web 开发的核心配置方式,合理使用可实现清晰的 URL 路由结构。
3.mapper.xml中的id是怎么用的
id 的作用
在 MyBatis 的映射文件(XML 文件)中,id
是 <insert>
标签的一个属性,用于唯一标识该 SQL 语句。id
的主要作用是让 MyBatis 能够通过它找到对应的 SQL 语句并执行。
id 的用途
id
与 Mapper 接口中的方法名一一对应。例如,如果 Mapper 接口中有一个方法名为 insertUser
,那么在映射文件中,<insert>
标签的 id
也必须是 insertUser
,这样才能正确关联接口方法与 SQL 语句。
使用方法
定义 Mapper 接口
在 Mapper 接口中声明一个方法,方法名与映射文件中的id
一致。public interface UserMapper { int insertUser(User user); }
在映射文件中配置 SQL
映射文件中的<insert>
标签的id
必须与接口方法名相同。<insert id="insertUser" parameterType="map"> INSERT INTO user(name, email, create_time) VALUES(#{name}, #{email}, #{createTime}) </insert>
调用方法
通过 MyBatis 的 SqlSession 或 Mapper 代理对象调用接口方法,MyBatis 会根据id
找到对应的 SQL 并执行。UserMapper userMapper = sqlSession.getMapper(UserMapper.class); Map<String, Object> params = new HashMap<>(); params.put("name", "John"); params.put("email", "john@example.com"); params.put("createTime", new Date()); userMapper.insertUser(params);
注意事项
id
必须在同一个命名空间(namespace)内唯一,不能重复。
id
的值应与 Mapper 接口中的方法名严格匹配,否则会导致 MyBatis 无法找到对应的 SQL 语句。
如果使用注解方式(如 @Insert
),则无需在 XML 中配置 id
,但方法名仍需与 SQL 逻辑对应。
@Autowierd注解
@Autowired 注解详解
@Autowired
是 Spring 框架中用于依赖注入的核心注解,它能够自动将 Spring 容器中的 Bean 注入到目标对象中。以下是关于@Autowired
的详细说明和使用方法。工作原理
@Autowired
通过以下方式实现自动注入:
- 类型匹配:优先根据类型(类或接口)从 Spring 容器中查找匹配的 Bean。
- 名称匹配:如果同一类型存在多个 Bean,则根据字段或方法参数的名称匹配 Bean 的名称(需配合
@Qualifier
使用)。- 注入方式:支持构造函数、Setter 方法和字段直接注入。
使用方式
- 1.字段注入 直接在字段上使用
@Autowired
,Spring 会自动注入匹配的 Bean。@Service public class UserService { @Autowired private UserRepository userRepository; }
- 2.Setter 方法注入 通过 Setter 方法注入,灵活性更高。
@Service public class UserService { private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } }
3.构造函数注入(推荐) Spring 4.3 后,如果类只有一个构造函数,可以省略
@Autowired
。@Service public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } }
@Qualifier
注解 当同一类型存在多个 Bean 时,使用 @Qualifier指定具体 Bean 的名称。@Service public class UserService { @Autowired @Qualifier("userRepositoryImpl") private UserRepository userRepository; }
注意事项
- 循环依赖:避免构造函数注入导致的循环依赖问题,推荐使用 Setter 或字段注入。
- 测试友好性:构造函数注入更易于单元测试。
- Bean 范围:确保被注入的 Bean 在 Spring 容器中(如
@Component
、@Service
等注解标记)。