一、开发环境搭建
(一)安装Java开发工具包(JDK)
- 下载JDK
- 访问Oracle官网或其他开源JDK提供商(如OpenJDK)的网站,根据自己的操作系统版本选择合适的JDK版本进行下载。目前,Spring Boot推荐使用JDK 11及以上版本。
- 以Windows系统为例,下载完成后,运行安装程序,按照提示完成安装。在安装过程中,建议将JDK安装到一个没有空格和特殊字符的路径,例如
C:\Java\jdk-11
。
- 配置环境变量
- 安装完成后,需要配置环境变量,以便在命令行中能够直接使用
java
和javac
命令。 - 打开系统的环境变量设置(在Windows中可以通过“控制面板”或右键点击“此电脑”选择“属性”来进入),找到“系统变量”中的
Path
变量,点击“编辑”。 - 在“编辑环境变量”窗口中,点击“新建”,添加JDK的
bin
目录路径(例如C:\Java\jdk-11\bin
),然后点击“确定”保存。 - 同时,还需要设置
JAVA_HOME
环境变量。在“系统变量”中点击“新建”,变量名为JAVA_HOME
,变量值为JDK的安装路径(例如C:\Java\jdk-11
)。 - 配置完成后,打开命令行窗口,输入以下命令进行验证:
如果配置正确,将显示JDK的版本信息,例如:java -version javac -version
java version "11.0.12" 2021-07-20 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.12+8-LTS-237) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.12+8-LTS-237, mixed mode)
- 安装完成后,需要配置环境变量,以便在命令行中能够直接使用
(二)安装IntelliJ IDEA
- 下载IntelliJ IDEA
- 访问JetBrains官网,选择“Community”(社区版)或“Ultimate”(专业版)。对于Spring Boot开发,社区版已经足够使用。
- 根据自己的操作系统选择对应的安装包进行下载。
- 安装IntelliJ IDEA
- 下载完成后,运行安装程序,按照提示完成安装。在安装过程中,可以接受默认设置,也可以根据自己的需求进行自定义配置。
- 安装完成后,启动IntelliJ IDEA。首次启动时,可以选择“Import Settings”来导入之前的配置,或者直接点击“Do not import settings”开始新的配置。
- 配置IntelliJ IDEA
- 设置JDK:在IntelliJ IDEA中,点击菜单栏的“File” -> “Project Structure”,在弹出的窗口中选择“Project”选项卡,点击“Project SDK”旁边的“New…”,选择刚才安装的JDK路径(例如
C:\Java\jdk-11
),完成JDK的配置。 - 安装插件:为了更好地支持Spring Boot和MyBatis开发,建议安装以下插件:
- Spring Initializr:用于快速生成Spring Boot项目。
- MyBatis Plugin:提供MyBatis相关的代码提示和语法检查功能。
- 在IntelliJ IDEA中,点击菜单栏的“File” -> “Settings”(Windows)或“IntelliJ IDEA” -> “Preferences”(Mac),在弹出的窗口中选择“Plugins”,搜索并安装上述插件。
- 设置JDK:在IntelliJ IDEA中,点击菜单栏的“File” -> “Project Structure”,在弹出的窗口中选择“Project”选项卡,点击“Project SDK”旁边的“New…”,选择刚才安装的JDK路径(例如
(三)安装MySQL数据库
- 下载MySQL
- 访问MySQL官网,根据自己的操作系统版本选择合适的MySQL版本进行下载。建议选择“MySQL Community Server”版本。
- 以Windows系统为例,下载完成后,运行安装程序,按照提示完成安装。在安装过程中,可以选择“Developer Default”安装配置,该配置会自动安装MySQL Server、MySQL Workbench等常用组件。
- 配置MySQL
- 安装完成后,启动MySQL服务。在Windows系统中,可以通过“服务”管理工具(在“运行”中输入
services.msc
)找到“MySQL”服务,右键点击选择“启动”。 - 使用MySQL Workbench或命令行工具连接到MySQL数据库。默认情况下,MySQL的用户名为
root
,密码在安装过程中设置。 - 为了方便开发,建议创建一个专门的数据库和用户。例如,创建一个名为
test_db
的数据库和一个名为test_user
的用户,密码为test_password
:CREATE DATABASE test_db; CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'test_password'; GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'localhost'; FLUSH PRIVILEGES;
- 安装完成后,启动MySQL服务。在Windows系统中,可以通过“服务”管理工具(在“运行”中输入
二、创建Spring Boot项目
(一)使用Spring Initializr生成项目
- 访问Spring Initializr
- 打开浏览器,访问Spring Initializr网站。
- 配置项目信息
- 在Spring Initializr页面中,填写以下信息:
- Project:选择“Maven”(推荐使用Maven作为项目构建工具)。
- Language:选择“Java”。
- Spring Boot Version:选择最新的稳定版本(例如2.7.0)。
- Group:输入项目的包名,例如
com.example
。 - Artifact:输入项目的名称,例如
demo
。 - Name:输入项目的显示名称,例如
DemoApplication
。 - Description:输入项目的描述信息,例如
Demo project for Spring Boot
。 - Package name:输入项目的包路径,例如
com.example.demo
。
- 在“Dependencies”部分,添加以下依赖:
- Spring Web:用于构建基于Spring MVC的Web应用。
- Spring Boot DevTools:提供热部署功能,方便开发时快速重启应用。
- MyBatis Framework:集成MyBatis作为持久层框架。
- MySQL Driver:提供MySQL数据库的驱动支持。
- 在Spring Initializr页面中,填写以下信息:
- 生成项目
- 配置完成后,点击“Generate”按钮,下载生成的项目压缩包。
- 将下载的压缩包解压到本地指定目录。
(二)导入项目到IntelliJ IDEA
- 打开IntelliJ IDEA
- 启动IntelliJ IDEA,点击“Open”按钮,选择刚才解压的项目目录,然后点击“OK”。
- 导入项目
- IntelliJ IDEA会自动识别这是一个Maven项目,并开始导入依赖。在导入过程中,可能会弹出提示框,询问是否启用自动导入功能,建议选择“Enable Auto-Import”。
- 导入完成后,项目结构如下:
demo ├── src │ ├── main │ │ ├── java │ │ │ └── com.example.demo │ │ │ └── DemoApplication.java │ │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com.example.demo │ └── DemoApplicationTests.java └── pom.xml
(三)配置项目
-
配置application.properties
- 打开
src/main/resources/application.properties
文件,添加以下配置信息,用于连接MySQL数据库:# 数据库配置 spring.datasource.url=jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC spring.datasource.username=test_user spring.datasource.password=test_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # MyBatis配置 mybatis.mapper-locations=classpath:mappers/*.xml mybatis.type-aliases-package=com.example.demo.entity
spring.datasource.url
:指定MySQL数据库的连接URL,其中test_db
是数据库名称,localhost:3306
是数据库服务器地址和端口。spring.datasource.username
和spring.datasource.password
:指定数据库的用户名和密码。mybatis.mapper-locations
:指定MyBatis的Mapper文件存放路径。mybatis.type-aliases-package
:指定MyBatis的实体类存放路径。
- 打开
-
配置pom.xml
- 打开
pom.xml
文件,确认已经添加了以下依赖:<!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot DevTools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- MyBatis Starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <!-- MySQL Driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
- 如果版本号与生成项目时的版本不一致,可以根据实际情况进行调整。
- 打开
三、设计数据库
(一)创建数据库表
- 设计表结构
- 假设我们要开发一个简单的用户管理系统,需要一个
user
表来存储用户信息。表结构如下:id
:主键,自增。username
:用户名,字符串类型,唯一。password
:密码,字符串类型。email
:邮箱,字符串类型。created_at
:创建时间,时间戳类型。updated_at
:更新时间,时间戳类型。
- 假设我们要开发一个简单的用户管理系统,需要一个
- 创建表
- 使用MySQL Workbench或命令行工具,执行以下SQL语句创建
user
表:CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, email VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
- 使用MySQL Workbench或命令行工具,执行以下SQL语句创建
(二)插入测试数据
- 插入数据
- 为了方便测试,可以插入一些测试数据。执行以下SQL语句:
INSERT INTO user (username, password, email) VALUES ('user1', 'password1', 'user1@example.com'), ('user2', 'password2', 'user2@example.com'), ('user3', 'password3', 'user3@example.com');
- 为了方便测试,可以插入一些测试数据。执行以下SQL语句:
四、开发应用
(一)创建实体类
- 创建User类
- 在
src/main/java/com/example/demo/entity
目录下创建User.java
文件,内容如下:package com.example.demo.entity; import java.util.Date; public class User { private Integer id; private String username; private String password; private String email; private Date createdAt; private Date updatedAt; // Getters and Setters public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } public Date getUpdatedAt() { return updatedAt; } public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } }
- 这个类对应数据库中的
user
表,每个字段对应表中的一个列。
- 这个类对应数据库中的
- 在
(二)创建Mapper接口
- 创建UserMapper接口
- 在
src/main/java/com/example/demo/mapper
目录下创建UserMapper.java
文件,内容如下:package com.example.demo.mapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; @Mapper public interface UserMapper { @Select("SELECT * FROM user") List<User> findAll(); User findById(Integer id); int insert(User user); int update(User user); int deleteById(Integer id); }
- 使用MyBatis的
@Mapper
注解标记这是一个Mapper接口。 - 使用
@Select
注解定义了一个查询所有用户的方法findAll
。 - 其他方法(
findById
、insert
、update
、deleteById
)将在后续通过XML文件定义SQL语句。
- 使用MyBatis的
- 在
(三)创建Mapper XML文件
- 创建UserMapper.xml
- 在
src/main/resources/mappers
目录下创建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="com.example.demo.mapper.UserMapper"> <select id="findById" parameterType="int" resultType="com.example.demo.entity.User"> SELECT * FROM user WHERE id = #{id} </select> <insert id="insert" parameterType="com.example.demo.entity.User"> INSERT INTO user (username, password, email) VALUES (#{username}, #{password}, #{email}) </insert> <update id="update" parameterType="com.example.demo.entity.User"> UPDATE user SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id} </update> <delete id="deleteById" parameterType="int"> DELETE FROM user WHERE id = #{id} </delete> </mapper>
- 在
<mapper>
标签中,namespace
属性值为UserMapper
接口的全限定名。 - 定义了
findById
、insert
、update
、deleteById
四个方法的SQL语句。
- 在
- 在
(四)创建Service层
-
创建UserService接口
- 在
src/main/java/com/example/demo/service
目录下创建UserService.java
文件,内容如下:package com.example.demo.service; import com.example.demo.entity.User; import java.util.List; public interface UserService { List<User> findAll(); User findById(Integer id); User save(User user); User update(User user); void deleteById(Integer id); }
- 定义了用户相关的业务方法。
- 在
-
创建UserServiceImpl类
- 在
src/main/java/com/example/demo/service/impl
目录下创建UserServiceImpl.java
文件,内容如下:package com.example.demo.service.impl; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<User> findAll() { return userMapper.findAll(); } @Override public User findById(Integer id) { return userMapper.findById(id); } @Override public User save(User user) { userMapper.insert(user); return user; } @Override public User update(User user) { userMapper.update(user); return user; } @Override public void deleteById(Integer id) { userMapper.deleteById(id); } }
- 使用
@Service
注解标记这是一个Service类。 - 通过
@Autowired
注解注入UserMapper
接口。 - 实现了
UserService
接口中的所有方法,调用了Mapper层的方法来操作数据库。
- 使用
- 在
(五)创建Controller层
- 创建UserController类
- 在
src/main/java/com/example/demo/controller
目录下创建UserController.java
文件,内容如下:package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @GetMapping public List<User> getAllUsers() { return userService.findAll(); } @GetMapping("/{id}") public User getUserById(@PathVariable Integer id) { return userService.findById(id); } @PostMapping public User createUser(@RequestBody User user) { return userService.save(user); } @PutMapping("/{id}") public User updateUser(@PathVariable Integer id, @RequestBody User user) { user.setId(id); return userService.update(user); } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Integer id) { userService.deleteById(id); } }
- 在
- 使用
@RestController
注解标记这是一个Controller类。- 使用
@RequestMapping("/users")
注解定义了Controller的根路径。 - 定义了五个方法,分别对应CRUD操作:
getAllUsers
:获取所有用户。getUserById
:根据ID获取用户。createUser
:创建新用户。updateUser
:更新用户信息。deleteUser
:删除用户。
- 使用
@Autowired
注解注入UserService
接口。 - 使用
@RequestBody
注解接收JSON格式的请求体,并将其转换为User
对象。 - 使用
@PathVariable
注解获取路径中的参数。
- 使用
五、运行和测试应用
(一)运行应用
- 启动应用
- 在IntelliJ IDEA中,点击
DemoApplication.java
文件中的main
方法旁边的“运行”按钮,或者在终端中运行以下命令:mvn spring-boot:run
- 应用启动后,控制台会输出日志信息,表示应用已经成功启动。默认情况下,应用会运行在
http://localhost:8080
。
- 在IntelliJ IDEA中,点击
(二)测试接口
- 使用Postman测试
- 打开Postman,创建以下请求进行测试:
- 获取所有用户
- 请求类型:
GET
- 请求地址:
http://localhost:8080/users
- 预期响应:返回一个包含所有用户信息的JSON数组。
- 请求类型:
- 根据ID获取用户
- 请求类型:
GET
- 请求地址:
http://localhost:8080/users/1
(假设用户ID为1) - 预期响应:返回一个用户对象的JSON数据。
- 请求类型:
- 创建新用户
- 请求类型:
POST
- 请求地址:
http://localhost:8080/users
- 请求体(JSON格式):
{ "username": "newuser", "password": "newpassword", "email": "newuser@example.com" }
- 预期响应:返回创建的用户对象的JSON数据。
- 请求类型:
- 更新用户信息
- 请求类型:
PUT
- 请求地址:
http://localhost:8080/users/1
(假设用户ID为1) - 请求体(JSON格式):
{ "username": "updateduser", "password": "updatedpassword", "email": "updateduser@example.com" }
- 预期响应:返回更新后的用户对象的JSON数据。
- 请求类型:
- 删除用户
- 请求类型:
DELETE
- 请求地址:
http://localhost:8080/users/1
(假设用户ID为1) - 预期响应:无返回数据,用户被删除。
- 请求类型:
- 获取所有用户
- 打开Postman,创建以下请求进行测试:
- 使用浏览器测试
- 打开浏览器,访问
http://localhost:8080/users
,可以直接查看返回的JSON数据。
- 打开浏览器,访问
六、优化和扩展
(一)添加日志功能
-
配置日志
- 在
application.properties
文件中添加以下配置:# 日志配置 logging.level.root=INFO logging.level.org.springframework=DEBUG logging.level.com.example.demo=DEBUG
logging.level.root
:设置全局日志级别为INFO
。logging.level.org.springframework
:设置Spring框架的日志级别为DEBUG
。logging.level.com.example.demo
:设置项目包的日志级别为DEBUG
。
- 在
-
使用日志工具
- 在代码中,可以通过
org.slf4j.Logger
和org.slf4j.LoggerFactory
来记录日志。例如,在UserServiceImpl
类中添加日志记录:import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Service public class UserServiceImpl implements UserService { private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); @Override public List<User> findAll() { logger.info("Finding all users"); return userMapper.findAll(); } @Override public User findById(Integer id) { logger.info("Finding user by id: {}", id); return userMapper.findById(id); } @Override public User save(User user) { logger.info("Saving user: {}", user); userMapper.insert(user); return user; } @Override public User update(User user) { logger.info("Updating user: {}", user); userMapper.update(user); return user; } @Override public void deleteById(Integer id) { logger.info("Deleting user by id: {}", id); userMapper.deleteById(id); } }
- 在代码中,可以通过
(二)添加异常处理
- 创建全局异常处理器
- 在
src/main/java/com/example/demo/controller
目录下创建GlobalExceptionHandler.java
文件,内容如下:package com.example.demo.controller; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public Map<String, String> handleException(Exception e) { Map<String, String> error = new HashMap<>(); error.put("error", "Internal Server Error"); error.put("message", e.getMessage()); return error; } @ExceptionHandler(RuntimeException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public Map<String, String> handleRuntimeException(RuntimeException e) { Map<String, String> error = new HashMap<>(); error.put("error", "Bad Request"); error.put("message", e.getMessage()); return error; } }
- 使用
@ControllerAdvice
注解标记这是一个全局异常处理器。 - 定义了两个异常处理方法:
handleException
:处理所有Exception
类型的异常,返回500 Internal Server Error
状态码。handleRuntimeException
:处理所有RuntimeException
类型的异常,返回400 Bad Request
状态码。
- 每个方法返回一个包含错误信息的JSON对象。
- 使用
- 在
(三)添加分页功能
-
修改Mapper接口
- 在
UserMapper
接口中添加分页查询方法:List<User> findByPage(@Param("offset") int offset, @Param("limit") int limit);
- 在
UserMapper.xml
文件中添加对应的SQL语句:<select id="findByPage" parameterType="map" resultType="com.example.demo.entity.User"> SELECT * FROM user LIMIT #{offset}, #{limit} </select>
- 在
- 在
-
修改Service层
- 在
UserService
接口中添加分页查询方法:List<User> findByPage(int page, int size);
- 在
UserServiceImpl
类中实现该方法:@Override public List<User> findByPage(int page, int size) { int offset = (page - 1) * size; return userMapper.findByPage(offset, size); }
- 在
- 在
-
修改Controller层
- 在
UserController
类中添加分页查询接口:@GetMapping("/page") public List<User> getUsersByPage(@RequestParam int page, @RequestParam int size) { return userService.findByPage(page, size); }
- 在
(四)添加数据校验
-
添加校验注解
- 在
User
类中添加校验注解:package com.example.demo.entity; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; public class User { private Integer id; @NotBlank(message = "Username cannot be blank") @Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters") private String username; @NotBlank(message = "Password cannot be blank") @Size(min = 6, max = 100, message = "Password must be between 6 and 100 characters") private String password; @Email(message = "Invalid email format") private String email; // Getters and Setters }
- 在
-
在Controller层启用校验
- 在
UserController
类中,使用@Valid
注解启用校验:@PostMapping public User createUser(@Valid @RequestBody User user) { return userService.save(user); } @PutMapping("/{id}") public User updateUser(@PathVariable Integer id, @Valid @RequestBody User user) { user.setId(id); return userService.update(user); }
- 在
-
处理校验失败
- 在
GlobalExceptionHandler
类中添加校验失败的处理方法:@ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach((error) -> { String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return errors; }
- 在
七、部署应用
(一)打包应用
- 使用Maven打包
- 在项目根目录下运行以下命令:
mvn clean package
- 打包完成后,会在
target
目录下生成一个demo-0.0.1-SNAPSHOT.jar
文件(版本号根据实际情况可能不同)。
- 在项目根目录下运行以下命令:
(二)运行打包后的应用
- 运行JAR文件
- 在终端中运行以下命令:
java -jar target/demo-0.0.1-SNAPSHOT.jar
- 应用启动后,可以通过浏览器或Postman访问接口进行测试。
- 在终端中运行以下命令:
(三)部署到服务器
- 上传JAR文件
- 将打包后的JAR文件上传到服务器的指定目录。
- 在服务器上运行
- 在服务器上运行以下命令启动应用:
nohup java -jar demo-0.0.1-SNAPSHOT.jar > app.log 2>&1 &
- 使用
nohup
命令可以让应用在后台运行,并将日志输出到app.log
文件中。
- 在服务器上运行以下命令启动应用: