SpringBoot 集成 Mybatis 操作数据库
系统环境:
- JDK 版本:1.8
- 数据库:Mysql 8.0
- Mybatis 版本:3.5.4
- SpringBoot 版本:2.2.5.RELEASE
参考地址:
示例项目地址:
一、Mybatis 简介
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
这里主要是介绍下如果通过 xml 方式来使用 Mybatis,这种方式比较灵活,尤其是在写复杂 SQL 语句时,能很好的创建表与表之前的关系,如果是单表方式,更推荐使用 mybatis-plus 或者 jpa。
二、示例准备
2.1 表结构
所有表都是用于方便演示,请不要在乎合理性。
总共拥有 group(用户组表)、 user(用户表) 、 role(角色表)、user_role(用户角色关系表)、base_info(用户基本信息表)五个表。

用户组表 group:
用户组表是对用户进行分组归类,该表内容如下:

用户表 user:
用户表是用于记录 用户名、密码 等用户基本信息,该表内容如下:

角色表 role:
角色表是记录角色信息,用于与用户绑定,一个用户可能拥有多个角色,一个角色也可能属于多个用户,该表内容如下:

用户角色关系表:
用户关系表是用于维护 用户表 与 角色表 两表间的关联关系,该表内容如下:

用户基本信息表 base_info:
用户基本信息表是用于记录用户 姓名、性别、生日、备注信息 等,该表内容如下:

