前置要求:Java基础、Maven基础、SQL基础
学习时长:约5-7天(每天4小时)
Spring Boot版本:3.2+
适用场景:企业级应用、微服务、REST API、后台管理系统
一、Spring Boot 是什么?
Spring Boot 是 Java 生态中最流行的Web框架,简化了Spring应用的开发,是企业级Java开发的事实标准。
| 特点 | 说明 |
|---|---|
| 核心理念 | 约定优于配置,开箱即用 |
| 学习曲线 | ★★★☆☆(需要Java和Spring基础) |
| 核心优势 | 自动配置、内嵌服务器、Starter依赖 |
| 生态完善 | Spring全家桶:Security、Data、Cloud |
| 就业市场 | Java岗位中Spring Boot需求占比最高 |
二、快速开始
2.1 创建项目
# 方式1:使用Spring Initializr(推荐)
# https://start.spring.io/
# 选择:Java 17, Maven, Spring Web, Spring Data JPA, MySQL Driver
# 方式2:命令行
curl https://start.spring.io/starter.zip \
-d type=maven-project \
-d language=java \
-d bootVersion=3.2.0 \
-d baseDir=myproject \
-d groupId=com.example \
-d artifactId=myproject \
-d dependencies=web,jpa,mysql,lombok \
-o myproject.zip
unzip myproject.zip
cd myproject
2.2 项目结构
myproject/
├── pom.xml # Maven配置
├── src/main/java/com/example/
│ ├── MyprojectApplication.java # 启动类
│ ├── controller/ # 控制器
│ ├── service/ # 业务逻辑
│ ├── repository/ # 数据访问
│ ├── model/ # 实体类
│ ├── dto/ # 数据传输对象
│ ├── config/ # 配置类
│ └── exception/ # 异常处理
└── src/main/resources/
├── application.yml # 配置文件
├── static/ # 静态资源
└── templates/ # 模板文件
2.3 配置文件
# application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update # 自动更新表结构
show-sql: true # 显示SQL
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.MySQLDialect
# 日志配置
logging:
level:
com.example: DEBUG
org.hibernate.SQL: DEBUG
三、核心概念
3.1 启动类
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // 组合注解:@Configuration + @EnableAutoConfiguration + @ComponentScan
public class MyprojectApplication {
public static void main(String[] args) {
SpringApplication.run(MyprojectApplication.class, args);
}
}
3.2 控制器(Controller)
package com.example.controller;
import com.example.model.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController // @Controller + @ResponseBody
@RequestMapping("/api/users")
@CrossOrigin // 允许跨域
public class UserController {
@Autowired
private UserService userService;
// GET /api/users
@GetMapping
public List<User> getAll() {
return userService.findAll();
}
// GET /api/users/1
@GetMapping("/{id}")
public ResponseEntity<User> getById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// POST /api/users
@PostMapping
public ResponseEntity<User> create(@RequestBody User user) {
User saved = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
// PUT /api/users/1
@PutMapping("/{id}")
public ResponseEntity<User> update(@PathVariable Long id, @RequestBody User user) {
return userService.findById(id)
.map(existing -> {
user.setId(id);
return ResponseEntity.ok(userService.save(user));
})
.orElse(ResponseEntity.notFound().build());
}
// DELETE /api/users/1
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
if (userService.findById(id).isPresent()) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
return ResponseEntity.notFound().build();
}
// GET /api/users/search?keyword=张三
@GetMapping("/search")
public List<User> search(@RequestParam String keyword) {
return userService.search(keyword);
}
}
3.3 实体类(Model)
package com.example.model;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 50)
private String username;
@Column(nullable = false, unique = true, length = 100)
private String email;
@Column(nullable = false)
private String password;
@Column(length = 20)
private String phone;
@Column(nullable = false)
@Builder.Default
private Boolean isActive = true;
@CreationTimestamp
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
}
3.4 数据访问层(Repository)
package com.example.repository;
import com.example.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// 方法名查询(Spring Data JPA自动生成SQL)
Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email);
List<User> findByIsActiveTrue();
List<User> findByUsernameContainingOrEmailContaining(String username, String email);
// 自定义JPQL查询
@Query("SELECT u FROM User u WHERE u.username LIKE %:keyword% OR u.email LIKE %:keyword%")
List<User> searchByKeyword(@Param("keyword") String keyword);
// 原生SQL查询
@Query(value = "SELECT * FROM users WHERE is_active = true ORDER BY created_at DESC", nativeQuery = true)
List<User> findActiveUsers();
// 统计
long countByIsActiveTrue();
boolean existsByUsername(String username);
boolean existsByEmail(String email);
}
3.5 业务逻辑层(Service)
package com.example.service;
import com.example.model.User;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@Transactional // 事务管理
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public Optional<User> findByUsername(String username) {
return userRepository.findByUsername(username);
}
public User save(User user) {
// 检查用户名是否已存在
if (userRepository.existsByUsername(user.getUsername())) {
throw new RuntimeException("用户名已存在");
}
return userRepository.save(user);
}
public User update(Long id, User userDetails) {
User user = userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在"));
user.setUsername(userDetails.getUsername());
user.setEmail(userDetails.getEmail());
user.setPhone(userDetails.getPhone());
return userRepository.save(user);
}
public void delete(Long id) {
if (!userRepository.existsById(id)) {
throw new RuntimeException("用户不存在");
}
userRepository.deleteById(id);
}
public List<User> search(String keyword) {
return userRepository.searchByKeyword(keyword);
}
public long countActiveUsers() {
return userRepository.countByIsActiveTrue();
}
}
四、请求参数处理
@RestController
@RequestMapping("/api/demo")
public class DemoController {
// 路径参数
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id).orElse(null);
}
// 查询参数
@GetMapping("/users")
public List<User> getUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String keyword) {
return userService.findWithPagination(page, size, keyword);
}
// 请求体(JSON)
@PostMapping("/users")
public User createUser(@RequestBody @Valid UserDTO userDTO) {
return userService.createFromDTO(userDTO);
}
// 表单参数
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
return userService.login(username, password);
}
// 文件上传
@PostMapping("/upload")
public String upload(@RequestParam MultipartFile file) {
// 处理文件
return "上传成功";
}
// 请求头
@GetMapping("/info")
public String getInfo(@RequestHeader("Authorization") String token) {
return "Token: " + token;
}
}
五、DTO与参数验证
// DTO(数据传输对象)
package com.example.dto;
import jakarta.validation.constraints.*;
import lombok.Data;
@Data
public class UserDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 50, message = "用户名长度3-50")
private String username;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 100, message = "密码长度6-100")
private String password;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
}
// 全局异常处理
package com.example.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach(error -> {
String field = ((FieldError) error).getField();
String message = error.getDefaultMessage();
errors.put(field, message);
});
return ResponseEntity.badRequest().body(errors);
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, String>> handleRuntime(RuntimeException ex) {
Map<String, String> error = new HashMap<>();
error.put("error", ex.getMessage());
return ResponseEntity.badRequest().body(error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Map<String, String>> handleGeneral(Exception ex) {
Map<String, String> error = new HashMap<>();
error.put("error", "服务器内部错误");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
六、分页与排序
// Controller
@GetMapping("/users/page")
public Page<User> getUsersPage(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortBy,
@RequestParam(defaultValue = "desc") String direction) {
Sort sort = direction.equalsIgnoreCase("asc") ?
Sort.by(sortBy).ascending() :
Sort.by(sortBy).descending();
Pageable pageable = PageRequest.of(page, size, sort);
return userRepository.findAll(pageable);
}
// Repository
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findByIsActiveTrue(Pageable pageable);
Page<User> findByUsernameContaining(String keyword, Pageable pageable);
}
// 返回结果包含
// {
// "content": [...],
// "totalElements": 100,
// "totalPages": 10,
// "number": 0, // 当前页
// "size": 10, // 每页大小
// "first": true,
// "last": false
// }
七、完整项目示例(用户管理系统)
// ====================
// 启动类
// ====================
@SpringBootApplication
public class UserManagementApplication {
public static void main(String[] args) {
SpringApplication.run(UserManagementApplication.class, args);
}
}
// ====================
// 实体类
// ====================
@Entity
@Table(name = "users")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 50)
private String username;
@Column(nullable = false, unique = true, length = 100)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
@Builder.Default
private Boolean isActive = true;
@CreationTimestamp
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
}
// ====================
// Repository
// ====================
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email);
Page<User> findByUsernameContainingOrEmailContaining(
String username, String email, Pageable pageable);
long countByIsActiveTrue();
}
// ====================
// Service
// ====================
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
public Page<User> findAll(int page, int size) {
return userRepository.findAll(PageRequest.of(page, size, Sort.by("createdAt").descending()));
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User create(UserDTO dto) {
if (userRepository.existsByUsername(dto.getUsername())) {
throw new RuntimeException("用户名已存在");
}
if (userRepository.existsByEmail(dto.getEmail())) {
throw new RuntimeException("邮箱已存在");
}
User user = User.builder()
.username(dto.getUsername())
.email(dto.getEmail())
.password(passwordEncoder.encode(dto.getPassword()))
.build();
return userRepository.save(user);
}
public User update(Long id, UserDTO dto) {
User user = userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在"));
user.setUsername(dto.getUsername());
user.setEmail(dto.getEmail());
if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
user.setPassword(passwordEncoder.encode(dto.getPassword()));
}
return userRepository.save(user);
}
public void delete(Long id) {
userRepository.deleteById(id);
}
public Page<User> search(String keyword, int page, int size) {
return userRepository.findByUsernameContainingOrEmailContaining(
keyword, keyword, PageRequest.of(page, size));
}
}
// ====================
// Controller
// ====================
@RestController
@RequestMapping("/api/users")
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public Page<User> getAll(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return userService.findAll(page, size);
}
@GetMapping("/{id}")
public ResponseEntity<User> getById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<User> create(@RequestBody @Valid UserDTO dto) {
return ResponseEntity.status(HttpStatus.CREATED).body(userService.create(dto));
}
@PutMapping("/{id}")
public ResponseEntity<User> update(@PathVariable Long id, @RequestBody @Valid UserDTO dto) {
return ResponseEntity.ok(userService.update(id, dto));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
@GetMapping("/search")
public Page<User> search(
@RequestParam String keyword,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return userService.search(keyword, page, size);
}
}
学习建议
- 先理解Spring IoC和DI,这是框架的核心思想
- 掌握分层架构:Controller → Service → Repository
- 学会使用Lombok,减少样板代码
- 理解事务管理,@Transactional是关键
- 做一个完整项目,巩固所学知识
下一步学习
- Spring Security — 安全认证
- Spring Cloud — 微服务
- Go Gin 框架