Mybatis中强大的resultMap功能介绍

Mybatis中强大的resultMap功能介绍

本文主要介绍Mybatis中强大的resultMap函数的相关信息。通过示例代码进行了非常详细的介绍,对大家学习或使用Mybatis有一定的参考价值。有需要的话一起学吧。

前言

在Mybatis中,有一个强大的功能元素resultMap。当我们想要将JDBC结果集中的数据转换成合理的Java对象时,您可以感受到它非凡的特性。正如其官员所说:

resultMap元素是MyBatis中最重要和最强大的元素。它可以把你从90%的JDBC结果集数据提取代码中解放出来,在某些情况下,允许你做一些JDBC不支持的操作。事实上,在为一些复杂的语句(如连接)编写映射代码时,一个resultMap可以用相同的函数替换数千行代码。ResultMap的设计思想是,对于简单的语句,不需要配置显式的结果映射,对于更复杂的语句,只需要描述它们之间的关系。

一、字段映射

在Mybatis中,映射结果的最简单方法是通过typeAliases来处理它。

如果要这样做,那么第一步是配置实体类包的路径:

my batis . type-aliases-package=com . XXX . entity

该路径下的所有类都将在TYPE_ALIASES容器中注册。当我们指定返回值类型时,我们可以只使用别名。

例如,我们有一个用户类:

@数据

公共类用户{

私有字符串id;

私有字符串用户名;

私有字符串密码;

私有字符串地址;

私人字符串电子邮件;

}

如果数据库中表的字段与用户类的属性名一致,我们可以使用resultType将其返回。

select id= get users result type= User

挑选

u.id,

用户名,

密码,

u .地址,

电子邮件

用户u

/选择

当然,这是属性和字段名完全相同的理想情况。但实际上有一些不一致的地方。这时候我们的resultMap就要出现了。

如果用户类保持不变,但SQL语句发生了变化,则id将更改为uid。

select id= get users result type= User

挑选

u.id作为uid,

用户名,

密码,

u .地址,

电子邮件

用户u

/选择

然后,在结果集中,我们将丢失id数据。这时,我们可以定义一个resultMap来映射不同的字段。

结果映射id=getUserByIdMap type=User

结果属性=id 列=uid/result

/结果映射

然后,我们将上面select语句中的resultType修改为resultMap=getUserByIdMap 。

这里的列对应于数据库的列名或别名;属性对应于结果集的字段或属性。

这是resultMap最简单也是最基本的用法:字段映射。

下面,我们来看看其他几个标签是如何应用的。

元素名称

形容

构造器

当用于实例化一个类时,结果被注入构造方法。

联合

关联一个对象。

收藏品

关联多个对象

二、构造方法

如果要将结果注入到构造函数中,可以使用constructor元素。

例如,我们的用户类添加了一个构造方法:

公共用户(字符串id,字符串名称){

this . id=id -;

this . username=name -;

}

我们需要在resultMap中定义构造函数元素:

结果映射id=getUserByIdMap type=User

构造器

idArg column= id name= id Java type= string /idArg

arg column= username name= name Java type= string /arg

/构造函数

/结果映射

列表示数据库字段名或别名;Name是构造函数中的参数名;JavaType指定参数的类型。

可以想象,以这种方式指定构造方法后,我们的结果集中的id和username属性会发生变化。

{

id: 1001 -,

用户名:后羿-,

密码: 123456 ,

地址,北京市海淀区,

电子邮件: 510273027@qq.com

}

三、关联

在实际业务中,我们的用户一般都有一个角色。那么用户类一般用实体类来表示。

@数据

公共类用户{

//省略用户属性.

//角色信息

私人角色角色;

}

当我们查询用户时,如果我们还想查看其角色信息,我们将编写这样的查询语句:

select id= getuser byid result type= User

挑选

u.id,

用户名,

密码,

u .地址,

电子邮件,

r.id为 role_id ,

r.name为“角色名称”

用户u

在u.id=ur.user_id上左连接user_roles ur

r.id=ur.role_id上的左联接角色r

其中u.id=#{id}

/选择

如上所述,需要查询单个用户及其角色信息。但是,在这里,我们不能使用resultType=User返回。

毕竟User类中只有一个Role对象,没有role_id和role_name字段属性。

所以,我们要用联想来联系它们。

结果映射id=用户映射类型=用户

id属性=id 列=id/id

结果属性=用户名列=用户名/结果

结果属性=密码列=密码/结果

结果属性=地址列=地址/结果

结果属性=电子邮件列=电子邮件/结果

关联属性=role javaType=Role

id属性=id 列=role_id/id

结果属性=名称列=角色名称/结果

/关联

/结果映射

最后,我们可以一起显示角色信息:

{

id: 1001 ,

用户名:后羿,

密码: 123456 ,

地址,北京市海淀区,

邮箱: 510273027@qq.com ,

角色:{

id: 3 ,

姓名:射手

}

}

事实上,如果你确定关联信息是一对一的,有一个更简单的方法来替换关联。我们将在本文的第五部分看到它是如何实现的——自动填充关联对象。

四、集合

1、集合的嵌套结果映射

上图,我们看到一个用户后羿,他的角色是射手;但是很多时候,我们每个人都不可能只有一个角色。因此,我们需要将User类中的role属性的类型改为List。

@数据

公共类用户{

//省略用户属性.

//角色信息

私有列表角色角色;

}