2.2 表 SQL
Mysql 的表 SQL 文件内容如下:
SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;
-- ------------------------------ Table structure for base_info-- ----------------------------DROP TABLE IF EXISTS `base_info`;CREATE TABLE `base_info` ( `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', `user_id` int(0) NULL DEFAULT NULL COMMENT '用户ID号', `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '姓名', `sex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '性别', `birthday` date NULL DEFAULT NULL COMMENT '生日', `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ------------------------------ Records of base_info-- ----------------------------INSERT INTO `base_info` VALUES (1, 1, '张三', '男', '1994-08-01', '无');INSERT INTO `base_info` VALUES (2, 2, '李四', '女', '1990-06-06', '无');INSERT INTO `base_info` VALUES (3, 3, '王五', '男', '1988-01-27', '无');INSERT INTO `base_info` VALUES (4, 4, '赵六', '女', '1991-05-06', '无');INSERT INTO `base_info` VALUES (5, 5, '孙七', '男', '1995-03-21', '无');INSERT INTO `base_info` VALUES (6, 6, '周八', '女', '1989-11-22', '无');
-- ------------------------------ Table structure for group-- ----------------------------DROP TABLE IF EXISTS `group`;CREATE TABLE `group` ( `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '组名', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ------------------------------ Records of group-- ----------------------------INSERT INTO `group` VALUES (1, '测试组1');INSERT INTO `group` VALUES (2, '测试组2');
-- ------------------------------ Table structure for role-- ----------------------------DROP TABLE IF EXISTS `role`;CREATE TABLE `role` ( `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '角色名称', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ------------------------------ Records of role-- ----------------------------INSERT INTO `role` VALUES (1, '管理员');INSERT INTO `role` VALUES (2, '测试');INSERT INTO `role` VALUES (3, '开发');INSERT INTO `role` VALUES (4, '运维');INSERT INTO `role` VALUES (5, '产品');INSERT INTO `role` VALUES (6, '需求');
-- ------------------------------ Table structure for user-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', `group_id` int(0) NULL DEFAULT NULL COMMENT '组号', `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户名', `password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '密码', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ------------------------------ Records of user-- ----------------------------INSERT INTO `user` VALUES (1, 1, 'zhangsan', '123456');INSERT INTO `user` VALUES (2, 1, 'lisi', '123456');INSERT INTO `user` VALUES (3, 1, 'wangwu', '123456');INSERT INTO `user` VALUES (4, 2, 'zhaoliu', '123456');INSERT INTO `user` VALUES (5, 2, 'sunqi', '123456');INSERT INTO `user` VALUES (6, 2, 'zhouba', '123456');
-- ------------------------------ Table structure for user_role-- ----------------------------DROP TABLE IF EXISTS `user_role`;CREATE TABLE `user_role` ( `id` int(0) NOT NULL COMMENT '主键', `user_id` int(0) NULL DEFAULT NULL COMMENT '用户ID', `role_id` int(0) NULL DEFAULT NULL COMMENT '角色ID', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ------------------------------ Records of user_role-- ----------------------------INSERT INTO `user_role` VALUES (1, 1, 1);INSERT INTO `user_role` VALUES (2, 1, 2);INSERT INTO `user_role` VALUES (3, 1, 3);INSERT INTO `user_role` VALUES (4, 2, 2);INSERT INTO `user_role` VALUES (5, 2, 3);INSERT INTO `user_role` VALUES (6, 3, 4);INSERT INTO `user_role` VALUES (7, 4, 4);INSERT INTO `user_role` VALUES (8, 5, 5);INSERT INTO `user_role` VALUES (9, 5, 6);INSERT INTO `user_role` VALUES (10, 6, 5);
SET FOREIGN_KEY_CHECKS = 1;三、示例项目基础配置
3.1 引入 Maven 相关依赖
这里是使用 Maven 进行相关依赖管理,引入的依赖如下:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> </parent>
<groupId>club.mydlq</groupId> <artifactId>springboot-mybatis-example</artifactId> <version>1.0.0</version> <name>springboot-mybatis-example</name> <description>springboot mybatis example project</description>
<properties> <java.version>1.8</java.version> </properties>
<dependencies> <!--web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <!--swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>依赖说明:
- spring-boot-starter-parent: SpringBoot 父依赖。
- spring-boot-starter-web: SpringBoot web 依赖。
- lombok: 项目集成组件,用于使用注解方式快速构建实体类对象的 Get、Set 和其他一些便捷方法。
- mysql-connector-java: 用于连接 Mysql 的驱动。
- mybatis-spring-boot-starter: SpringBoot 与 Mybatis 集成的依赖。
- springfox-swagger2: Swagger 组件,用于暴露项目的 API 信息,方便进行测试工作。
- springfox-swagger-ui: Swagger 组件,用于对 Swagger 暴露的项目 API 生成对应 WEB UI 页面。
3.2 配置相关参数
进入 application.yml 文件,配置数据库相关参数,内容如下:
spring: application: name: springboot-mybatis-example datasource: type: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/mybatis_example?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true hikari: pool-name: DatebookHikariCP minimum-idle: 5 maximum-pool-size: 15 max-lifetime: 1800000 connection-timeout: 30000 username: root password: 123456
mybatis: mapper-locations: classpath:mappers/*.xml参数说明:
- spring.datasource.type: 指定使用的数据库连接池。
- spring.datasource.driverClassName: 指定使用的数据库驱动。
- spring.datasource.url: 数据库地址。
- spring.datasource.username: 数据库用户名。
- spring.datasource.password: 数据库密码。
- spring.datasource.hikari.pool-name: 指定使用的数据库连接池。
- spring.datasource.hikari.minimum-idle: 连接池最小最小空闲连接。
- spring.datasource.hikari.maximum-pool-size: 连接池最大连接数。
- spring.datasource.hikari.max-lifetime: 连接池连接最大存活时间。
- spring.datasource.hikari.connection-timeout: 连接池连接超时时间。
- mybatis.mapper-locations: 指定 Mybatis Mapper xml 文件的位置。
3.3 单表实体类对象
数据库中每个表都有多个字段,需要提前在项目中创建与各个表字段关联的实体类,以方便后续数据库信息转换为 Java 对象,实体类如下:
Group.java
import lombok.Data;
@Datapublic class Group { /** 主键ID */ private Integer id; /** 组名 */ private String name;}User.java
import lombok.Data;
@Datapublic class User { /** 主键ID */ private Integer id; /** 组号 */ private Integer groupId; /** 用户名 */ private String username; /** 密码 */ private String password;}Role.java
import lombok.Data;
@Datapublic class Role { /** 主键ID */ private Integer id; /** 角色名称 */ private String name;}BaseInfo.java
import lombok.Data;import java.util.Date;
@Datapublic class BaseInfo { /** 主键ID */ private Integer id; /** 用户ID */ private String userId; /** 姓名 */ private String name; /** 性别 */ private String sex; /** 出生日期 */ private Date birthday; /** 备注 */ private String remark;}3.4 多表实体类对象
多表实体类对象指的是,将之前的单表实体聚合,然后一个实体对象参数中包含另一个实体对象的集合,方便后续多表查询演示,实体对象内容如下:
UserInfo.java
import club.mydlq.model.single.BaseInfo;import club.mydlq.model.single.User;import lombok.Data;import lombok.EqualsAndHashCode;
@Data@EqualsAndHashCode(callSuper = true)public class UserInfo extends User {
/** 用户基本信息 */ private BaseInfo baseInfo;
}GroupUser.java
import club.mydlq.model.single.Group;import club.mydlq.model.single.User;import lombok.Data;import lombok.EqualsAndHashCode;import java.util.List;
@Data@EqualsAndHashCode(callSuper = true)public class GroupUser extends Group {
/** 用户列表 */ private List<User> users;
}GroupUserRole.java
import club.mydlq.model.single.Group;import lombok.Data;import lombok.EqualsAndHashCode;import java.util.List;
@Data@EqualsAndHashCode(callSuper = true)public class GroupUserRole extends Group {
/** 用户角色列表 */ private List<UserRole> users;
}UserRole.java
import club.mydlq.model.single.Role;import club.mydlq.model.single.User;import lombok.Data;import lombok.EqualsAndHashCode;import java.util.List;
@Data@EqualsAndHashCode(callSuper = true)public class UserRole extends User {
/** 角色列表 */ private List<Role> roles;
}3.5 项目启动类
SpringBoot 项目的启动类。
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplicationpublic class Application {
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}四、示例项目 Mapper
按 Mybatis 的规则,在执行 Sql 语句进行数据库操作时,需要提前创建接口类来定义数据库操作方法,便于项目中其它类调用。然后还需要创建 xml 文件跟对应 Mapper 接口类绑定,实现接口中的方法,在里面按 Mybatis 规则写 SQL 语句。
4.1 单表 CURD 操作
“用户表”操作接口类:
import java.util.List;import club.mydlq.model.single.User;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;
@Mapperpublic interface UserMapper {
/** * 查询全部用户数据列表 * * @return 用户信息列表 */ List<User> selectAll();
/** * 根据主键ID查询用户 * * @param id 主键ID * @return 用户 */ User selectById(@Param("id") Integer id);
/** * 根据用户名模糊查询用户 * * @param username 用户名 * @return 用户 */ User selectByUsername(@Param("username") String username);
/** * 根据主键ID更新用户 * * @param user 用户实体对象 * @return 是否更新成功 */ Boolean updateById(@Param("user") User user);
/** * 插入用户 * * @param user 用户实体对象 * @return 是否插入成功 */ Boolean insert(@Param("user") User user);
/** * 插入用户并返回主键ID到实体对象 * * @param user 用户实体对象 * @return 是否插入成功 */ Boolean insertAndReturnId(@Param("user") User user);
/** * 根据主键ID删除用户信息 * * @param id 主键 * @return 是否删除成功 */ Boolean deleteById(@Param("id") Integer id);
}“用户表”操作 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">
<!--User 表操作,单表操作示例--><mapper namespace="club.mydlq.mappers.single.UserMapper">
<!--结果映射参数设置--> <resultMap id="UserResultMap" type="club.mydlq.model.single.User"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="group_id" jdbcType="INTEGER" property="groupId"/> <result column="password" jdbcType="VARCHAR" property="password"/> <result column="username" jdbcType="VARCHAR" property="username"/> </resultMap>
<!-- 查询全部用户列表 --> <select id="selectAll" resultMap="UserResultMap"> SELECT id, group_id, username, password FROM `user` </select>
<!--根据主键ID查询用户--> <select id="selectById" parameterType="java.lang.Integer" resultMap="UserResultMap"> SELECT id, group_id, username, password FROM `user` WHERE id = #{id, jdbcType=INTEGER} </select>
<!--根据用户名模糊查询用户--> <select id="selectByUsername" parameterType="java.lang.String" resultMap="UserResultMap"> SELECT id, group_id, username, password FROM `user` WHERE username LIKE concat('%', #{username, jdbcType=INTEGER}, '%') </select>
<!-- 插入用户 --> <insert id="insert" parameterType="club.mydlq.model.single.User"> INSERT INTO `user` <trim prefix="(" suffix=")" suffixOverrides=","> <if test="groupId != null">group_id,</if> <if test="username != null">username,</if> <if test="password != null">password,</if> </trim> <trim prefix="values(" suffix=")" suffixOverrides=","> <if test="groupId != null">#{groupId, jdbcType=INTEGER},</if> <if test="username != null">#{username, jdbcType=VARCHAR},</if> <if test="password != null">#{password, jdbcType=VARCHAR},</if> </trim> </insert>
<!-- 插入用户并返回主键ID --> <insert id="insertAndReturnId" parameterType="club.mydlq.model.single.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO `user` <trim prefix="(" suffix=")" suffixOverrides=","> <if test="groupId != null">group_id,</if> <if test="username != null">username,</if> <if test="password != null">password,</if> </trim> <trim prefix="values(" suffix=")" suffixOverrides=","> <if test="groupId != null">#{groupId, jdbcType=INTEGER},</if> <if test="username != null">#{username, jdbcType=VARCHAR},</if> <if test="password != null">#{password, jdbcType=VARCHAR},</if> </trim> </insert>
<!--更新用户--> <update id="updateById" parameterType="club.mydlq.model.single.User"> UPDATE `user` <set> <if test="groupId != null">group_id = #{groupId, jdbcType=INTEGER},</if> <if test="username != null">username = #{username, jdbcType=VARCHAR},</if> <if test="password != null">password = #{password, jdbcType=VARCHAR},</if> </set> WHERE id = #{id, jdbcType=INTEGER} </update>
<!-- 删除用户信息 --> <delete id="deleteById" parameterType="java.lang.Integer"> DELETE FROM `user` WHERE id = #{id, jdbcType=INTEGER} </delete>
</mapper>4.2 单表 CURD 批量操作
“用户表”批量操作接口类:
import club.mydlq.model.single.User;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import java.util.List;
/** * User 表批量操作 Mapper */@Mapperpublic interface UserBatchMapper {
/** * 批量查询用户 * * @param ids 用户ID列表 * @return 用户列表 */ List<User> selectBatch(@Param("ids") List<Integer> ids);
/** * 批量插入用户 * * @param userList 用户列表 * @return 是否插入成功 */ Boolean insertBatch(@Param("userList") List<User> userList);
/** * 批量更新用户 * * @param userList 用户列表 * @return 是否更新成功 */ Boolean updateBatch(@Param("userList") List<User> userList);
/** * 批量查询用户 * * @param ids 用户ID列表 * @return 用户列表 */ Boolean deleteBatch(@Param("ids") List<Integer> ids);
}“用户表”批量操作 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">
<!--User 表操作,单表操作示例--><mapper namespace="club.mydlq.mappers.single.UserBatchMapper">
<!--结果映射参数设置--> <resultMap id="UserResultMap" type="club.mydlq.model.single.User"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="group_id" jdbcType="INTEGER" property="groupId"/> <result column="password" jdbcType="VARCHAR" property="password"/> <result column="username" jdbcType="VARCHAR" property="username"/> </resultMap>
<!--批量查询--> <select id="selectBatch" parameterType="java.util.List" resultMap="UserResultMap"> SELECT id, group_id, username, password FROM `user` WHERE id IN <trim prefix="(" suffix=")"> <foreach collection="ids" index="index" item="id" separator=","> #{id} </foreach> </trim> </select>
<!-- 批量插入用户 --> <insert id="insertBatch" parameterType="java.util.List"> INSERT INTO `user` (`group_id`, `username`, `password`) VALUES <foreach collection="userList" item="user" index="index" separator=","> ( #{user.groupId, jdbcType=INTEGER}, #{user.username, jdbcType=VARCHAR}, #{user.password, jdbcType=VARCHAR} ) </foreach> </insert>
<!-- 批量更新用户 --> <update id="updateBatch" parameterType="java.util.List"> <foreach collection="userList" item="user" index="index" separator=";"> UPDATE `user` <set> <if test="user.groupId != null">group_id=#{user.groupId, jdbcType=INTEGER},</if> <if test="user.username != null">username=#{user.username, jdbcType=VARCHAR},</if> <if test="user.password != null">password=#{user.password, jdbcType=VARCHAR},</if> </set> WHERE id = #{user.id, jdbcType=INTEGER} </foreach> </update>
<!-- 批量删除用户信息 --> <delete id="deleteBatch" parameterType="java.util.List"> DELETE FROM `user` WHERE id IN <trim prefix="(" suffix=")"> <foreach collection="ids" index="index" item="id" separator=","> #{id} </foreach> </trim> </delete>
</mapper>4.3 多表一对一操作

“用户表”与”用户基本信息表”操作接口类:
import club.mydlq.model.many.UserInfo;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import java.util.List;
@Mapperpublic interface UserInfoMapper {
/** * 根据用户ID查询用户与用户基本信息 * * @param userId 用户ID * @return 用户与用户基本信息 */ UserInfo selectByUserId(@Param("userId") Integer userId);
/** * 查询全部用户与用户基本信息 * * @return 用户与基本信息列表 */ List<UserInfo> selectAll();
}“用户表”与”用户基本信息表”操作 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="club.mydlq.mappers.many.UserInfoMapper">
<!--结果映射参数设置--> <resultMap id="UserInfoResultMap" type="club.mydlq.model.many.UserInfo"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="group_id" jdbcType="INTEGER" property="groupId"/> <result column="username" jdbcType="VARCHAR" property="username"/> <result column="password" jdbcType="VARCHAR" property="password"/> <association property="baseInfo" javaType="club.mydlq.model.single.BaseInfo"> <id column="baseId" jdbcType="INTEGER" property="id"/> <result column="userId" jdbcType="INTEGER" property="userId"/> <result column="name" jdbcType="VARCHAR" property="name"/> <result column="sex" jdbcType="VARCHAR" property="sex"/> <result column="birthday" jdbcType="DATE" property="birthday"/> <result column="remark" jdbcType="VARCHAR" property="remark"/> </association> </resultMap>
<!-- 查询全部用户信息列表 --> <select id="selectAll" resultMap="UserInfoResultMap"> SELECT A.id, A.group_id, A.username, A.password, B.id AS baseId, B.user_id AS userId, B.name, B.sex, B.birthday, B.remark FROM `user` AS A, `base_info` AS B </select>
<!--查询用户信息--> <select id="selectByUserId" parameterType="java.lang.Integer" resultMap="UserInfoResultMap"> SELECT A.id, A.group_id, A.username, A.password, B.id AS baseId, B.user_id AS userId, B.name, B.sex, B.birthday, B.remark FROM `user` AS A, `base_info` AS B WHERE A.id = B.user_id AND A.id = #{userId, jdbcType=INTEGER} </select>
</mapper>4.4 多表一对多操作

“用户组表”与”用户表”操作接口类:
import club.mydlq.model.many.GroupUser;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;
@Mapperpublic interface GroupUserMapper {
/** * 根据组ID查询用户列表 * * @param groupId 组ID * @return 用户列表 */ GroupUser selectByGroupId(@Param("groupId") Integer groupId);
}“用户组表”与”用户表”操作 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="club.mydlq.mappers.many.GroupUserMapper">
<!--结果映射参数设置--> <resultMap id="GroupUserResultMap" type="club.mydlq.model.many.GroupUser"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="name" jdbcType="VARCHAR" property="name"/> <collection property="users" ofType="club.mydlq.model.single.User"> <id column="userId" jdbcType="INTEGER" property="id"/> <result column="group_id" jdbcType="INTEGER" property="groupId"/> <result column="username" jdbcType="VARCHAR" property="username"/> <result column="password" jdbcType="VARCHAR" property="password"/> </collection> </resultMap>
<!-- 查询某个组与组内用户列表 --> <select id="selectByGroupId" parameterType="java.lang.Integer" resultMap="GroupUserResultMap"> SELECT A.id,A.name, B.id AS userId, B.group_id, B.username, B.password FROM `group` AS A, `user` AS B WHERE A.id = B.group_id AND A.id = #{groupId, jdbcType=INTEGER} </select>
</mapper>4.5 多表一对多对多操作

“用户组表”、“用户表”、“角色表”与”用户角色表”操作接口类:
import club.mydlq.model.many.GroupUserRole;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import java.util.List;
@Mapperpublic interface GroupUserRoleMapper {
/** * 根据组ID查找某个用户组下的全部用户与用户关联角色信息 * * @param groupId 组ID * @return 用户与用户角色信息列表 */ List<GroupUserRole> selectUserAndRoleByGroupId(@Param("groupId") Integer groupId);
}“用户组表”、“用户表”、“角色表”与”用户角色表”操作 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="club.mydlq.mappers.many.GroupUserRoleMapper">
<!--结果映射参数设置--> <resultMap id="GroupUserRoleResultMap" type="club.mydlq.model.many.GroupUserRole"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="name" jdbcType="VARCHAR" property="name"/> <collection property="users" ofType="club.mydlq.model.many.UserRole"> <id column="userId" jdbcType="INTEGER" property="id"/> <result column="group_id" jdbcType="INTEGER" property="groupId"/> <result column="username" jdbcType="VARCHAR" property="username"/> <result column="password" jdbcType="VARCHAR" property="password"/> <collection property="roles" ofType="club.mydlq.model.single.Role"> <id column="roleId" jdbcType="INTEGER" property="id"/> <result column="roleName" jdbcType="VARCHAR" property="name"/> </collection> </collection> </resultMap>
<!--根据用户组ID查询用户和用户关联的全部角色--> <select id="selectUserAndRoleByGroupId" parameterType="java.lang.Integer" resultMap="GroupUserRoleResultMap"> select A.id, A.name, B.id AS userId, B.group_id, B.username, B.password, C.id AS roleId, C.name AS roleName FROM `group` AS A, `user` AS B, `role` AS C, `user_role` AS D WHERE A.id = B.group_id AND B.id = D.user_id AND C.id = D.role_id AND A.id = #{groupId, jdbcType=INTEGER} </select>
</mapper>五、示例项目测试 Controller
5.1 创建 Swagger 配置类
import com.google.common.base.Predicates;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration@EnableSwagger2public class SwaggerConfig {
@Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .paths(Predicates.not(PathSelectors.regex("/error.*"))) .paths(Predicates.not(PathSelectors.regex("/actuator.*"))) .build(); }
private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("springboot 集成 mybatis") .description("springboot 集成 mybatis 示例接口") .version("1.0.0") .build(); }
}5.2 创建用于测试的 Controller 类
UserController.java(用户接口,单表操作)
import club.mydlq.mappers.single.UserMapper;import club.mydlq.model.single.User;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
@RestController@RequestMapping("/user")@Api(tags = "用户接口(单表操作)")public class UserController {
@Resource private UserMapper userMapper;
@GetMapping("/all") @ApiOperation(value = "查询全部\"用户\"", notes = "测试查询全部\"用户\"。") public Object getUserAll() { return userMapper.selectAll(); }
@GetMapping("/{id}") @ApiOperation(value = "查询\"用户\"", notes = "测试查询\"用户\"。") public Object getUser(@PathVariable Integer id) { return userMapper.selectById(id); }
@GetMapping("/username/{username}") @ApiOperation(value = "根据\"用户名\"查询\"用户\"", notes = "测试根据\"用户名\"查询\"用户\"。") public Object getUserByUsername(@PathVariable String username){ return userMapper.selectByUsername(username); }
@PostMapping @ApiOperation(value = "插入\"用户\"", notes = "测试插入\"用户\"。") public Object saveUser(@RequestBody User user) { return userMapper.insert(user); }
@PostMapping("/return") @ApiOperation(value = "插入\"用户\"并且返回\"主键ID\"", notes = "测试插入\"用户\"并且返回\"主键ID\"。") public Object saveUserAndReturnId(@RequestBody User user) { boolean inserted = userMapper.insertAndReturnId(user); if (inserted){ return user.getId(); } return "插入失败"; }
@PutMapping @ApiOperation(value = "更新\"用户\"", notes = "测试更新\"用户\"。") public Object updateUser(@RequestBody User user) { return userMapper.updateById(user); }
@DeleteMapping("/{id}") @ApiOperation(value = "删除\"用户\"", notes = "测试删除\"用户\"。") public Object deleteUser(@PathVariable Integer id) { return userMapper.deleteById(id); }
}UserBatchController.java(用户接口,单表批量操作)
import club.mydlq.mappers.single.UserBatchMapper;import club.mydlq.model.single.User;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import java.util.List;
@RestController@RequestMapping("/userBatch")@Api(tags = "用户接口(单表批量操作)")public class UserBatchController {
@Resource private UserBatchMapper userBatchMapper;
@PostMapping("/find") @ApiOperation(value = "批量查询\"用户\"", notes = "测试批量查询\"用户\"。") public Object getUserBatch(@RequestBody List<Integer> ids) { return userBatchMapper.selectBatch(ids); }
@PostMapping("/save") @ApiOperation(value = "批量插入\"用户\"", notes = "测试批量插入\"用户\"") public Object saveUserBatch(@RequestBody List<User> userList) { return userBatchMapper.insertBatch(userList); }
@PutMapping("/update") @ApiOperation(value = "批量更新\"用户\"", notes = "测试批量更新\"用户\"") public Object updateUserBatch(@RequestBody List<User> userList) { return userBatchMapper.updateBatch(userList); }
@DeleteMapping("/delete") @ApiOperation(value = "批量删除\"用户\"", notes = "测试批量删除\"用户\"") public Object deleteUserBatch(@RequestBody List<Integer> ids) { return userBatchMapper.deleteBatch(ids); }
}UserInfoController.java(用户与用户信息接口,多表查询,一对一)
import club.mydlq.mappers.many.UserInfoMapper;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
@RestController@RequestMapping("/userInfo")@Api(tags = "用户与用户信息接口(多表查询,一对一)")public class UserInfoController {
@Resource private UserInfoMapper userInfoMapper;
@GetMapping("/all") @ApiOperation(value = "查询全部\"用户与用户信息\"列表", notes = "测试查询全部\"用户与用户信息\"列表。") public Object getUserInfoAll() { return userInfoMapper.selectAll(); }
@GetMapping("/{userId}") @ApiOperation(value = "查询某个\"用户与用户信息\"", notes = "测试查询某个\"用户与用户信息。") public Object getUserInfo(@PathVariable Integer userId) { return userInfoMapper.selectByUserId(userId); }
}GroupUserController.java(组与用户接口(多表操作,一对多))
import club.mydlq.mappers.many.GroupUserMapper;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
@RestController@RequestMapping("/groupUser")@Api(tags = "组与用户接口(多表操作,一对多)")public class GroupUserController {
@Resource private GroupUserMapper groupUserMapper;
@GetMapping("/{userId}") @ApiOperation(value = "查询某组\"用户\"列表", notes = "测试查询某组\"用户\"列表。") public Object getUserInfo(@PathVariable Integer userId) { return groupUserMapper.selectByGroupId(userId); }
}GroupUserRoleController.java(组、用户与角色接口,多表查询,一对一对多)
import club.mydlq.mappers.many.GroupUserRoleMapper;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
@RestController@RequestMapping("/GroupUserRole")@Api(tags = "组、用户与角色接口(多表查询,一对一对多)")public class GroupUserRoleController {
@Resource private GroupUserRoleMapper groupUserRoleMapper;
@GetMapping("/{groupId}") @ApiOperation(value = "查询某组\"用户与角色\"列表", notes = "测试查询某组\"用户与角色\"列表。") public Object getUserInfo(@PathVariable Integer groupId) { return groupUserRoleMapper.selectUserAndRoleByGroupId(groupId); }
}六、 启动项目进行测试
访问 Swagger 页面,对各个接口进行测试:

