结合MyBatis的Mapper.xml文件,展示完整的层级数据流转和数据库操作。
// User.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_user")
public class User {
@TableId(type = IdType.AUTO)
private Long userId;
@NotBlank
private String username;
@NotBlank
private String password;
private String email;
private String phone;
private Date createTime;
// 非数据库字段,用于关联查询
@TableField(exist = false)
private List<Role> roles;
}
// Role.java
@Data
@TableName("sys_role")
public class Role {
@TableId(type = IdType.AUTO)
private Long roleId;
private String roleName;
private String roleDesc;
}
@Mapper
public interface UserMapper {
// 插入用户并返回主键
int insertUser(User user);
// 根据ID查询用户(包含角色信息)
User selectUserWithRoles(@Param("userId") Long userId);
// 分页查询用户
List<User> selectUserList(UserQueryDTO queryDTO);
// 批量插入用户角色关系
int batchInsertUserRoles(@Param("list") List<UserRole> userRoles);
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<resultMap id="BaseUserMap" type="com.example.entity.User">
<id column="user_id" property="userId"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
<result column="create_time" property="createTime"/>
resultMap>
<resultMap id="UserWithRolesMap" type="com.example.entity.User" extends="BaseUserMap">
<collection property="roles" ofType="com.example.entity.Role">
<id column="role_id" property="roleId"/>
<result column="role_name" property="roleName"/>
<result column="role_desc" property="roleDesc"/>
collection>
resultMap>
<insert id="insertUser" useGeneratedKeys="true" keyProperty="userId">
INSERT INTO sys_user (username, password, email, phone)
VALUES (#{username}, #{password}, #{email}, #{phone})
insert>
<select id="selectUserWithRoles" resultMap="UserWithRolesMap">
SELECT
u.*,
r.role_id, r.role_name, r.role_desc
FROM
sys_user u
LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id
LEFT JOIN sys_role r ON ur.role_id = r.role_id
WHERE
u.user_id = #{userId}
select>
<select id="selectUserList" resultMap="BaseUserMap">
SELECT * FROM sys_user
<where>
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
if>
<if test="email != null and email != ''">
AND email = #{email}
if>
<if test="phone != null and phone != ''">
AND phone = #{phone}
if>
<if test="createTimeStart != null">
AND create_time >= #{createTimeStart}
if>
<if test="createTimeEnd != null">
AND create_time <= #{createTimeEnd}
if>
where>
ORDER BY create_time DESC
select>
<insert id="batchInsertUserRoles">
INSERT INTO sys_user_role (user_id, role_id)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.userId}, #{item.roleId})
foreach>
insert>
mapper>
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
private final RoleMapper roleMapper;
private final PasswordEncoder passwordEncoder;
@Override
@Transactional
public UserVO createUser(UserDTO userDTO) {
// DTO转Entity
User user = new User();
BeanUtils.copyProperties(userDTO, user);
// 密码加密
user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
// 保存用户
userMapper.insertUser(user);
// 保存用户角色关系
if (!CollectionUtils.isEmpty(userDTO.getRoleIds())) {
List<UserRole> userRoles = userDTO.getRoleIds().stream()
.map(roleId -> new UserRole(user.getUserId(), roleId))
.collect(Collectors.toList());
userMapper.batchInsertUserRoles(userRoles);
}
// 返回完整的用户信息
return getUserVO(user.getUserId());
}
@Override
public PageVO<UserVO> getUsers(UserQueryDTO queryDTO) {
// 设置分页参数
PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize());
// 查询用户列表
List<User> users = userMapper.selectUserList(queryDTO);
PageInfo<User> pageInfo = new PageInfo<>(users);
// 转换为VO列表
List<UserVO> userVOs = users.stream()
.map(user -> UserVO.fromEntity(user, getRolesByUserId(user.getUserId())))
.collect(Collectors.toList());
// 构建分页VO
return new PageVO<>(
pageInfo.getTotal(),
pageInfo.getPageNum(),
pageInfo.getPageSize(),
userVOs
);
}
@Override
public UserVO getUserVO(Long userId) {
User user = userMapper.selectUserWithRoles(userId);
return UserVO.fromEntity(user, user.getRoles());
}
private List<Role> getRolesByUserId(Long userId) {
return roleMapper.selectByUserId(userId);
}
}
@Data
public class UserDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 4, max = 20)
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20)
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d).*$",
message = "密码必须包含字母和数字")
private String password;
@Email
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$")
private String phone;
@NotEmpty(message = "至少分配一个角色")
private List<Long> roleIds;
// 自定义转换方法
public User toEntity() {
User user = new User();
BeanUtils.copyProperties(this, user);
return user;
}
}
@Data
@Accessors(chain = true)
public class UserVO {
private Long userId;
private String username;
private String email;
private String phone;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private List<RoleVO> roles;
// 静态工厂方法
public static UserVO fromEntity(User user, List<Role> roles) {
return new UserVO()
.setUserId(user.getUserId())
.setUsername(user.getUsername())
.setEmail(user.getEmail())
.setPhone(user.getPhone())
.setCreateTime(user.getCreateTime())
.setRoles(roles.stream()
.map(RoleVO::fromEntity)
.collect(Collectors.toList()));
}
}
@Data
@AllArgsConstructor
public class PageVO<T> {
private Long total;
private Integer pageNum;
private Integer pageSize;
private List<T> list;
// 计算总页数
public Integer getPages() {
if (pageSize == 0) return 0;
return (int) Math.ceil((double) total / pageSize);
}
}
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping
public ResponseEntity<Result<UserVO>> createUser(
@Valid @RequestBody UserDTO userDTO) {
UserVO userVO = userService.createUser(userDTO);
return ResponseEntity.ok(Result.success(userVO));
}
@GetMapping
public ResponseEntity<Result<PageVO<UserVO>>> getUsers(
@Valid UserQueryDTO queryDTO) {
PageVO<UserVO> page = userService.getUsers(queryDTO);
return ResponseEntity.ok(Result.success(page));
}
@GetMapping("/{userId}")
public ResponseEntity<Result<UserVO>> getUser(
@PathVariable Long userId) {
UserVO userVO = userService.getUserVO(userId);
return ResponseEntity.ok(Result.success(userVO));
}
}
// 通用返回结果
@Data
@AllArgsConstructor
class Result<T> {
private int code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
return new Result<>(200, "success", data);
}
}
Mapper.xml优化:
resultMap
实现复杂结果映射对象转换优化:
分页处理:
验证增强:
性能优化:
这种结构清晰地区分了各层职责,使代码更易维护和扩展,同时保证了良好的性能。