现在变成了多个角色对应的用户,所以不是简单的关联。

因为关联处理与一种类型的关联;这里我们有多种类型的关联,所以我们需要使用集合属性。

我们的总体结果图将如下所示:

结果映射id=用户映射类型=用户

id属性=id 列=id/id

结果属性=用户名列=用户名/结果

结果属性=密码列=密码/结果

结果属性=地址列=地址/结果

结果属性=电子邮件列=电子邮件/结果

类型为“Role”的集合属性为“roles”

id属性=id 列=role_id/id

结果属性=名称列=角色名称/结果

/收藏

/结果映射

这样,即使你有多个字符,你也能正确显示:

{

id: 1003 ,

用户名:丢西姆的故事,

密码: 123456 ,

地址,北京市东城区,

邮箱: 510273027@qq.com ,

角色:[

{

id: 1 ,

姓名:钟丹

},

{

id: 2 ,

姓名:打野

}

]

}

2、集合的嵌套 Select 查询

在大多数业务系统中,我们都会有一个菜单表,如下,一个菜单表:

身份证明(identification)

名字

全球资源定位器(Uniform Resource Locator)

家长id

一个

系统管理

0

1001

用户管理

/用户

一个

1002

角色管理

/角色

一个

1003

单位管理

/雇主

一个

2

平台监控

0

2001

系统监控

/系统/监视器

2

2002

数据监控

/数据/监视器

2

这里我们将菜单分为两级。当我们把菜单返回到前端的时候,也是需要分级的,不可能横向显示这七条数据。所以,这里我们的菜单实体类如下:

@数据

公共课程菜单{

私有字符串id;

私有字符串名称;

私有字符串url

私有字符串parent _ id

private ListMenu childMenu

}

一级菜单,包含一个二级菜单列表,这里用childMenu表示。

在SQL语句中,如果没有parent_id字段属性,我们将首先检查所有一级菜单:

select id= get menus result map= menus map

挑选

医学博士,

m.name,

m.url,

m.parent_id

菜单m

其中1=1

选择

当test=parent_id!=null

并且m.parent_id=#{parent_id}

/什么时候

否则

并且m.parent_id=0

/否则

/选择

/选择

这个查询语句,不传递任何参数,我们会得到两个一级菜单的数据。

那么,当这个方法只调用一次的时候,如何才能把所有的菜单信息都找出来并分层显示呢?

让我们看看menusMap的定义:

结果映射id=menusMap type=Menu

id属性=id 列=id/id

结果属性=名称列=名称/结果

结果属性=url 列=url/result

结果属性= desc 列= desc /结果

结果属性=parent_id 列= parent _ id /结果

type= Menu select= get menus column= { parent _ id=id } /collection的集合属性=childMenu

/结果映射

关注收集元素:

property=“child menu”对应于菜单中的子菜单列表;

of type=“Menu”对应于返回数据的类型;

Select=getMenus 指定Select语句的id;

column=“{ parent _ id=id }”是参数的表达式。

这个系列的全部意义可以理解如下:

通过getMenus的SELECT语句获取一级菜单中childMenu属性的结果;在上面的SELECT语句中,需要传递一个parent_id参数;该参数的值是一级菜单中的id。

这样我们就可以得到所有的分级菜单信息。

[

{

id: 1 ,

名称:系统管理,

parent_id: 0 ,

子菜单:[

{

id: 1001 ,

名称:用户管理,

URL“:/用户”,

parent_id: 1

},

{

id: 1002 ,

名称:角色管理,

URL“:/角色”,

parent_id: 1

},

{

id: 1003 ,

姓名:公司管理层,

URL :/雇主,

parent_id: 1

}

]

},

{

id: 2 ,

名称:平台监控,

parent_id: 0 ,

子菜单:[

{

id: 2001 ,

名称:系统监控,

URL :/系统/监视器,

parent_id: 2

},

{

id: 2002 ,

名称:数据监控,

URL :/数据/监视器,

parent_id: 2

}

]

}

]

五、自动填充关联对象

我们知道当Mybatis解析返回值时。

第一步是获取返回值类型,获取类对象,然后获取构造函数,设置可访问和返回的实例,然后包装成元对象对象。

从数据库rs得到结果后,会调用metaobject.setvalue(字符串名,对象值)来填充对象。

有趣的是,在这个过程中,它会用.

如果名称属性包含。符号之前找到属性名。符号,并将其视为实体对象。

可能作者这里描述的不够直观,我们来看例子。

在本文的第三部分,我们有一个用户对应一个角色的例子。

其中,用户类定义如下:

@数据

公共类用户{

//省略用户属性.

//角色信息

私人角色角色;

}

这里不需要定义resultMap,只需要返回resultType=User。但是,角色信息的别名需要修改,重点是。符号。

select id= get userlist result type= User

挑选

u.id,

用户名,

密码,

u .地址,

电子邮件,

r.id为 role.id ,

r.name为“role.name”

用户u

在u.id=ur.user_id上左连接user_roles ur

r.id=ur.role_id上的左联接角色r

/选择

这样,当Mybatis解析到Role.id属性时,发现角色别名被。符号,角色对象将首先被初始化,值将被赋予id属性。

相关代码如图所示:

总结

这就是本文的全部内容。希望这篇文章的内容对你的学习或工作有一定的参考价值。谢谢你的支持。

Mybatis中强大的resultMap功能介绍