Singerw's Repository Singerw's Repository
首页
  • 相关文章

    • HTML相关文章
    • CSS相关文章
    • JavaScript相关文章
  • 学习笔记

    • JavaScript笔记
    • ES6笔记
    • Vue笔记
  • 相关文章

    • Spring相关文章
    • SpringBoot相关文章
    • MyBatis相关文章
    • MySQL相关文章
  • 学习笔记

    • SpringBoot笔记
    • Spring笔记
    • MyBatis笔记
    • MySQL笔记
    • JavaWeb笔记
    • JavaCore笔记
  • 学习笔记

    • Linux笔记
    • Git笔记
    • 技术文档
  • 偏门技术

    • GitHub技巧
    • 博客搭建
    • 科学上网
  • 安装教程

    • JDK
    • MySQL
    • Node.js
    • Linux
  • 终身学习
  • 面试人生
  • 心情杂货
  • 生活随笔
  • 归档
  • 标签
GitHub (opens new window)

Singerw

谁能够凭爱意将富士山私有
首页
  • 相关文章

    • HTML相关文章
    • CSS相关文章
    • JavaScript相关文章
  • 学习笔记

    • JavaScript笔记
    • ES6笔记
    • Vue笔记
  • 相关文章

    • Spring相关文章
    • SpringBoot相关文章
    • MyBatis相关文章
    • MySQL相关文章
  • 学习笔记

    • SpringBoot笔记
    • Spring笔记
    • MyBatis笔记
    • MySQL笔记
    • JavaWeb笔记
    • JavaCore笔记
  • 学习笔记

    • Linux笔记
    • Git笔记
    • 技术文档
  • 偏门技术

    • GitHub技巧
    • 博客搭建
    • 科学上网
  • 安装教程

    • JDK
    • MySQL
    • Node.js
    • Linux
  • 终身学习
  • 面试人生
  • 心情杂货
  • 生活随笔
  • 归档
  • 标签
GitHub (opens new window)
  • MyBatis学习笔记

    • 《MyBatis》学习笔记
    • MyBatis简介
    • 第一个MyBatis程序
    • 生命周期和作用域
    • 配置文件之基本优化
    • XML实现CRUD
    • Annotation实现CRUD
    • 万能Map
    • Mapper-XML文件
    • ResultMat的使用
      • 1、简单结果集映射
      • 2、Association完整案例
        • 步骤一、编写实体类
        • 步骤二、实现数据查询操作
        • 步骤三、编写查询方法接口
        • 步骤四、编写mapper.xml中的ResultMap
        • 步骤五、进行单元测试
      • 3、Collection节点案例
        • 步骤一、编写实体类
        • 步骤二、实现数据查询操作
        • 步骤三、编写查询方法接口
        • 步骤四、编写mapper.xml中的ResultMap
        • 步骤五、进行单元测试
      • 4、ResultMap使用常见问题
    • 实现日志功能
    • MyBatis动态SQL
    • 实现分页功能
    • MyBatis缓存
    • MyBatis中配置文件示例
    • MyBatis工具类
    • generator插件自动生成代码
  • MyBatis-Plus学习笔记

  • 《MyBatis》学习笔记
  • MyBatis学习笔记
Singerw
2021-09-25

ResultMat的使用

# ResultMat的使用🌊

  • resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。
  • 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

# 1、简单结果集映射

解决属性名和字段名不一致的问题

【示例】数据库中的User表字段

  • userid
  • username
  • userphone
  • userpassword
  • jurisdiction
  • createtime
  • logintime
  • userstatus

数据库中的字段和实体类中的字段不一致。

【示例】User.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private int id;
    private String name;
    private String phone;
    private String password;
    private int juri;
    private String created;
    private String logined;
    private int status;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

使用结果集映射

【示例】UserMapper.xml

<mapper namespace="com.singerw.mapper.UserMapper">
    <!--查询所有用户-->
    <select id="getUsers" resultMap="userMap">
        select *
        from goku.g_users
    </select>

    <!--根据ID查询用户-->
    <select id="getUser" resultMap="userMap">
        select *
        from goku.g_users
        where userid = #{userid}
    </select>

    <!--resultMap结果集映射-->
    <resultMap id="userMap" type="User">
        <!-- 实体类和表列做关联-->
        <!-- id 主键 属性 -->
        <id property="id" column="userid"></id>
        <!--其他部分-->
        <!--column数据库中的字段,property实体类中的属性-->
        <result property="name" column="username"></result>
        <result property="phone" column="userphone"></result>
        <result property="password" column="userpassword"></result>
        <result property="jurisdiction" column="jurisdiction"></result>
        <result property="juri" column="createtime"></result>
        <result property="created" column="createtime"></result>
        <result property="logined" column="logintime"></result>
        <result property="status" column="userstatus"></result>
    </resultMap>

</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

【示例】UserMapperTest.java

public class UserMapperTest {

