【Spring Boot】MyBatis多表查询的操作:注解和XML实现SQL语句

发布于:2025-05-01 ⋅ 阅读:(63) ⋅ 点赞:(0)

1.准备工作

1.1创建数据库

(1)创建数据库:

CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;

(2)使用数据库

-- 使⽤数据数据
USE mybatis_test;

1.2 创建用户表和实体类

创建用户表


-- 创建表[⽤⼾表]

CREATE TABLE `user_info` (
 `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
 `username` VARCHAR ( 127 ) NOT NULL,
 `password` VARCHAR ( 127 ) NOT NULL,
 `age` TINYINT ( 4 ) NOT NULL,
 `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
 `phone` VARCHAR ( 15 ) DEFAULT NULL,
 `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
 `create_time` DATETIME DEFAULT now(),
 `update_time` DATETIME DEFAULT now() ON UPDATE now(),
 PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 

添加用户信息

-- 添加⽤⼾信息
INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

实体类的属性名与表中的字段名⼀⼀对应

@Data
public class UserInfo {

    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;

}

1.3 创建文章表和实体类

上⾯建了⼀张⽤⼾表, 我们再来建⼀张⽂章表, 进⾏多表关联查询.
⽂章表的uid, 对应⽤⼾表的id.

创建文章表:

-- 创建⽂章表
DROP TABLE IF EXISTS articleinfo;
CREATE TABLE articleinfo (
id INT PRIMARY KEY auto_increment, title VARCHAR ( 100 ) NOT NULL,
content TEXT NOT NULL, uid INT NOT NULL,
delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
create_time DATETIME DEFAULT now(), update_time DATETIME DEFAULT now()
) DEFAULT charset 'utf8mb4';

插入数据

-- 插⼊测试数据
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正文', 1
);
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'MySQL', 'MySQL正文', 1
);
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'C', 'C正文', 2
);

实体类的属性名与表中的字段名⼀⼀对应

@Data
public class ArticleInfo { 
	private Integer id; 
	private String title; 
	private String content; 
	private Integer uid; 
	private Integer deleteFlag; 
	private Date createTime; 
	private Date updateTime;
}

1.4 配置文件

Application.yml文件中配置:

# 数据库连接配置
spring:
  datasource:
    
    # MySQL在远程服务器上
    url: jdbc:mysql://x.x.x.x:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root  #MySQL账号
    password: root  #MySQL密码
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  configuration: # 配置打印 MyBatis⽇志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true #配置驼峰⾃动转换
    
  # 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
  mapper-locations: classpath:mapper/**Mapper.xml

1.5 依赖添加

		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>
        
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <version>2.2.2</version>
            <scope>test</scope>
        </dependency>

2.多表查询

2.1 需求: 根据uid查询书的作者等相关信息

2.1.1 注解实现

SQL命令:

SELECT
	a.id,
	a.title,
	a.content,
	a.uid,
	b.username,
	b.age,
	b.gender
FROM
	articleinfo a
	LEFT JOIN user_info b ON a.uid = b.id
WHERE
	a.id =1;

根据查询的结果在ArticleInfo 类补充相关的属性:

@Data
public class ArticleInfo {
	private Integer id;
	private String title;
	private String content;
	private Integer uid;
	private Integer deleteFlag;
	private Date createTime;
	private Date updateTime;
	// 补充⽤⼾相关信息
	private String username;
	private Integer age;
	private Integer gender;
 }

ArticleInfoMapper接口:

@Mapper
public interface ArticleInfoMapper {

    @Select("select a.id,a.title,a.content,a.uid, b.username, b.age, b.gender " + // 注意最后的空格
            "from articleinfo a left join user_info b on a.uid=b.id " +
            "where a.id = #{id}")
    ArticleInfo queryArticleAndUser(Integer id);
}

测试代码:

@Slf4j
@SpringBootTest
class ArticleInfoMapperTest {

    @Autowired
    private ArticleInfoMapper articleInfoMapper;

    @Test
    void queryArticleAndUser() {
        articleInfoMapper.queryArticleAndUser(1);
    }
}

运行结果:
在这里插入图片描述
如果名称不⼀致的, 采⽤Results, 或者别名的⽅式解决, 和单表查询⼀样 Mybatis 不分单表还是多表, 主要就是三部分: SQL, 映射关系和实体类

2.1.2 XML实现

SQL命令:

SELECT
	a.id,
	a.title,
	a.content,
	a.uid,
	b.username,
	b.age,
	b.gender
FROM
	articleinfo a
	LEFT JOIN user_info b ON a.uid = b.id
WHERE
	a.id =1;

根据查询的结果在ArticleInfo 类补充相关的属性:

@Data
public class ArticleInfo {
	private Integer id;
	private String title;
	private String content;
	private Integer uid;
	private Integer deleteFlag;
	private Date createTime;
	private Date updateTime;
	// 补充⽤⼾相关信息
	private String username;
	private Integer age;
	private Integer gender;
 }

ArticleInfoMapper接口:

@Mapper
public interface ArticleInfoXMLMapper {
    ArticleInfo queryArticleAndUser(Integer id);
}

ArticleInfoXMLMapper.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="org.example.mybatis.mapper.ArticleInfoXMLMapper">


    <select id ="queryArticleAndUser" resultType="org.example.mybatis.model.ArticleInfo">
        select a.id,a.title,a.content,a.uid, b.username, b.age, b.gender
            from articleinfo a left join user_info b on a.uid=b.id
            where a.id = #{id}
    </select>

</mapper>

测试代码:

@Slf4j
@SpringBootTest
class ArticleInfoXMLMapperTest {

    @Autowired
    private ArticleInfoXMLMapper articleInfoXMLMapper;

    @Test
    void queryArticleAndUser() {
        articleInfoXMLMapper.queryArticleAndUser(1);
    }
}

运行结果:
在这里插入图片描述

如果名称不⼀致的, 采⽤ResultMap, 或者别名的⽅式解决, 和单表查询⼀样 Mybatis 不分单表还是多表, 主要就是三部分: SQL, 映射关系和实体类

2.2 需求: 根据user_in的id查询作者创作的书相关信息

2.1.1 注解实现

SQL命令:

SELECT
	b.username,
	b.age,
	b.gender,
	a.id,
	a.title,
	a.content,
	a.uid
FROM
	articleinfo a
	RIGTH JOIN user_info  b ON b.uid = a.id
WHERE
	b.id =1;

根据查询的结果在ArticleInfo 类补充相关的属性:

@Data
public class ArticleInfo {
	private Integer id;
	private String title;
	private String content;
	private Integer uid;
	private Integer deleteFlag;
	private Date createTime;
	private Date updateTime;
	// 补充⽤⼾相关信息
	private String username;
	private Integer age;
	private Integer gender;
 }

ArticleInfoMapper接口:

@Mapper
public interface ArticleInfoMapper {
    @Select("select b.username, b.age,b.gender,a.id,a.title,a.content,a.uid " + // 注意最后的空格
            "from articleinfo a right join user_info b on a.uid=b.id " +
            "where b.id = #{id}")
    List<ArticleInfo> queryArticleAndUser(Integer id);
}

测试代码:

@Slf4j
@SpringBootTest
class ArticleInfoMapperTest {

    @Autowired
    private ArticleInfoMapper articleInfoMapper;

    @Test
    void queryArticleAndUser() {
        articleInfoMapper.queryArticleAndUser(1);
    }
}

运行结果:
在这里插入图片描述

如果名称不⼀致的, 采⽤Results, 或者别名的⽅式解决, 和单表查询⼀样 Mybatis 不分单表还是多表, 主要就是三部分: SQL, 映射关系和实体类

2.1.2 XML实现

SQL命令:

SELECT
	b.username,
	b.age,
	b.gender,
	a.id,
	a.title,
	a.content,
	a.uid
FROM
	articleinfo a
	RIGHT JOIN user_info b ON a.uid = b.id
WHERE
	a.id =1;

根据查询的结果在ArticleInfo 类补充相关的属性:

@Data
public class ArticleInfo {
	private Integer id;
	private String title;
	private String content;
	private Integer uid;
	private Integer deleteFlag;
	private Date createTime;
	private Date updateTime;
	// 补充⽤⼾相关信息
	private String username;
	private Integer age;
	private Integer gender;
 }

ArticleInfoMapper接口:

@Mapper
public interface ArticleInfoXMLMapper {
    List<ArticleInfo> queryArticleAndUser(Integer id);
}

ArticleInfoXMLMapper.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="org.example.mybatis.mapper.ArticleInfoXMLMapper">


    <select id ="queryArticleAndUser" resultType="org.example.mybatis.model.ArticleInfo">
        select b.username, b.age, b.gender,a.id,a.title,a.content,a.uid
            from articleinfo a right join user_info b on a.uid=b.id
            where b.id = #{id}
    </select>

</mapper>

测试代码:

@Slf4j
@SpringBootTest
class ArticleInfoXMLMapperTest {

    @Autowired
    private ArticleInfoXMLMapper articleInfoXMLMapper;

    @Test
    void queryArticleAndUser() {
        articleInfoXMLMapper.queryArticleAndUser(1);
    }
}

运行结果:
在这里插入图片描述

如果名称不⼀致的, 采⽤ResultMap, 或者别名的⽅式解决, 和单表查询⼀样 Mybatis 不分单表还是多表, 主要就是三部分: SQL, 映射关系和实体类


网站公告

今日签到

点亮在社区的每一天
去签到