编者著:
在学校的实训过程中一直在做的前端方面的活,后端的了解不深入,为此,重新学习,参照实训期间已经完成的项目,将后端从零开始进行操作。
项目初建
springinitial选项选择maven,勾选依赖
一些常用的依赖选项:
-
Spring Data JPA:如果项目需要与数据库进行交互,尤其是使用关系型数据库,可以勾选
Spring Data JPA
。它提供了方便的数据访问层开发和ORM功能。 -
Spring Security:如果项目涉及用户认证和授权,可以勾选
Spring Security
。它提供了一整套安全功能,包括登录、注册、角色管理等。 -
Spring Boot DevTools:如果希望在开发时提高效率,可以勾选
Spring Boot DevTools
。它提供了自动重启、LiveReload等开发者工具。 -
Spring Boot Actuator:用于监控和管理应用,提供健康检查、监控指标等功能。
-
Spring Configuration Processor:有助于在IDE中获得配置文件的自动补全。
-
Lombok:简化Java代码,尤其是简化getter/setter、构造函数等常见代码的编写。
-
Spring Cloud:如果项目需要微服务架构或者需要使用分布式系统功能,如服务发现、配置管理等,可以勾选相关的Spring Cloud依赖。
-
Spring Kafka/RabbitMQ:如果项目需要消息队列功能,可以根据需要勾选
Spring for Apache Kafka
或Spring for RabbitMQ
。
具体选择哪些依赖,取决于你的项目需求。一般来说,一个最基本的前后端分离项目需要Spring Web
、Spring Data JPA
和Spring Security
。其他依赖可以根据具体功能需求逐步添加。
勾选完毕后,完成创建。
数据库连接
点击设置进入配置,本地已有数据库,配置完成
在application中,进行数据库配置
配置完毕后在pom中添加依赖
swagger依赖用knife4j ui,
mybatispuls所需依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
mybatis生成目录
通过mybatisx建表生成实体类,service以及mapper结构,自行创建controller
完成三层的代码编写
mapper
以注解方式的实现为例:
@Mapper
public interface AdminMapper extends BaseMapper<Admin> {
@Select("SELECT * FROM admin WHERE id = #{id}")
Admin findById(@Param("id") int id);
@Insert("INSERT INTO admin(name, password) VALUES(#{name}, #{password})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(Admin admin);
@Select("SELECT * FROM admin")
List<Admin> findAll();
@Update("UPDATE admin SET name=#{name}, password=#{password} WHERE id=#{id}")
int update(Admin admin);
@Delete("DELETE FROM admin WHERE id = #{id}")
int delete(@Param("id") int id);
}
对mapper理解
在MyBatis中,`#{}` 用于标记占位符,将其替换为传入参数的具体值。当你使用 `#{name}` 这样的占位符时,MyBatis会根据方法的参数或参数对象的属性名来匹配相应的值。
@Select("SELECT * FROM admin WHERE id = #{id}")
Admin findById(@Param("id") int id);
@Insert("INSERT INTO admin(name, password) VALUES(#{name}, #{password})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(Admin admin);
对于一般的直接传入id的情况,通过@Param(“id”),这里的id会被绑定到#{id}上,int id则是个形式参数,负责标记的还是@Param
如何匹配 `#{name}` 和 `#{password}`
1. 传入的参数对象:在这个方法中,`Admin admin` 是一个传入的参数对象。这个对象包含了插入操作所需要的数据属性。
2. `#{}` 占位符的工作原理:
- MyBatis 会通过反射机制遍历传入的参数对象 `admin`,查找和占位符匹配的属性。
- 具体来说,当MyBatis看到 `#{name}` 时,它会去查找 `admin` 对象中是否有一个名为 `name` 的属性。
- 同理,`#{password}` 会查找 `admin` 对象中名为 `password` 的属性。
3. 属性值替换:
- MyBatis 找到匹配的属性后,就会使用该属性的值替换占位符。例如,`admin` 对象的 `name` 属性值为 "username",`password` 属性值为 "password",那么 MyBatis 会将 `#{name}` 替换为 "username",`#{password}` 替换为 "password"。
4. 生成的SQL语句:
- 替换完成后,最终的SQL语句可能类似于:
INSERT INTO admin(name, password) VALUES('username', 'password')
总结
`#{name}` 和 `#{password}` 是MyBatis的占位符,用于在SQL语句中动态替换成方法参数的实际值。MyBatis通过反射机制自动识别并替换这些占位符的值。当方法传入一个对象时,如 `Admin admin`,MyBatis会根据对象的属性名称匹配占位符,并将属性值注入到SQL语句中。这样就实现了参数和SQL语句之间的动态绑定。
service
public interface AdminService {
Admin findById(int id);
List<Admin> findAll();
int insert(Admin admin);
int update(Admin admin);
int delete(int id);
}
serviceimpl
@Service
public class AdminServiceImpl implements AdminService {
private AdminMapper adminMapper;
@Autowired
public AdminServiceImpl(AdminMapper adminMapper){
this.adminMapper=adminMapper;
}
@Override
public Admin findById(int id) {
return adminMapper.findById(id);
}
@Override
public List<Admin> findAll() {
return adminMapper.findAll();
}
@Override
public int insert(Admin admin) {
return adminMapper.insert(admin);
}
@Override
public int update(Admin admin) {
return adminMapper.update(admin);
}
@Override
public int delete(int id) {
return adminMapper.delete(id);
}
}
controller
@RestController
@RequestMapping("/admin")
@Api(tags = "管理员接口") // Knife4j 标签
public class AdminController {
private final AdminService adminService;
@Autowired
public AdminController(AdminService adminService) {
this.adminService = adminService;
}
@ApiOperation(value = "根据ID查找管理员", notes = "根据ID查找管理员信息")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "查找成功"),
@ApiResponse(code = 404, message = "管理员未找到")
})
@GetMapping("/{id}")
public Admin findById(@PathVariable int id) {
return adminService.findById(id);
}
@ApiOperation(value = "获取所有管理员", notes = "获取所有管理员列表")
@GetMapping("/list")
public List<Admin> findAll() {
return adminService.findAll();
}
@ApiOperation(value = "保存新的管理员", notes = "保存新的管理员信息")
@PostMapping("/save")
public int save(@RequestBody Admin admin) {
return adminService.insert(admin);
}
@ApiOperation(value = "更新管理员信息", notes = "更新现有管理员的信息")
@PutMapping("/update")
public int update(@RequestBody Admin admin) {
return adminService.update(admin);
}
@ApiOperation(value = "删除管理员", notes = "根据ID删除管理员")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "删除成功"),
@ApiResponse(code = 404, message = "管理员未找到")
})
@DeleteMapping("/delete/{id}")
public int delete(@PathVariable int id) {
return adminService.delete(id);
}
}
@RequestBody用于接收HTTP请求体中的JSON数据
在`POST`、`PUT`、`PATCH`等请求中,数据通常通过请求体发送,尤其是当数据结构复杂时,使用`@RequestBody`是推荐的做法。`@RequestBody`将请求体的数据解析为Java对象,非常适合处理JSON或XML格式的数据。
{
"name": "John",
"age": 30
}
@PathVariable用于从URL路径中获取变量。
GET /users/{id}
@RequestParam用于从查询参数中提取数据(通常出现在URL的`?`之后)或表单数据,并将其绑定到方法参数上
GET /search?query=java&sort=desc
@GetMapping("/search")
public List<Result> search(@RequestParam String query, @RequestParam String sort) {
return searchService.search(query, sort);
}
knife4j注解
@Api
:定义在类上,表示Controller的标签,通常用于说明该Controller的功能。@ApiOperation
:定义在方法上,用于说明该接口的作用和详细描述。@ApiResponse
和@ApiResponses
:定义在方法上,用于说明接口的响应状态和对应的描述信息。
运行配置
设置mapperscan,扫描mapper文件夹下面使用注解的部分
添加mybatis.mapper,完成对xml部分的配置
swaggerconfig
@Configuration
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // 仅扫描有@ApiOperation注解的方法
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("API 文档")
.description("API 文档描述")
.version("1.0")
.build();
}
}
1. @Configuration
注解
- 该注解表明这是一个配置类,相当于传统的 Spring XML 配置文件。Spring 会将该类标记为一个配置类并进行管理。
2. createRestApi
方法
- 这是一个标记为
@Bean
的方法,返回一个Docket
对象。Docket
是 Swagger 的主要配置对象,用于控制和定制 Swagger 的各项功能。
Docket
配置内容
-
DocumentationType.OAS_30
:指定文档类型,这里使用的是 OpenAPI 3.0 规范(OAS 3.0),也即 Swagger 3.0。 -
apiInfo(apiInfo())
:设置 API 文档的基本信息,包括标题、描述、版本等。这个信息是通过apiInfo()
方法生成的ApiInfo
对象。 -
select()
:返回一个ApiSelectorBuilder
实例,用于控制哪些接口暴露给 Swagger 来生成文档。 -
apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
:仅扫描带有@ApiOperation
注解的方法。RequestHandlerSelectors.withMethodAnnotation
是一个选择器,用于选择特定的注解方法。 -
build()
:构建并返回一个Docket
实例。
3. apiInfo
方法
- 该方法返回一个
ApiInfo
对象,用于提供 API 的一些基本信息。
ApiInfo
配置内容
-
title
:API 文档的标题,在文档页面上显示。 -
description
:API 文档的描述,提供有关 API 的更多信息。 -
version
:API 的版本号,可以帮助区分不同版本的 API。
运行项目
访问http://localhost:8080/doc.html (端口可以调整)