    private SqlSession sqlSession = MyBatisUtils.getSqlSession();
    private UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    @Test
    public void getUsers() {
        List<User> users = userMapper.getUsers();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }

    @Test
    public void getUser() {
        User user = userMapper.getUser(2);
        System.out.println(user);
        sqlSession.close();
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 2、Association完整案例

一个复杂类型的关联,按照结果嵌套查询,多对一。

🌊(以1:N为案例关联映射)🌊

​ 在数据库设计中,普遍存在一对多,多对一的表关系。blogdb数据库中三个基本表结构如下 。

在数据库表设计的过程中,建立了如上的表结构,那么到程序设计中,实体类应该怎么写呢?

一个作者可以发表多篇文章,而发表的这些多篇文章只能有一个作者,这里文章和作者是1:N的关系。

Article(N):如果需要得到一篇或多篇文章的作者,需要在实体类中增加一个类型。

private Users users
1

User(1):在user表中查询某一用户的时候,同时想得到这个用户发表了哪些文章,需要在实体类中增加一个集合。

private List<Article> articleList
1

通过关键字或者文章ID查询一篇或多篇文章和每篇文章的作者信息

# 步骤一、编写实体类

【实体类示例】:Article.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Article {
    private int id;
    private String title;
    private String content;
    private String summary;
    private int cid;
    private Users users;
    private String created;
    private int status;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

【实体类示例】:Users.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
    private int id;
    private String username;
    private String nickname;
    private String password;
    private int status;
    private String email;
    private String userface;
    private String created;
    private String lastlogin;
    private List<Article> articleList;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 步骤二、实现数据查询操作

【SQL语句示例】

<!--使用了resultMap,需要在xml中创建一个id为articleMap的resultMap-->
<select id="getArticles" resultMap="articleMap">
        SELECT article.id,
               article.title,
               article.content,
               article.summary,
               article.created,
               article.`status`,
               `user`.id AS uid,
               `user`.username,
               `user`.nickname
        FROM article
                 INNER JOIN `user` ON article.uid = `user`.id
        WHERE article.title LIKE #{title}
    </select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 步骤三、编写查询方法接口

【查询方法示例】:ArticleMapper.java

public interface ArticleMapper {

    List<Article> getArticles(String title);
}
1
2
3
4

# 步骤四、编写mapper.xml中的ResultMap

【ResultMap关联示例】:ArticleMapper.xml

<!-- 映射关系的管理和定义 ,type指的是实体类型(取了别名),id当前的resultMap的名字 -->
<resultMap type="Article" id="articleMap">
    <!-- 主键使用id -->
    <id property="id" column="id"/>
    <!-- 一个result表示一个列和实体类的属性的对应关系 -->
    <result property="title" column="title"/>
    <result property="content" column="content"/>
    <result property="summary" column="summary"/>
    <result property="created" column="created"/>
    <result property="status" column="status"/>
    <!-- 此时我们的Article类中,增加了一个Users类型的属性 -->
    <association property="users" column="uid" javaType="com.singerw.pojo.Users">
        <!-- author类对应的表中的列 和 类属性关联 -->
        <id property="id" column="uid"/>
        <result property="username" column="username"/>
        <result property="nickname" column="nickname"/>
    </association>
</resultMap>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 步骤五、进行单元测试

public class ArticleMapperTest {

    @Test
    public void getArticles() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        List<Article> articles = mapper.getArticles("%VUE%");
        articles.forEach(System.out::println);
    }
}
1
2
3
4
5
6
7
8
9
10

Article(id=2, title=VUE, content=VUE是极简的前端框架, summary=vue, category=null, users=Users(id=1, username=tom, nickname=唐木松, password=null, status=0, email=null, userface=null, created=null, lastlogin=null, articleList=null, categoriesList=null), created=2020-12-25 01:20:20, status=1)

# 3、Collection节点案例

一个复杂类型的集合。按照结果嵌套查询,一对多。

🌊(以1:N为案例关联映射)🌊

​ 在数据库设计中,普遍存在一对多,多对一的表关系。blogdb数据库中三个基本表结构如下 。

在数据库表设计的过程中,建立了如上的表结构,那么到程序设计中,实体类应该怎么写呢?

一个作者可以发表多篇文章,而发表的这些多篇文章只能有一个作者,这里文章和作者是1:N的关系。

Article(N):如果需要得到一篇或多篇文章的作者,需要在实体类中增加一个类型。

private Users users
1

User(1):在user表中查询某一用户的时候,同时想得到这个用户发表了哪些文章,需要在实体类中增加一个集合。

private List<Article> articleList
1

通过用户ID查询用户和用户发表的文章

# 步骤一、编写实体类

【实体类示例】:Article.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Article {
    private int id;
    private String title;
    private String content;
    private String summary;
    private int cid;
    private Users users;
    private String created;
    private int status;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

【实体类示例】:Users.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
    private int id;
    private String username;
    private String nickname;
    private String password;
    private int status;
    private String email;
    private String userface;
    private String created;
    private String lastlogin;
    private List<Article> articleList;
    private List<Category> categoriesList;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 步骤二、实现数据查询操作

【SQL语句示例】

SELECT `user`.id       AS userid,
               `user`.username,
               `user`.nickname,
               `user`.`password`,
               `user`.`status` AS userstatus,
               `user`.email,
               `user`.userface,
               `user`.created  AS user_created,
               `user`.lastlogin,
               article.id      AS articleid,
               article.title,
               article.content,
               article.summary,
               article.created,
               article.STATUS  AS articlestatus
        FROM `user`
                 INNER JOIN article ON `user`.id = article.uid
        WHERE `user`.id = #{id}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 步骤三、编写查询方法接口

【查询方法示例】:UsersMapper.java

public interface UsersMapper {

    <List>Users getUserAndArticle(int id);
}
1
2
3
4

# 步骤四、编写mapper.xml中的ResultMap

【ResultMap关联示例】:UsersMapper.xml

<!-- 映射关系的管理和定义 ,type指的是实体类型,id当前的resultMap的名字 -->
<resultMap type="Users" id="userMap2">
    <!-- 主键使用id -->
    <id property="id" column="userid"/>
    <!-- 一个result表示一个列和实体类的属性的对应关系 -->
    <result property="username" column="username"/>
    <result property="nickname" column="nickname"/>
    <result property="password" column="password"/>
    <result property="status" column="userstatus"/>
    <result property="email" column="email"/>
    <result property="userface" column="userface"/>
    <result property="created" column="user_created"/>
    <result property="lastlogin" column="lastlogin"/>

    <collection property="articleList" ofType="Article">
        <id property="id" column="articleid"/>
        <result property="title" column="title"/>
        <result property="content" column="content"/>
        <result property="summary" column="summary"/>
        <result property="created" column="category_created"/>
        <result property="status" column="articlestatus"/>
    </collection>
</resultMap>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 步骤五、进行单元测试

public class UsersMapperTest {

    @Test
    public void getUserAndArticle() {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
        Users user = mapper.getUserAndArticle(2);
        System.out.println(user);
    }
}
1
2
3
4
5
6
7
8
9
10

Users(id=2, username=jerry, nickname=吴八阁, password=e10adc3949ba59abbe56e057f20f883e, status=1, email=jerry@qq.com, userface=jerry.jpg, created=2021-01-08 01:01:22, lastlogin=2020-12-08 01:01:22, articleList=[Article(id=1, title=SpringBoot, content=SpringBoot是spring全家桶中很重要的一员, summary=spring, category=null, users=null, created=null, status=1), Article(id=5, title=MySQL, content=VUE是极简的前端框架, summary=vue, category=null, users=null, created=null, status=1), Article(id=7, title=Dubbo, content=VUE是极简的前端框架, summary=vue, category=null, users=null, created=null, status=1), Article(id=8, title=RabbitMQ, content=VUE是极简的前端框架, summary=vue, category=null, users=null, created=null, status=1), Article(id=10, title=Oracle, content=VUE是极简的前端框架, summary=vue, category=null, users=null, created=null, status=1), Article(id=12, title=Layui, content=VUE是极简的前端框架, summary=vue, category=null, users=null, created=null, status=1)], categoriesList=null)

# 4、ResultMap使用常见问题

1、使用别名时,要创建别名

<resultMap type="Users" id="userMap2">
1
<!-- 别名 -->
<typeAliases>
    <typeAlias type="com.singerw.pojo.Users" alias="Users" />
</typeAliases>
1
2
3
4

2、使用resultMap时需要先创建一个resultMap

<select id="getCategoryAndArticle" resultMap="categoryMap">
    ...
</select>
1
2
3
<resultMap id="categoryMap" type="Category">
   ...
</resultMap>
1
2
3

3、resultMap中的每张表都要求都有主键

 <id property="id" column="id"/>
1
<resultMap id="categoryMap" type="Category">
    <!--主键-->
    <id property="id" column="id"/>
    <!--其他部分-->
    <result property="catename" column="catename"/>
    ...
    <collection property="articleList" ofType="Article">
        <result property="id" column="art_id"/>
       ...
    </collection>
</resultMap>
1
2
3
4
5
6
7
8
9
10
11

4、result中property需要实体类中的属性名,column是表中的类名。

<result property="id" column="art_id"/>
1

5、JavaType:是用来指定实体类中属性的类型。

6、ofType:是用来指定映射到List或者集合中的实体类类型,泛型中的约束类型!

编辑 (opens new window)
#MyBatis
Mapper-XML文件
实现日志功能

← Mapper-XML文件 实现日志功能→

最近更新
01
Maven资源导出问题终极版
10-12
02
《MyBatis-Plus》学习笔记
10-07
03
MyBatis-Plus—配置日志
10-07
更多文章>
Theme by Vdoing | Copyright © 2020-2021 版权所有 | repository.singerw.com
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×