1,切分application的环境并引入依赖
通过将application.yml进行切分,切分成三个不同的环境,生产环境和开发环境,我们可以在不同情况下所需要的不同环境上进行相关的配置
我们对代码进行一次切分
application.yml
spring:
application:
name: springboot3-learn
profiles:
active: dev
application-dev.yml
java
server:
port: 8000
# springdoc-openapi项目配置
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: 'default'
paths-to-match: '/**'
packages-to-scan: net.chatmindai.springboot3learn.controller
# knife4j的增强配置,不需要增强可以不配
knife4j:
enable: true
setting:
language: zh_cn
spring:
datasource:
url: jdbc:mysql://124.223.65.138:38306/springboot3learn?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: springboot3learn
password: jhYWm3YHh6GGKppY
在上述yml文件中配置了连接数据库的功能 ,当应用程序启动时, Spring Boot 会自动使用这些配置信息来建立数据库连接, 为应用程序提供数据访问功能。
- 这是 JDBC 连接 URL,用于连接 MySQL 数据库。
- 这是用于连接数据库的用户名。在本例中是
springboot3learn
。 - 这是用于连接数据库的密码。在本例中是
jhYWm3YHh6GGKppY
。
application-prod.yml
java
server:
port: 80
knife4j:
enable: false
然后引入maven依赖
java
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
这两个 Maven 依赖项的作用如下:
-
MyBatis-Plus Spring Boot 3 Starter (
mybatis-plus-spring-boot3-starter
):- MyBatis-Plus 是一个增强版的 MyBatis 框架,提供了各种便捷的功能和工具。
- 这个依赖项是 MyBatis-Plus 的 Spring Boot 3 版本的启动器,它可以帮助你更快地在 Spring Boot 3 应用程序中集成和使用 MyBatis-Plus。
- 它提供了自动配置、代码生成、分页插件等功能,使得在 Spring Boot 项目中使用 MyBatis-Plus 变得更加简单。
-
MySQL Connector/J (
mysql-connector-j
):- 这是 MySQL 官方提供的 JDBC 驱动程序。
- 它允许 Java 应用程序连接和与 MySQL 数据库进行交互。
- 在 Spring Boot 应用程序中使用 MySQL 数据库时,需要引入此依赖项才能建立数据库连接。
接着我们创建连接数据库
依次点击如上,导入数据源
点击测试连接,可以连通
右键对应的架构,创建新的查询控制台,使用如下sql语句创建表
sql
-- auto-generated definition
create table demo_user
(
id bigint auto_increment comment '主键ID'
primary key,
name varchar(50) not null comment '用户名称,长度2-50个字符',
age int not null comment '用户年龄,0-150岁',
email varchar(255) not null comment '用户邮箱地址',
phone_number varchar(20) null comment '用户手机号,格式:1开头的11位数字',
birth_date date null comment '用户出生日期',
plan_date date null comment '计划日期,必须是未来的日期',
score double null comment '用户分数,必须为正数',
hobbies json null comment '用户兴趣爱好列表,1-5项',
agree_terms tinyint(1) not null comment '是否同意服务条款',
create_at datetime default CURRENT_TIMESTAMP null comment '记录创建时间',
update_at datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '记录最后更新时间'
)
comment '演示用户信息表' collate = utf8mb4_unicode_ci;
这是一个用于存储演示用户信息的表,它包含了用户的各种基本信息,如姓名、年龄、联系方式、兴趣爱好等。这些信息可以用于后续的业务逻辑处理和数据分析。
这个sql表的功能 在后续user: 根据上面建表语句 ,编写mybatis-plus 的实体类
在IDEA插件市场中找到mybatisx安装
然后右键点击表,选择MybatisX-Generator,生成 MybatisX-Generator
我们对应生成了很多新的代码
User.java
java
package net.chatmindai.springboot3learn.entity.user;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 演示用户信息表
* @TableName demo_user
*/
@TableName(value ="demo_user")
@Data
public class User implements Serializable {
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户名称,长度2-50个字符
*/
private String name;
/**
* 用户年龄,0-150岁
*/
private Integer age;
/**
* 用户邮箱地址
*/
private String email;
/**
* 用户手机号,格式:1开头的11位数字
*/
private String phoneNumber;
/**
* 用户出生日期
*/
private Date birthDate;
/**
* 计划日期,必须是未来的日期
*/
private Date planDate;
/**
* 用户分数,必须为正数
*/
private Double score;
/**
* 用户兴趣爱好列表,1-5项
*/
private Object hobbies;
/**
* 是否同意服务条款
*/
private Integer agreeTerms;
/**
* 记录创建时间
*/
private Date createAt;
/**
* 记录最后更新时间
*/
private Date updateAt;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
@TableField(exist = false)
:
这个注解来自于mybatis框架,用于标记实体类中的某个属性不需要映射到数据库的字段。
private static final long serialVersionUID = 1L;
确保实体类的序列化机制与数据库表映射之间的分离和独立性。
UserMapper.java
java
package net.chatmindai.springboot3learn.mapper;
import net.chatmindai.springboot3learn.entity.user.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author zhangkun
* @description 针对表【demo_user(演示用户信息表)】的数据库操作Mapper
* @createDate 2024-10-08 14:41:15
* @Entity net.chatmindai.springboot3learn.entity.user.User
*/
public interface UserMapper extends BaseMapper<User> {
}
这段代码义了一个名为 UserMapper
的接口,它用于执行对数据库表 demo_user
的数据库操作。导入了 MyBatis-Plus 提供的 BaseMapper
接口,它提供了基本的数据库操作方法。
Basemapper接口
BaseMapper 接口提供了增删改查(CRUD)操作的基本方法,如 insert、deleteById、upd
以下是 BaseMapper 接口提供的一些常用方法:
- insert(T entity):插入一条记录。
- deleteById(Serializable id):根据主键删除一条记录。
- deleteByIds(Collection<? extends Serializable> ids):根据主键集合删除多条记录。
- updateById(T entity):根据主键更新一条记录。
- selectById(Serializable id):根据主键查询一条记录。
- selectBatchIds(Collection<? extends Serializable> ids):根据主键集合查询多条记录。
- selectOne(T queryWrapper):根据条件查询一条记录。
- selectList(T queryWrapper):根据条件查询多条记录。
- selectPage(IPage<T> page, T queryWrapper):根据条件分页查询记录。
- ateById、selectById 等,这些方法可以直接在实体类上使用。
通过继承 Basemapper接口,开发者可以直接使用这些方法操作数据库,而不需要编写具体的masql语句,例如
java
public interface UserMapper extends BaseMapper<User> {
// 无需额外的方法定义,直接使用BaseMapper提供的方法
}
然后,在服务层或控制器层,可以直接注入 UserMapper
并使用它提供的方法:
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUserById(Long id) {
return userMapper.selectById(id);
}
// 其他数据库操作方法...
}
例如上述代码 private UserMapper userMapper;
定义了一个 UserMapper
类型的私有成员变量,用于在 UserService
类中执行数据库操作。
BaseMapper
接口极大地简化了数据库操作的开发工作,提高了开发效率。
UserService.java
java
import net.chatmindai.springboot3learn.entity.user.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author zhangkun
* @description 针对表【demo_user(演示用户信息表)】的数据库操作Service
* @createDate 2024-10-08 14:41:15
*/
public interface UserService extends IService<User> {
}
定义了一个 UserService
接口,它扩展了 MyBatis-Plus 提供的 IService
接口
MyBatis-Plus 的 IService 接口
IService 是 MyBatis-Plus 提供的一个服务层接口,它为开发者提供了一系列服务层操作方法,这些方法封装了基本的 CRUD(创建、读取、更新、删除)操作。以下是 IService 接口提供的一些关键点:
- 泛型支持:IService 接口是泛型的,可以接受任何实体类作为参数,这使得它可以适用于不同的表和实体类。
- 扩展性:IService 接口提供了基本的 CRUD 方法,但开发者也可以根据需要添加自定义的方法。
- 与 BaseMapper 的关系:IService 接口通常与 BaseMapper 接口一起使用,BaseMapper 提供了数据访问层的操作,而 IService 提供了业务逻辑层的操作。
UserService 接口的作用
- 业务逻辑封装:UserService 接口将 demo_user 表的数据库操作封装在服务层,使得业务逻辑与数据访问层分离。
- 服务层操作:通过扩展 IService<User>,UserService 接口可以提供基本的 CRUD 操作,如添加、删除、更新和查询用户信息。
- 自定义方法:开发者可以在 UserService 接口中添加自定义方法,以实现更复杂的业务逻辑。
UserServiceImpl.java
java
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.chatmindai.springboot3learn.entity.user.User;
import net.chatmindai.springboot3learn.service.UserService;
import net.chatmindai.springboot3learn.mapper.UserMapper;
import org.springframework.stereotype.Service;
/**
* @author zhangkun
* @description 针对表【demo_user(演示用户信息表)】的数据库操作Service实现
* @createDate 2024-10-08 14:41:15
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService{
}
@Service 注解用于标识 UserServiceImpl 类是一个服务层组件。
UserServiceImpl 类扩展了 ServiceImpl<UserMapper, User> 类,这意味着它继承了 MyBatis-Plus 提供的服务层实现类的功能。
UserServiceImpl 类实现了 UserService 接口,它必须提供接口中定义的所有方法的实现。
MyBatis-Plus 的 ServiceImpl 类
ServiceImpl 类是 MyBatis-Plus 提供的一个服务层实现类的基类,它封装了基本的 CRUD 操作,并提供了一些额外的服务层方法。ServiceImpl 类需要两个泛型参数:
- 第一个参数是 Mapper 接口类型,这里传入 UserMapper。
- 第二个参数是实体类类型,这里传入 User。
UserMapper.xml
关于User.xml文件的详细用法,可以移步致下文进行深度学习
springboot入门学习笔记2(连接mysql,使用mybatis,plus等
设置启动类
然后需要给启动类加一个注解用于扫描 @MapperScan("net.chatmindai.springboot3learn.mapper")
注解在 SpringBoot 应用程序中的作用是:
-
扫描 Mapper 接口:
- 这个注解告诉 Spring 去扫描
net.chatmindai.springboot3learn.mapper
包及其子包下的所有接口。 - 它会自动识别这些接口为 MyBatis 的 Mapper 接口,并为它们创建代理实现类。
- 这个注解告诉 Spring 去扫描
-
消除手动配置 Mapper 的需要:
- 通常情况下,你需要在配置文件中手动配置 Mapper 接口的位置,以便 MyBatis 能够识别它们。
- 使用
@MapperScan
注解可以消除这个需求,Spring 会自动扫描并配置这些 Mapper 接口。
-
提高开发效率:
- 在大型项目中,通常会有多个 Mapper 接口,手动配置会非常繁琐。
- 使用
@MapperScan
注解可以大大简化这个过程,提高开发效率。
创建接口
首先引入依赖
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.0.Final</version>
</dependency>
我们来简单介绍一下这些依赖:
-
org.mapstruct:mapstruct
- MapStruct 是一个基于注解的 Java Bean 映射库,可以自动生成映射代码,大大简化了对象转换的工作。
- 这个依赖提供了 MapStruct 的核心功能。
-
org.projectlombok:lombok
- Lombok 是一个 Java 工具库,可以通过注解的方式自动生成常见的 getter、setter、构造函数等样板代码。
- 这个依赖可以帮助开发者减少编写样板代码的工作量。
-
org.mapstruct:mapstruct-processor
- 这个依赖是 MapStruct 的注解处理器,用于在编译时自动生成映射代码。
接着我们创建UserConverter接口,用来实现DemoDTO和User类之间的转换
java
package net.chatmindai.springboot3learn.entity.user;
import net.chatmindai.springboot3learn.entity.demo.dto.DemoDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 用户转换器
*
* @author zk
* @date 2024/10/09
*/
@Mapper
public interface UserConverter {
UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
@Mappings({
@Mapping(target = "id", ignore = true),
@Mapping(target = "createAt", ignore = true),
@Mapping(target = "updateAt", ignore = true),
@Mapping(target = "agreeTerms", expression = "java(userDto.isAgreeTerms() ? 1 : 0)"),
@Mapping(target = "birthDate", source = "birthDate", qualifiedByName = "localDateToLocalDateTime"),
@Mapping(target = "planDate", source = "planDate", qualifiedByName = "localDateToLocalDateTime")
})
User userDtoToUser(DemoDTO userDto);
@Named("localDateToLocalDateTime")
default LocalDateTime localDateToLocalDateTime(LocalDate date) {
return date != null ? date.atStartOfDay() : null;
}
}
问:为什么要实现DemoDTO和User类的转换
User类是用户核心业务逻辑的载体,包含了用户各种行为,属性,通过User类可以实现更多业务逻辑方法比如密码校验,权限管理这种,User对象也可能有其他子类比如社交关系这种
而DTO在 Spring Boot 中充当数据传输的载体,只包含客户端需要的最少数据,避免一些不便于暴露的数据暴露,满足前端接收的需求就可以,后端将数据处理后,使用DTO封装响应结果。
UserConverter 接口定义了将 DTO转换为实体类的转换逻辑。UserController 类提供了一个创建新用户的 API 接口,通过UserConverter的方法接受 DemoDTO 对象,转换为 User 对象并保存到数据库,最后返回保存结果。
我们来看控制类
java
package net.chatmindai.springboot3learn.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import net.chatmindai.springboot3learn.entity.CommonResult;
import net.chatmindai.springboot3learn.entity.demo.dto.DemoDTO;
import net.chatmindai.springboot3learn.entity.user.User;
import net.chatmindai.springboot3learn.entity.user.UserConverter;
import net.chatmindai.springboot3learn.service.UserService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.validation.Valid;
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
@Tag(name = "用户管理", description = "用户相关的 API")
public class UserController {
private final UserService userService;
@PostMapping("/register")
@Operation(summary = "创建新用户", description = "接收 DemoDTO,转换为 User 并保存到数据库")
public CommonResult<User> createUser(@Valid @RequestBody DemoDTO demoDTO) {
User user = UserConverter.INSTANCE.userDtoToUser(demoDTO);
boolean saved = userService.save(user);
if (saved) {
return CommonResult.success(user, "用户创建成功");
} else {
return CommonResult.error("用户创建失败");
}
}
}
@RestController注解将当前类标记为一个REST控制器类,用于处理HTTP请求和响应
@RequestMapping("/users")将控制器的基础路径设置为/users
@RequiredArgsConstructor注解会自动生成一个包含所有必需参数的构造函数。在本例中,它会为 UserService
生成一个构造函数。
public CommonResult<User> createUser(@Valid @RequestBody DemoDTO demoDTO)
接受了一个DemoDTO类型的参数,通过Vailed进行数据校验,返回一个自定义的响应包装类
User user = UserConverter.INSTANCE.userDtoToUser(demoDTO);
用 UserConverter
类将 DemoDTO
对象转换为 User
对象。
boolean saved = userService.save(user);
这个代码用UserService的save方法将转换后的User对象保存到数据库
最后通过if判断返回相应的响应 实现用户的注册操作
每次发送请求之后,我们的数据库都会保存用户的信息
关于上述文件的交互作用
User.java 定义了用户的数据结构。
UserMapper.java 定义了与数据库表交互的方法。
UserMapper.xml 定义了实体类与数据库表的映射关系。
UserService.java 定义了用户管理的业务逻辑方法。
UserServiceImpl.java 实现了用户管理的业务逻辑,并调用 UserMapper 接口来执行数据库操作。UserConverter 接口定义了将 DTO转换为实体类的转换逻辑
UserController 类提供了一个创建新用户的 API 接口,通过UserConverter的方法接受 DemoDTO 对象,转换为 User 对象并保存到数据库,最后返回保存结果。